Labo

EC-CUBE3 分室

【3.0.12-p1】動的ブロック基礎 新規追加プラグイン

2016年12月11日 / 投稿者名:chiharu


今回は動的なブロックを新規追加するプラグインです。
動的に何を出力するのかによって処理する内容は大きく変わります。
まぁ、兎にも角にも最初は定番の何もしないブロックの作成です(笑)
新規作成ブロックのベースになりますのでしっかり確認をしたいと思います。
 
ちなみに固定ページと異なり URL の問題が発生しません。
固定の内容をブロックに表示したい場合は管理画面から作成できます。
ブロックに関しては全く問題なさそうですね。
 
それでは進めて行きたいと思います。
 
 ・
 ・
 ・
 
出来ました。
とりあえず、以下の形式で枠は出来ている形ではないでしょうか。
 
■プラグインファイル
 config.yml
 PluginManager.php
 ServiceProvider/NakwebTest005ServiceProvider.php
 Controller/Block/NakwebTest005Controller.php
 Resource/template/Block/nakwebtest005_new_block.twig
 
 ▼config.yml
※今までとほぼ変わらないため省略します(笑)
 
 ▼PluginManager.php

<?php
/**
 * This file is part of EC-CUBE
 */

namespace Plugin\NakwebTest005;

use Eccube\Plugin\AbstractPluginManager;
use Eccube\Common\Constant;
use Eccube\Entity\BlockPosition;
use Eccube\Entity\Master\DeviceType;
use Eccube\Entity\PageLayout;
use Eccube\Util\Cache;
use Symfony\Component\Filesystem\Filesystem;

class PluginManager extends AbstractPluginManager
{


    // プラグイン用変数
    private $originBlock;
    private $blockName     = 'プラグイン新規追加ブロック';
    private $blockFileName = 'nakwebtest005_new_block';

    public function __construct()
    {
        // コピー元ブロックファイル
        $this->originBlock = __DIR__ . '/Resource/template/Block/' . $this->blockFileName . '.twig';
    }

    public function install($config, $app)
    {
    }

    public function uninstall($config, $app)
    {
        // ブロックの削除
        $this->removeBlock($app);
    }

    public function enable($config, $app)
    {
        // ブロックへ登録
        $this->copyBlock($app);
    }

    public function disable($config, $app)
    {
        // ブロックの削除
        $this->removeBlock($app);
    }

    public function update($config, $app)
    {
    }


    /**
     * ブロックを登録する処理
     *
     * @param $app
     * @throws \Exception
     */
    private function copyBlock($app)
    {

        // ファイルコピー
        $file = new Filesystem();
        // ブロックファイルをコピー
        $file->copy($this->originBlock, $app['config']['block_realdir'] . '/' . $this->blockFileName . '.twig');

        $em = $app['orm.em'];
        $em->getConnection()->beginTransaction();
        try {

            $DeviceType = $app['eccube.repository.master.device_type']->find(DeviceType::DEVICE_TYPE_PC);
            /** @var \Eccube\Entity\Block $Block */
            $Block = $app['eccube.repository.block']->findOrCreate(null, $DeviceType);

            // Blockの登録
            $Block->setName($this->blockName);
            $Block->setFileName($this->blockFileName);
            $Block->setDeletableFlg(Constant::DISABLED);
            $Block->setLogicFlg(1);
            $em->persist($Block);
            $em->flush($Block);

            // BlockPositionの登録
            $blockPos = $em->getRepository('Eccube\Entity\BlockPosition')->findOneBy(
                array('page_id' => 1, 'target_id' => PageLayout::TARGET_ID_MAIN_BOTTOM),
                array('block_row' => 'DESC'));

            $BlockPosition = new BlockPosition();

            // ブロックの順序を変更
            if ($blockPos) {
                $blockRow = $blockPos->getBlockRow() + 1;
                $BlockPosition->setBlockRow($blockRow);
            } else {
                // 1番目にセット
                $BlockPosition->setBlockRow(1);
            }

            $PageLayout = $app['eccube.repository.page_layout']->find(1);

            $BlockPosition->setPageLayout($PageLayout);
            $BlockPosition->setPageId($PageLayout->getId());
            $BlockPosition->setTargetId(PageLayout::TARGET_ID_MAIN_BOTTOM);
            $BlockPosition->setBlock($Block);
            $BlockPosition->setBlockId($Block->getId());
            $BlockPosition->setAnywhere(Constant::ENABLED);

            $em->persist($BlockPosition);
            $em->flush($BlockPosition);

            $em->getConnection()->commit();

        } catch (\Exception $e) {
            $em->getConnection()->rollback();
            throw $e;
        }

    }

    /**
     * ブロックを削除する処理
     *
     * @param $app
     * @throws \Exception
     */
    private function removeBlock($app)
    {
        $file = new Filesystem();
        $file->remove($app['config']['block_realdir'] . '/' . $this->blockFileName . '.twig');

        // Blockの取得(file_nameはアプリケーションの仕組み上必ずユニーク)
        /** @var \Eccube\Entity\Block $Block */
        $Block = $app['eccube.repository.block']->findOneBy(array('file_name' => $this->blockFileName));

        if ($Block) {
            $em = $app['orm.em'];
            $em->getConnection()->beginTransaction();

            try {
                // BlockPositionの削除
                $blockPositions = $Block->getBlockPositions();
                /** @var \Eccube\Entity\BlockPosition $BlockPosition */
                foreach ($blockPositions as $BlockPosition) {
                    $Block->removeBlockPosition($BlockPosition);
                    $em->remove($BlockPosition);
                }

                // Blockの削除
                $em->remove($Block);

                $em->flush();
                $em->getConnection()->commit();

            } catch (\Exception $e) {
                $em->getConnection()->rollback();
                throw $e;
            }
        }

        Cache::clear($app, false);

    }

}

PluginManager.php の enable や disable の処理で管理画面にブロックを表示する処理を行っています。
 
今回の注意点として以下の2か所かと思います。
 ※ブロックの設定

            // Blockの登録
            $Block->setName($this->blockName);
            $Block->setFileName($this->blockFileName);
            $Block->setDeletableFlg(Constant::DISABLED);
            $Block->setLogicFlg(1);
            $em->persist($Block);
            $em->flush($Block);

 $Block->setDeletableFlg(Constant::DISABLED);
  上記項目は削除可能区分になります。
  誤って削除さてもあまり良い結果にはなりません。
  忘れずに「DISABLED」にして下さい。
 
 $Block->setLogicFlg(1);
  上記項目は動的処理を行うかのフラグになります。
  該当の項目が「0」になっていると記述したロジックが動作しません。
  こちらも忘れずに「1」にして下さい。
 
 ※ブロックポジションの設定

            $BlockPosition->setPageLayout($PageLayout);
            $BlockPosition->setPageId($PageLayout->getId());
            $BlockPosition->setTargetId(PageLayout::TARGET_ID_MAIN_BOTTOM);
            $BlockPosition->setBlock($Block);
            $BlockPosition->setBlockId($Block->getId());
            $BlockPosition->setAnywhere(Constant::ENABLED);

 $BlockPosition->setTargetId(PageLayout::TARGET_ID_MAIN_BOTTOM);
  ここは表示ポジションを設定することができます。
  今回はメイン下部に表示するようにしています。
 
  まぁ、初期状態でポジションを設定しないことも考えられます。
  その場合はポジション設定自体いらないですけどね。
 
 ▼ServiceProvider/NakwebTest005ServiceProvider.php
 ※ServiceProviderフォルダに保存しています。

<?php
/**
 * This file is part of EC-CUBE
 */

namespace Plugin\NakwebTest005\ServiceProvider;

use Eccube\Application;
use Silex\Application as BaseApplication;
use Silex\ServiceProviderInterface;

class NakwebTest005ServiceProvider implements ServiceProviderInterface
{
    public function register(BaseApplication $app)
    {
        // ブロックのルーティング(bind先頭に「block_」をつける)
        $app->match('/block/nakwebtest005_new_block', '\Plugin\NakwebTest005\Controller\Block\NakwebTest005Controller::dispexec')->bind('block_nakwebtest005_new_block');
    }

    public function boot(BaseApplication $app)
    {
    }
}

 コントローラーを設定しています。
 今回は表示だけの為、非常にシンプルです。
 なお、ページレイアウトの設定の際に bind 名称を定義する必要があります。
 「ブロック」を作成する場合は bind先頭に「block_」をつける必要があるようです。
 
 ▼Controller/Block/NakwebTest005Controller.php
 ※Controller/Blockフォルダに保存しています。

<?php
/**
 * This file is part of EC-CUBE
 */

namespace Plugin\NakwebTest005\Controller\Block;

use Eccube\Application;
use Symfony\Component\HttpFoundation\Request;

class NakwebTest005Controller
{
    public function dispexec(Application $app, Request $request)
    {

        $smapleData = 'ここに表示内容';

        return $app['view']->render( "Block/nakwebtest005_new_block.twig",
            array(
                'smapleData' => $smapleData,
            )
        );

    }
}

 表示ページの内容を設定しています。
 今後のことも考え、twigファイルの指定をしています。
 
 ▼Resource/template/Block/nakwebtest005_new_block.twig
 ※Resource/template/Blockフォルダに保存しています。

<div class="row">
    <div class="col-md-12">
        <h1 class="">動的ブロック</h1>
        <p class="">{{ sampleData|raw }}</p>
    </div>
</div>

 表示内容は twig の記載内容になります。
 ここに記載した内容が表示される感じですね。
 実際に出力さする際には NakwebTest005Controller.php にて各種変数を設定しておく必要があります。
 
 
なお、今回の内容を作業している際に思った感想は以下のものでした。
 ・「あ、『bloc』から『Block』に代わっている・・・」
 ・「レスポンシブなのにブロックのデバイスタイプは残ってるんだ・・・」
特に「bloc」に関しては 2系の時はスペルミスで決着が付きそうですね(笑)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

* Copy This Password *

* Type Or Paste Password Here *

*

コメント欄にコードを挿入したい場合は、[php][/php] を使ってください。