BeginnerEngineerBlog
中の人
中の人

【ECCUBE4】既存テーブルのフィールドの文字数とかを変更する

公開: 2024-05-12 22:38
更新: 2024-05-15 00:14
21
ECCUBE4.2 mysql カスタマイズ symfony5.x
メモ
こんにちは!

中の人です!

最近eccube4系で、既存のフィールドのlengthとかを変えたい時あって、カスタマイズフォルダでtrait作って上書きできるかと思ったんですけどできなかったので、以前紹介した


を応用?したらできたので自分のメモとして紹介します


どういうこと?


変更前



インストール後作成されるデータベースのcustomerテーブルですが、
name01がvarchar(255)です

これをvarchar(10)に変更したいということです

うまくいきそうなやり方でやってみる


ということで、entityカスタマイズの王道なイメージ(いや、王道なんだと思うけど)で変更しようと思います

traitを作成


📁 root/app/Customize/Entity/CustomerTrait.php

<?php

namespace Customize\Entity;

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

/**
 * @EntityExtension("Eccube\Entity\Customer")
 */
trait CustomerTrait
{
    /**
     * @var string
     *                                                 👇 255から10に変更
     * @ORM\Column(name="name01", type="string", length=10)
     */
    private $name01;
}

コマンドを実行

$ bin/console eccube:generate:proxies
$ bin/console cache:clear --no-warmup
$ bin/console doctrin:schema:update --dump-sql --force

これの実行結果は

CREATE TABLE oauth2_authorization_code (identifier CHAR(80) NOT NULL, client VARCHAR(32) NOT NULL, expiry DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', user_identifier VARCHAR(128) DEFAULT NULL, scopes TEXT DEFAULT NULL COMMENT '(DC2Type:oauth2_scope)', revoked TINYINT(1) NOT NULL, INDEX IDX_509FEF5FC7440455 (client), PRIMARY KEY(identifier)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE oauth2_refresh_token (identifier CHAR(80) NOT NULL, access_token CHAR(80) DEFAULT NULL, expiry DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', revoked TINYINT(1) NOT NULL, INDEX IDX_4DD90732B6A2DD68 (access_token), PRIMARY KEY(identifier)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE oauth2_client (identifier VARCHAR(32) NOT NULL, name VARCHAR(128) NOT NULL, secret VARCHAR(128) DEFAULT NULL, redirect_uris TEXT DEFAULT NULL COMMENT '(DC2Type:oauth2_redirect_uri)', grants TEXT DEFAULT NULL COMMENT '(DC2Type:oauth2_grant)', scopes TEXT DEFAULT NULL COMMENT '(DC2Type:oauth2_scope)', active TINYINT(1) NOT NULL, allow_plain_text_pkce TINYINT(1) DEFAULT 0 NOT NULL, PRIMARY KEY(identifier)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE oauth2_access_token (identifier CHAR(80) NOT NULL, client VARCHAR(32) NOT NULL, expiry DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', user_identifier VARCHAR(128) DEFAULT NULL, scopes TEXT DEFAULT NULL COMMENT '(DC2Type:oauth2_scope)', revoked TINYINT(1) NOT NULL, INDEX IDX_454D9673C7440455 (client), PRIMARY KEY(identifier)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_api_webhook (id INT UNSIGNED AUTO_INCREMENT NOT NULL, payload_url VARCHAR(1024) NOT NULL, secret VARCHAR(1024) DEFAULT NULL, enabled TINYINT(1) NOT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', discriminator_type VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_coupon_order (coupon_order_id INT UNSIGNED AUTO_INCREMENT NOT NULL, coupon_id INT UNSIGNED NOT NULL, coupon_cd VARCHAR(20) DEFAULT NULL, coupon_name VARCHAR(50) DEFAULT NULL, user_id INT UNSIGNED DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, order_id INT UNSIGNED NOT NULL, pre_order_id VARCHAR(255) DEFAULT NULL, order_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetimetz)', order_item_id INT UNSIGNED DEFAULT NULL, discount NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, visible TINYINT(1) DEFAULT 1 NOT NULL, order_change_status TINYINT(1) DEFAULT 1 NOT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', discriminator_type VARCHAR(255) NOT NULL, PRIMARY KEY(coupon_order_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_coupon_detail (coupon_detail_id INT UNSIGNED AUTO_INCREMENT NOT NULL, coupon_id INT UNSIGNED DEFAULT NULL, product_id INT UNSIGNED DEFAULT NULL, category_id INT UNSIGNED DEFAULT NULL, coupon_type SMALLINT DEFAULT NULL, visible TINYINT(1) DEFAULT 1 NOT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', discriminator_type VARCHAR(255) NOT NULL, INDEX IDX_7B9D14166C5951B (coupon_id), INDEX IDX_7B9D1414584665A (product_id), INDEX IDX_7B9D14112469DE2 (category_id), PRIMARY KEY(coupon_detail_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_coupon (coupon_id INT UNSIGNED AUTO_INCREMENT NOT NULL, coupon_cd VARCHAR(20) DEFAULT NULL, coupon_type SMALLINT DEFAULT NULL, coupon_name VARCHAR(50) DEFAULT NULL, discount_type SMALLINT DEFAULT NULL, coupon_use_time INT DEFAULT NULL, discount_price NUMERIC(12, 2) UNSIGNED DEFAULT '0', discount_rate NUMERIC(10, 0) UNSIGNED DEFAULT '0', enable_flag TINYINT(1) DEFAULT 1 NOT NULL, available_from_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', available_to_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', visible TINYINT(1) DEFAULT 1 NOT NULL, coupon_member TINYINT(1) DEFAULT 0 NOT NULL, coupon_lower_limit NUMERIC(12, 2) UNSIGNED DEFAULT '0', coupon_release INT NOT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', discriminator_type VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_755A31039C2A7D91 (coupon_cd), PRIMARY KEY(coupon_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_mailmaga_template (template_id INT UNSIGNED AUTO_INCREMENT NOT NULL, subject VARCHAR(255) NOT NULL, body LONGTEXT NOT NULL, html_body LONGTEXT DEFAULT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', PRIMARY KEY(template_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;
CREATE TABLE plg_mailmaga_send_history (send_id INT UNSIGNED AUTO_INCREMENT NOT NULL, creator_id INT UNSIGNED DEFAULT NULL, mail_method SMALLINT DEFAULT NULL, subject VARCHAR(255) DEFAULT NULL, body LONGTEXT DEFAULT NULL, html_body LONGTEXT DEFAULT NULL, send_count INT UNSIGNED DEFAULT NULL, complete_count INT UNSIGNED DEFAULT 0, error_count INT UNSIGNED DEFAULT 0, start_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetimetz)', end_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetimetz)', search_data LONGTEXT DEFAULT NULL, create_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', update_date DATETIME NOT NULL COMMENT '(DC2Type:datetimetz)', INDEX IDX_424AD01261220EA6 (creator_id), PRIMARY KEY(send_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_bin` ENGINE = InnoDB;

なんかいっぱい出力されてますが、customerテーブルには干渉してません


データベースを確認してみますが、name01は255のままです

つまりこの王道のやり方は既存フィールドじゃ通用しないってことみたいですね

うまくいくやり方


ということで冒頭に紹介した前回記事を応用してみます

traitを修正


<?php

namespace Customize\Entity;

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

/**
 * @EntityExtension("Eccube\Entity\Customer")
 */
trait CustomerTrait
{
    // 👇 これの指定方法はお好みで!
    public static $column_extensions = [
        'name01' => [
            'length' => 10,
        ],
    ];
}

$column_extensionsというプロパティを作成して、目的のフィールドのlengthを指定します
コメントでもありますが、これは各々のお好みの方法で指定してください

EventListener作成


📁 root/app/Customize/EventListener/EntityEventListener.php

<?php
namespace Customize\EventListener;

use Customize\Entity\CustomerTrait;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;

class EntityEventListener implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return [
            'loadClassMetadata',
        ];
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $cm = $eventArgs->getClassMetadata();
        $class = $cm->getName();
        $uses = class_uses($class);

        if (in_array(CustomerTrait::class, $uses)) {// 👈 CustomerTraitがuseされてれば
            if (property_exists(CustomerTrait::class, 'column_extensions')) {// 👈 CustomerTraitの中に'column_extensions'というプロパティがあったら
                $column_extensions = CustomerTrait::$column_extensions;
                foreach ($column_extensions as $field => $extensions) {
                    if (isset($cm->fieldMappings[$field])) {// 👈 Customerに$field('name01')があったら
                        foreach ($extensions as $extension => $value) {
                            $cm->fieldMappings[$field][$extension] = $value;// 👈 traitについかしたプロパティの値に上書き
                        }
                    }
                    
                }
            }
        }
    }
}

コマンドを実行


$ bin/console eccube:generate:proxies
$ bin/console cache:clear --no-warmup
$ bin/console doctrin:schema:update --dump-sql --force

これの実行結果は

ALTER TABLE dtb_cart CHANGE total_price total_price NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE delivery_fee_total delivery_fee_total NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL;
ALTER TABLE dtb_order CHANGE subtotal subtotal NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE discount discount NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE delivery_fee_total delivery_fee_total NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE charge charge NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE tax tax NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE total total NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL, CHANGE payment_total payment_total NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL;
ALTER TABLE dtb_cart_item CHANGE price price NUMERIC(12, 2) DEFAULT '0' NOT NULL;
ALTER TABLE dtb_order_item CHANGE price price NUMERIC(12, 2) DEFAULT '0' NOT NULL;
ALTER TABLE dtb_payment CHANGE charge charge NUMERIC(12, 2) UNSIGNED DEFAULT '0';
ALTER TABLE dtb_customer CHANGE name01 name01 VARCHAR(10) NOT NULL, CHANGE buy_total buy_total NUMERIC(12, 2) UNSIGNED DEFAULT '0';
ALTER TABLE plg_coupon_order CHANGE discount discount NUMERIC(12, 2) UNSIGNED DEFAULT '0' NOT NULL;
ALTER TABLE plg_coupon CHANGE discount_price discount_price NUMERIC(12, 2) UNSIGNED DEFAULT '0', CHANGE coupon_lower_limit coupon_lower_limit NUMERIC(12, 2) UNSIGNED DEFAULT '0';

先ほどと同じようにいろいろと出力されてますが、

ALTER TABLE dtb_customer CHANGE name01 name01 VARCHAR(10) NOT NULL

dtb_customerの出力がされました

データベースを確認してみます


name01がvarchar(10)になりましたね!

おすおすー(゚∀゚ )オスオス


終わりに


てまぁ、trait作らなくてもEventListenerのみでやってもいいんだろうけど、やっぱtraitあると拡張してるよってわかりやすいかなって

すごいトリッキーな(処理を熟知した人が実装したであろう)記事あったんですが、この記事書いている最中見つけられませんでした🙇‍♂️
そんでもってトリッキーすぎて自分にはよくわからず今回の実装を行いました

スーパーな記事見つけたらこちらで紹介したいと思います

お疲れした!
0
0
0
0
通信エラーが発生しました。
似たような記事