EC-CUBE4で商品規格に必須項目を追加する方法
EC-CUBE4で商品や受注に項目を追加するには、 @EntityExtensionアノテーションを使って拡張を行います。
https://doc4.ec-cube.net/customize_entity
この際、@Eccube\FormAppendアノテーションを使うことで、 管理画面の登録フォームにも項目を追加できるのですが、 商品規格の項目に対して、ここでバリデーションを適用しようとすると、 登録しない規格の組み合わせ(つまりチェックを入れていないもの)に関しても、 アノテーションに設定したバリデーションが走ってしまいます。 必須項目にしたい時などは、これによって登録自体が できなくなってしまうのです。
今回はそれを回避し、かつ、srcフォルダ内を直接触らなくても良い方法を紹介します。
※ 以下では、商品規格に必須項目を追加することを想定しています。
商品規格を拡張する
まずは商品や受注の項目を拡張する時と同様、 @EntityExtensionアノテーションを使って商品規格の項目を作成します。
<?php
namespace Customize\Entity\ProductClass;
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation\EntityExtension;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @EntityExtension("Eccube\Entity\ProductClass")
*/
class ProductClassExtension
{
/**
* @ORM\Column(type="string", nullable=true)
* @Eccube\FormAppend(
* auto_render=true,
* type="text",
* options={
* "required": false,
* "label": "素材"
* }
* )
*/
private $material;
/**
* @return string
*/
public function getMaterial()
{
return $this->material;
}
/**
* @param string $material
*
* @return $this
*/
public function setMaterial($material)
{
$this->material = $material;
return $this;
}
}
ここでのポイントは、requiredをfalseとすることです。 trueにするとブラウザ側でバリデーションが走ってしまい、 登録できなくなってしまいます。
その後、商品規格の登録・編集ページのテンプレートに項目を追加します。 この時点で、新しい項目の登録はできるようになります。
※ データベースへのカラム追加は完了していると仮定しています。
商品規格独自のバリデーションを改修
ここからがミソなのですが、商品規格ページではチェックを入れているものと、 そうでないものとで分けてから、 バリデーションをかけるという独自の処理があります。 それが、ProductClassEditType.phpで行われていますので、 これを継承してそこに今回追加した項目のバリデーションを行います。
<?php
namespace Customize\Form\Type\Admin;
use Eccube\Form\Type\Admin\ProductClassEditType as BaseProductClassEditType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Validator\Constraints as Assert;
class ProductClassEditType extends BaseProductClassEditType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
// 追加した項目のバリデーションを検証するイベントリスナーを追加
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$data = $form->getData();
// 有効な組み合わせのみバリデーション検証を行う
// (isEnable == falseなものは、チェックを入れていない規格の組み合わせを表す)
if ($data['checked'] && $data['stock_unlimited']) {
// 規格が有効でかつ在庫無制限の場合のバリデーション
if (empty($data['material'])) {
$form['material']->addError(new FormError('素材が入力されていません。'));
}
} elseif ($data['checked']) {
// 規格が有効の場合のバリデーション
if (empty($data['material'])) {
$form['material']->addError(new FormError('素材が入力されていません。'));
}
}
});
}
}
こうすることで、チェックを入れている規格の組み合わせだけに、 バリデーションをかけることができます。