【EC-CUBE4】エンティティ:Entity

スポンサーリンク
スポンサーリンク

Entityについて説明していきます。

スポンサーリンク

Entityの定義

Entityとは、データを扱うクラスです。

本体Entity:ドキュメントルート/src/Eccube/Entity

基本的には、データベースの各テーブルを定義し使用していきます。

関連するテーブルの情報を定義し「スキーマ更新コマンド」でDBへ更新も可能です。

Bash
bin/console doctrine:schema:update --dump-sql --force

商品クラスで解説

テーブル定義

PHP
    /**
     * Product
     * ↓ これがないとクラス名でテーブルが作成される
     * @ORM\Table(name="dtb_product")
     * ↓ クラス階層ごとに1つのテーブルを作成します
     * @ORM\InheritanceType("SINGLE_TABLE")
     * ↓ テーブルの識別用カラム
     * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
     * ↓ サービスの依存関係がないならコールバックの設定をした方が良いとのこと
     * @ORM\HasLifecycleCallbacks()
     * ↓ Repositoryの読込み設定
     * @ORM\Entity(repositoryClass="Eccube\Repository\ProductRepository")
     */
    class Product extends \Eccube\Entity\AbstractEntity

カラム定義

PHP
         * @ORM\Column(name="id", type="integer", options={"unsigned":true})
         * @ORM\Column(name="name", type="string", length=255)
         * @ORM\Column(name="create_date", type="datetimetz")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         * @ORM\OneToMany(targetEntity="Eccube\Entity\ProductImage", mappedBy="Product", cascade={"remove"})
         * @ORM\ManyToOne(targetEntity="Eccube\Entity\Member")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="creator_id", referencedColumnName="id")
         * })

定数やメソッドも追加可能

PHP
// 編集不可ステータス
const UNEDITABLE_STATUS = [
    self::PENDING,
    self::PROCESSING,
    self::CREDIT_SLIP,
];

/**
 * 銀行支払いかチェック
 * @return bool
 */
 public function isBankPayment() {
  return $this->getId() == Payment::BANK_PAYMENT ? true:false;
}

データ登録の流れ

  1. 登録対象Entityの取得 $Product = new Product
  2. $Product->setName = ‘テスト商品’
  3. 永続化登録設定 $this->entityManager->persist($Product)
  4. 登録処理 $this->entityManager->flush($Product)

実際のDBへ登録されるタイミングは、エラーがなく正常終了してテンプレートにいくタイミング。

Entityをカスタマイズしたい場合

src配下のEntity本体ソースは、アプデで影響が出る可能性があるので、

カラムやメソッドを追加したい場合

CustomizeでTraitを使用し拡張する

この場合は、スキーマ更新コマンドでdtb_categoryへslugカラムが追加される。

更新手順↓

proxy更新→キャッシュクリア→スキーマ更新コマンド

PHP
<?php

namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation\EntityExtension;

/**
 * @EntityExtension("Eccube\Entity\Category")
 */
trait CategoryTrait
{
    /**
     * @var string
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $slug;

    /**
     * @return string|null
     */
    public function getSlug(): ?string
    {
        return $this->slug;
    }

    /**
     * @param string|null $slug
     * @return $this
     */
    public function setSlug(?string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }
}

定数を使用したい場合

元のEntityを継承して使用する

PHP
<?php

namespace Customize\Entity\Master;

use Eccube\Entity\Master\OrderStatus as BaseEntity;

if (!class_exists('Customize\Entity\Master\OrderStatus')) {

    /** 親クラスの定数宣言を拡張する目的に作成しています */
    class OrderStatus extends BaseEntity {

        /** 入金待ち */
        const PAY_WAIT = 2;

        // 編集不可ステータス
        const UNEDITABLE_STATUS = [
            self::PENDING,
            self::PROCESSING,
            self::CREDIT_SLIP,
        ];
    
    }
}

使用したいファイルで、useして使用する

use Customize\Entity\Master\OrderStatus;

既存の他のTrait読み込み

下記プログラムでgetFullName()が使用可能となる

PHP
<?php

namespace Customize\Entity;

use Eccube\Annotation\EntityExtension;
use Eccube\Entity\NameTrait;

/**
  * @EntityExtension("Eccube\Entity\Customer")
 */
trait CustomerTrait
{
    use NameTrait;
}

src/Eccube/Entity/NameTrait.php

PHP
<?php

namespace Eccube\Entity;

trait NameTrait
{
    public function getFullName()
    {
        return (string) $this->name01.' '.$this->name02;
    }

    public function getFullNameKana()
    {
        return (string) $this->kana01.' '.$this->kana02;
    }
}

以前ハマった対応があったので紹介します。

初期表示データ取得できない

カスタマイズ中に発生した問題です。

EC-CUBE4は基本的にDoctrineを使用しています。

データベースをオブジェクト化した物で、都度データベースにアクセスしないでデータの取得や加工が行えます。

なぜこの状態になったか?

取得できなかったデータ
※わかりやすくEC-CUBEデフォルトのテーブルで説明します。

要件:カートの情報をデータ登録直後に一覧ページに表示したい。

関連するテーブルは、dtb_cartとdtb_cart_itemの2種類です。

パターン1

  1. dtb_cartへEntityで登録+永続化+フラッシュ
  2. dtb_cart_itemへEntityで登録+永続化+フラッシュ
  3. findByでリスト取得して、テンプレートへ

パターン2

  1. dtb_cartへEntityで登録+永続化+フラッシュ
  2. dtb_cart_itemへEntityで登録+永続化+フラッシュ
  3. テンプレートでfindByしてリスト取得

上記でうまくいかなかったです。

結局なんだったかと言うと、

リレーションが貼ってあるので、cart→cart_itemの順で登録

cartは最新の登録データは持っているが、紐づくcart_itemは後から登録されるので

cartのEntityに、cart_itemの最新情報が紐づいていない状態

cartのEntityを更新する

PHP
$this->entityManager->refresh(XXX);
XXXは、更新するEntityオブジェクト 

$this->entityManager->refresh($cart);

これで解決!

コメント

タイトルとURLをコピーしました