【Eccube4】お客様情報や非会員情報欄に項目を追加する方法
Eccube4
Eccube4はSymfonyというフレームワークの上に作られていて、ベースはSymfonyなので、Eccubeの解決方法で出てこない場合にはSymfonyを探してみると解決策が見つかる可能性があります
編集前に
基本的にPlugin内に新たにNewPlugin
というプラグインを作成して編集します
Twigファイルのみ使用しているテンプレートを書き換えないといけないです
公式のアップデートで修正するまでの一時処理になりそうな部分もあります
環境
Eccube 4.1.2
お客様情報に項目を追加する
編集する必要があるファイルは以下になります
app/Plugin/NewPlugin/Entity/CustomerTrait.php
app/template/<TemplateName>/admin/Customer/edit.twig
<TemplateName>
は使用しているテンプレートの名前です
変更していない場合にはdefault
になります
CustomerTrait.php
<?php
namespace Plugin\NewPlugin\Entity;
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Eccube\EntityExtension("Eccube\Entity\Customer")
*/
trait CustomerTrait {
/**
* @ORM\Column(name="added_property", type="string", length=255, nullable=true)
* @Eccube\FormAppend(
* auto_render=true,
* type="\Symfony\Component\Form\Extension\Core\Type\TextType",
* options={
* "required": true,
* "label": "追加する項目のラベル",
* "attr": {"placeholder": "例:SAMPLE"}
* }
* )
* @Assert\NotBlank(message="追加する項目のラベルを入力してください")
*/
private $added_property;
public function getAddedProperty() {
return $this->added_property;
}
public function setAddedProperty($added_property) {
$this->added_property = $added_property;
return $this;
}
}
edit.twig
これは必須の場合にラベルをつけるためのプロパティが用意されていないので、必須項目ラベルを付け足すための編集です
CustomerTrait
のauto_renderer
をfalse
にして、src/Eccube/Resource/template/Entry
内のTwigを上書きするのでも構わないと思います
sec/Eccube/Resource/template/admin/Customer/edit.twig
をコピーして編集します
...
<div class="row mb-2">
<div class="col-3">
<span>{{ 'admin.common.added_property'|trans }}</span>
<span class="badge badge-primary ml-1">{{ 'admin.common.required'|trans }}</span>
</div>
<div class="col">
{{ form_widget(form.added_property) }}
{{ form_errors(form.added_property) }}
</div>
</div>
...
{# エンティティ拡張の自動出力 #}
{% for f in form|filter(f => f.vars.eccube_form_options.auto_%}
{% if f.vars.eccube_form_options.form_theme %}
{% form_theme f f.vars.eccube_form_options.form_theme %}
{{ form_row(f) }}
{% if f.vars.id == "admin_customer_added_property" %}
{% else %}
<div class="row mb-2">
<div class="col-3">
<span>{{ f.vars.label|trans }}</span>
</div>
<div class="col">
{{ form_widget(f) }}
{{ form_errors(f) }}
</div>
</div>
{% endif %}
{% endfor %}
...
足したのは{% if f.vars.id == "admin_customer_added_property" %}
の箇所です
追加したプロパティは自動で出力せず、上の既存のものに追加しています
公式でプロパティを増やしてくれれば...例えばrequiredをauto_rendererと並列に置くとか...
ゲスト購入時に項目を追加する
// form table
app/Plugin/NewPlugin/Entity/OrderTrait.php
app/Plugin/NewPlugin/Entity/ShoppingTrait.php
app/Plugin/NewPlugin/Form/Extension/NonMemberExtension.php
// display
app/Plugin/NewPlugin/Controller/ShoppingController.php
app/Plugin/NewPlugin/Controller/NonMemberShoppingController.php
app/Plugin/NewPlugin/Service/OrderHelperService.php
app/Plugin/NewPlugin/Repository/OrderRepository.php
app/config/eccube/services.yaml
app/template/<TemplateName>/Shopping/index.twig
app/template/<TemplateName>/Shopping/confirm.twig
/shopping
を操作しているのはsrc/Eccube/Controller/ShoppingController.php
なので困ったらそのファイルを見ると良いです
OrderTrait.php
Entity
<?php
namespace Plugin\NewPlugin\Entity;
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Eccube\EntityExtension("Eccube\Entity\Order")
*/
trait OrderTrait {
/**
* @ORM\Column(name="added_property", type="string", length=255, nullable=true)
* @Eccube\FormAppend(
* auto_render=true,
* type="\Symfony\Component\Form\Extension\Core\Type\TextType",
* options={
* "required": true,
* "label": "追加する項目のラベル",
* "attr": {"placeholder": "例:SAMPLE"}
* }
* )
* @Assert\NotBlank(message="追加する項目のラベルを入力してください")
*/
private $added_property;
public function getAddedProperty() {
return $this->added_property;
}
public function setAddedProperty($added_property) {
$this->added_property = $added_property;
return $this;
}
}
プラグインの編集が終わったら
データベースを更新すると
データベースのスキーマを更新する
を行います
ShoppingTrait.php
上記で作成したOrderTrait.php
をコピーして、
ファイル名とtraitの名前をShoppingTrait
にしてください
ShoppingController
4.0.2
からある公式のバグ?のようです OrderTrait
で追加した項目をhandleRequest
に渡すと追加したプロパティが消えるので修正します
$form->handleRequest($request);
上記のコードを全て下のコードに置き換えます
$form->submit($request->get($form->getName()), false);
Symfony
のFormのsubmitにfalse
を第2項目で追加すると追加でプロパティを増やせるのですが、handleRequest
でラップされているので、消えます
NonMemberExtension.php
FormType
のカスタマイズです
Entityからカスタマイズする方が簡単ですが、NonMemberにはEntityがないのでFormTypeから変更します
src/Eccube/Form/Type/Front/NonMemberType.php
を上書きするためのものです
ファイル名ではなく、getExtendedType
とgetExtendedTypes
で返す型を上書きできます
<?php
namespace Plugin\NewPlugin\Form\Extension;
use Eccube\Form\Type\Front\NonMemberType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
class NonMemberExtension extends AbstractTypeExtension
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('added_property', TextType::class, [
'required' => true,
'constraints' => [
new NotBlank(),
],
'attr' => [
'placeholder' => '例:SAMPLE',
]
]);
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$builder = $form->getConfig();
$view->vars['added_property'] = $builder->getAttribute('added_property');
}
/**
* {@inheritdoc}
*/
public function getExtendedType()
{
return NonMemberType::class;
}
/**
* {@inheritdoc}
*/
public static function getExtendedTypes(): iterable
{
yield NonMemberType::class;
}
}
NonMemberShoppingController.php
/shopping/nonmember
ページのコントローラーです
sec/Eccube/Controller/NonMemberShoppingController.php
をコピーしてきます
以下の部分に新しいプロパティを追加します
<?php
...
class NonMemberShoppingController extends AbstractShoppingController
{
...
public function customer(Request $request)
{
...
$Order
...
->setEmail($data['customer_email'])
->setAddedProperty($data['customer_added_property']);
$this->session->set(OrderHelper::SESSION_NON_MEMBER, [
...,
'email' => $data['customer_email'],
'added_property' => $data['customer_added_property'],
]);
OrderHelperService.php
src/Eccube/Service/OrderHelper.php
をコピペして作成します
追加した項目をshoppingのお客様情報部分に渡すためのコードです
後でservices.yaml
に上書きすると記載します
<?php
...
namespace Plugin\NewPlugin\Service;
...
class OrderHelper
{
...
public function getNonMember($session_key = self::SESSION_NON_MEMBER)
{
...
$Customer
...
->setAddr02($data['addr02'])
+ ->setAddedProperty($data['added_property']);
OrderRepository.php
src/Eccube/Repository/OrderRepository.php
のgetQueryBuilderBySearchDataForAdmin
関数をそのままコピーして来て追加項目の分も追加します
namespace Plugin\NewPlugin\Repository;
use Eccube\Repository\OrderRepository as BaseOrderRepository;
use Doctrine\ORM\QueryBuilder;
use Eccube\Entity\Master\OrderStatus;
use Eccube\Entity\Shipping;
use Eccube\Util\StringUtil;
use Eccube\Repository\QueryKey;
class OrderRepository extends BaseOrderRepository
{
public function getQueryBuilderBySearchDataForAdmin($searchData)
{
...
// added_property
if (isset($searchData['added_property']) && StringUtil::isNotBlank($searchData['added_property'])) {
$qb
->andWhere('o.added_property LIKE :added_property')
->setParameter('added_property', '%'.$searchData['added_property'].'%');
}
...
}
}
services.yaml
一番下に下記を追加します
Plugin\NewPlugin\Service\OrderHelperService:
decorates: Eccube\Service\OrderHelper
Plugin\NewPlugin\Repository\OrderRepository:
decorates: Eccube\Repository\OrderRepository
これで上書きできました
index.twig
あとはデータがあるので見た目に追加してあげます
...
<dl>
<dt>
<label class="ec-label required">{{ '追加する項目のラベル'|trans }}</label>
<span class="ec-required">{{ '必須'|trans }}</span>
</dt>
<dd>
<div class="ec-input">
<span class="customer-form customer-added_property"></span>
</div>
</dd>
</dl>
</div>
...
<input type="hidden" id="customer-added_property" class="customer-in" name="customer_added_property" value="{{ Order.added_property }}">
...
ここでadded_property
が追加する項目のidになります
confirm.twig
<div class="ec-orderAccount__account">
...
<p class="ec-input">{{ Order.added_property }}</p>
</div>
困った時のコマンド
キャッシュを消す
bin/console cache:clear --no-warmup
プラグインを読み込む
bin/console eccube:plugin:install --code=PluginName
PluginName
にプラグインの名前を入れてください
プラグインを削除する
bin/console eccube:plugin:uninstall --code=PluginName
PluginName
にプラグインの名前を入れてください
プラグインを有効化する
bin/console eccube:plugin:enable --code=PluginName
PluginName
にプラグインの名前を入れてください
プラグインを無効化する
bin/console eccube:plugin:disable --code=PluginName
PluginName
にプラグインの名前を入れてください 強制的に消す場合には--uninstall-force=true
オプションもつけられます
データベースを更新する
bin/console make:migration
データベースのスキーマを更新する
bin/console doctrine:schema:update --dump-sql
参考
Symfonyで $form->isValid() のエラー内容を表示したい
プラグインのインストール
データ構造の説明
How to Decorate Services
FormTypeのカスタマイズ