EC-CUBE管理画面ではログインしているユーザーの権限によって挙動を変えたい時があると思います。
EC-CUBE4では拒否URL設定でページのアクセス自体を権限ごと設定することが可能ですが、より細かく挙動を制御したい場合もあります。
今回はモール型など権限管理が複雑なサイトで必須技術となる、権限によって管理画面フォームの項目を変化させる方法をご紹介します。

TokenStorageInterface

TokenStorageInterfaceクラスが重要です。ファイルの最初でuseをしておきます。

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

__constructでプロパティにセット

コンストラクタでTokenStorageInterfaceの依存性注入します。フォームではEccubeConfigをよく使用するので一緒にセットします。

    /**
     * @var EccubeConfig
     */
    protected $eccubeConfig;

    /**
     * @var TokenStorageInterface
     */
    private $tokenStorage;

    /**
     * CustomerType constructor.
     *
     * @param EccubeConfig $eccubeConfig
     */
    public function __construct(
        EccubeConfig $eccubeConfig,
        TokenStorageInterface $tokenStorage
    )
    {
        $this->eccubeConfig = $eccubeConfig;
        $this->tokenStorage = $tokenStorage;

    }

buildFormメソッド内でログインユーザー権限で切り分ける

FormTypeのbuildForm内でtokenStorageを利用してMemberクラスオブジェクトを取得、Authority(権限)によって切り分けます。
今回はシステム管理者権限でログインしている場合のみフォームの項目を追加します。

      // 管理権限のみ必須項目admin_only_itemを追加 
      $Member = $this->tokenStorage->getToken()->getUser();
        if ($Member->getAuthority()->getId() === \Eccube\Entity\Master\Authority::ADMIN) {
            $builder
                ->add('admin_only_item', TextType::class, [
                    'required' => true,
                    'label' => '管理権限のみの項目',
                    'constraints' => [
                        new Assert\NotBlank(),
                        new Assert\Length([
                            'max' => $this->eccubeConfig['eccube_stext_len'],
                        ])
                    ]
                ]);
        }

テンプレートへ表示する

この辺りは様々な考え方があると思いますが、form.admin_only_itemが定義されているかどうかで切り分けることにします。
管理者権限の場合はフォームが表示されますが、店舗オーナー権限の場合はadmin_only_itemがaddされていないので表示されません。

                                {% if form.admin_only_item is defined %}
                                <div class="row mb-2">
                                    <div class="col-3">
                                        <span>ラベル</span>
                                    </div>
                                    <div class="col">
                                        {{ form_widget(form.admin_only_item) }}
                                        {{ form_errors(form.admin_only_item) }}
                                    </div>
                                </div>
                                {% endif %}

管理権限でない場合にフォームではなくテキスト表示したい場合は、別途Entityをtwigに渡しておいて、{{ Entity.admin_only_item }} のような形でテキスト表示してやります。

display:noneではダメな理由

簡単のため権限によってフォームをCSSで非表示にしているコードをたまに見かけますが、これだとHTMLを操作してフォームを送信すると非表示の項目を更新することができてしまいます。
ですのでHTMLに詳しい人であれば権限を無視できるというリスクを抱えることになります。

今回紹介した方法であればそもそも権限によってformに要素を追加しないので、HTMLを操作してもフォーム送信時にエラーになり更新することができません。
ぜひEC-CUBE4でモール型など権限管理が複雑なサイトを開発する際にご利用ください。