カテゴリー
EC-CUBE

【EC-CUBE4】コントローラー:Controller

[temp id=3]

私のControllerの拡張方法を説明していきます。

ドキュメント読んで、手順通りに学んだわけではないので参考程度に見てください。

しっかり学びたい人は、Symfonyのドキュメントをお読みください。

https://symfony.com/doc/current/controller.html

簡単なControllerのカスタマイズ

ここで説明する情報は既存機能のカスタマイズです。

本体フォルダ→拡張フォルダを見に行きRouteが同一の場合上書きされる性質をもつ

新規のControllerを作成する際は、既存で使用されていないか必ず確認してください。

会員登録や商品詳細をカスタマイズしたいなどで応用できます。

Controllerのカスタマイズが必要か確認

大規模か改修の際は必要

一覧画面:テーブルに追加した項目のみの処理は不要

データ取得は、EntityTrait

表示は、twig

バリデーションは、Form

Controllerのカスタマイズ手順

今回は、会員登録「EntryController」を例に解説していきます。

重要パス
  1. 拡張フォルダ:プロジェクト名/app/Customize/Controller/
  2. 本体フォルダ:プロジェクト名/src/Eccube/Controller/
  1. EntryController.phpをコピーし拡張フォルダへ保存
  2. ファイル名変更CustomEntryController.php
  3. 拡張ファイルへ変更

3について、

  1. namespaceの変更
  2. useでAbstractControllerの読込み
 namespace Customize\Controller;

 use Eccube\Controller\AbstractController;

 class CustomEntryController extends AbstractController
 {

 }

確認方法

デバックするだけです。

    /**
     * 会員登録画面.
     *
     * @Route("/entry", name="entry")
     * @Template("Entry/index.twig")
     */
    public function index(Request $request)
    {
        dump('通過確認');
        exit;

スピード重視型

デフォルトController全てコピー

既存メソッドを改修

新規メソッド追加

追加スタマイズの可能性もあるので、この方が楽

綺麗さ重視型

不要な読込みファイルの削除

不要なメソッドの削除

カテゴリー
EC-CUBE

【EC-CUBE4】Commandクラス

定期お知らせメールを作成した際に触れたクラスです。
cron→bach→command

コマンドクラスからSwift_Messageでメール送信する

Commandクラス作成

コマンドで作成できます。

bin/console make:command

Commandクラスでメール送信テスト

https://github.com/EC-CUBE/ec-cube/issues/2116
githubから拝借させていただきました。

<?php
/* This file is part of EC-CUBE
* Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
* http://www.lockon.co.jp/
* For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
*/ 
namespace Eccube\Command;
 
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
 
class MailCommand extends Command
{
    protected static $defaultName = 'eccube:mail';

    /**
     * @var SymfonyStyle 
     */
     protected $io;

    public function __construct(\Swift_Mailer $mailer) { 
        parent::__construct();
        $this->mailer = $mailer;
    }

    protected function configure() {
        $this->setDescription('メールのテスト'); 
    }

    protected function initialize(InputInterface $input, OutputInterface $output) {
        $this->io = new SymfonyStyle($input, $output); 
    }

    protected function execute(InputInterface $input, OutputInterface $output) {
        $message = (new \Swift_Message())
            ->setSubject('メール送信チェック')
            ->setFrom('test01@example.com')
            ->setTo('test02@example.com')
            ->setBcc('test03@example.com')
            ->setReplyTo('test04@example.com')
            ->setReturnPath('test05@example.com');
        $this->mailer->send($message);
        $this->io->success('メール送信テスト完了.'); 
   }
 }

コマンド名になります。

protected static $defaultName = 'eccube:mail';
bin/console eccube:mail

テスト用の叩き台です。

コマンドクラスの挙動確認後

サービスクラスを作成しそこで、メール送るリストなどで選別しメールを送り完了

カテゴリー
EC-CUBE

【EC-CUBE4】設定

設定関連の情報をまとめて行きます。

設定ファイル

EC-CUBEは、「.env」ファイルに各種設定を記述します。

場所は、プロジェクト配下にあります。

「.env」ファイルは不可視ファイル

・確認にはオプション変更が必要

・ターミナルからコマンド実行の方は、「ls -la」コマンドで確認できます。

どんな設定があるの!?

複数あるので、重要な物を記述します。

・モードの設定

・DBの接続設定

・メールの設定

・Cookieの設定

DBの設定

envファイルの設定変更で、SQLが選べる。

こちらの3つ「sqlite, mysql, postgresql」が記述されています。

デフォルトはSQLite3になっている。

MySQLへ変更する場合

1行目を「#」でコメントアウトして、2行目の「#」を削除すればmysqlへ変更可能

SQLの再起動が必要かな!?

# DATABASE_URL=sqlite://var/eccube.db
 DATABASE_URL=mysql://dbuser:secret@mysql/eccubedb
# DATABASE_URL=postgresql://postgres/eccubedb?user=dbuser&password=secret

記述方法

mysql://dbuser:secret@mysql/eccubedb
SQL種類://ユーザー名:パスワード@ホスト名/データベース名

Docker-composeで作業している方は、ホスト名は「SQLのコンテナ名」になります。

MySQL初期ユーザーアカウント

ユーザーID:dbuser

パスワード:secret

メール設定

初期値は、メールが届かない設定になっているので変更しておきましょう。

gmail設定方法

# MAILER_URL=null://localhost
# MAILER_URL=sendmail://localhost
 MAILER_URL=gmail://「@前」:「パスワード」@localhost

Gmailブロックされたら

Gmailへ通知がきます。
来ない方は問題ないと思います。

Chromeの設定:セキュリティで変更可能

・二段階認証の解除

・安全性の低いアプリのアクセスの許可

MailCatcher設定方法

使用する方はこちら

MAILER_URL=smtp://mailcatcher:1025

こちら「http://127.0.0.1:1080/」にアクセスで使えます。

docker-compose.ymlのコンテナ名により記述が変わるっぽい─=≡Σ((( つ•̀ω•́)つ

MAILER_URL=smtp://127.0.0.1:1025

こんな感じの画面です。
ユーザーには送信されない為、開発にはすごく便利です。

カテゴリー
EC-CUBE

【EC-CUBE4】DB関連

データベース関連の情報をメモしていきます。

環境

EC-CUBE4
Docker-Composeでインストール
Mac

データベース名の変更

初期設定時の場合なので、途中で変更する際は注意下さい。

デフォルトのデータベース設定:eccubedb

変更するには下記ファイルのデータベース名の箇所を変更

.env
docker-compoae.yml

http://localhost:8080/へアクセスするとエラー

dbuserの権限で落ちてますね。

An exception occurred in driver: SQLSTATE[HY000] [1044] Access denied for user 'dbuser'@'%' to database データベース名

ではSQLで確認しましょう

DockerのコンテナへSQL接続

意味が違かったらすみません。

Dockerの下記画面で、黄色の枠のCLIを押せばコンテナのコマンドライン?が起動します。

コマンドラインからmysqlに接続

mysql -u root -p

デフォルトのパスワードは:root

sqlで権限確認

SHOW GRANTS FOR `dbuser`@`%`;

結果

 +------------------------------------------------------+
 | Grants for dbuser@%                                  |
 +------------------------------------------------------+
 | GRANT USAGE ON *.* TO 'dbuser'@'%'                   |
 | GRANT ALL PRIVILEGES ON `eccubedb`.* TO 'dbuser'@'%' |
 +------------------------------------------------------+
 2 rows in set (0.00 sec) 

eccubedbのみの権限になってましたね!

権限を付与していきます。

GRANT ALL ON データベース名.* TO 'dbuser'@`%`; 

データベースにコマンドラインから下記コマンドでデータ投入٩(๑’ꇴ’๑)۶

docker-compose exec ec-cube composer run-script compile 

結果:成功

 > bin/console doctrine:schema:create
 

  ! [CAUTION] This operation should not be executed in a production environment! 
 

  Creating database schema...
 

  [OK] Database schema created successfully!                                     
 

 > bin/console eccube:fixtures:load
   > Finished Successful! 

あとは「http://localhost:8080/」へアクセスして確認─=≡Σ((( つ•̀ω•́)つ

QueryBuilder

EC-CUBEに限らずPHP使うならほとんどのフレームワークに入っている─=≡Σ((( つ•̀ω•́)つ

IN

WHERE IN (1,2,3,4) どれかに該当するデータ

->where($qb->expr()->in('cn.name', $product_code))

JOIN

テーブル結合

->leftJoin('Eccube\Entity\OrderItem', 'oi', 'WITH', 'o.id = oi.id')    

MIN, MAX

cn.nameを長さで使用していたので違和感のある感じになっています。

 $qb->select('MIN(cn.name) min_value', 'MAX(cn.name) max_value')
    ->groupBy('cn.name');

CASE

指定の項目が条件にあった場合は、項目を置き換える。
nullは使い勝手が悪いから、「なし」とかに置き換えても使用可能

->addSelect("(case when t.period = '2020-01-01 00:00:00' then '7日前' else '3日前' end) AS return_date")

WHENが増えるとENDでエラーになる↓

->addSelect("(case when t.period1 = '2020-01-01 00:00:00' then '7日前' when t.period2 = '2020-01-01 00:00:00' then '3日前' end) AS return_date")
カテゴリー
EC-CUBE

【EC-CUBE4】カスタマイズ

バージョン:EC-CUBE4.0

いろいろ調べていて時間がかかったのでメモします

https://amzn.to/3ierEXx

カスタマイズ

EC-CUBE本体がsrc配下にあります。

本体パス:参考になるソースがあるので確認して下さいって感じです。

カスタマイズ対応クラス
  1. データ項目追加「Entity」
  2. サービス「Service」
  3. バリデーション「Form」
  4. 表示「Twig」

既存機能のカスタマイズは、基本的にControllerの修正なしで行える。

テンプレートは本体をコピー

本体パス:src/Eccube/Resource/template/

カスタマイズパス:app/template/

本体からカスタマイズへコピーする。

あとは、app/template/配下のファイルをカスタマイズするだけです。

Controller

本体パス:/src/Eccube/Controller/

カスタマイズパス:app/Customize/Controller/

カスタマイズパスへコントローラーの作成

既存のパスを上書きしたい場合は、アノテーションで指定すれば良いらしい

PHP
    /**
     * @Method("GET")
     * @Route("/test")
     */
    public function index(){

    }

Entity

本体パス:src/Eccube/Entity/

カスタマイズパス:app/Customize/Entity/

コマンドで作成可能
テーブルのカラム定義とgetter,setterも作ってくれる。

拡張する場合は「trait」

※プラグインのEntityをTraitしてCustomizeで定義するのは、やめた方が良い。

スキーマ更新時にエラーが発生する可能性があるのでプラグイン内でTraitする

Bash
bin/console make:entity

Repository

本体パス:src/Eccube/Repository/

カスタマイズパス:app/Customize/Repository/

Entityをコマンドで作成したら、合わせて作成してくれる。

Bash
bin/console make:entity

Command

本体パス:src/Eccube/Command/

カスタマイズパス:app/Customize/Command/

bin/consoleコマンドが作成出来る。

メルマガや定期処理を「cron」で行う際に使用した。

コマンドで作成可能

Bash
bin/console make:command

Form

本体パス:src/Eccube/Form/

カスタマイズパス:app/Customize/Form/

Fromクラスは、基本的にExtensionとTypeの2種類使用する

Extension既存のFromクラスの拡張で使用する。

既存の必須解除上書きやオプション追加や追加した項目のForm定義も可能

Type項目単体で定義しFormクラスで読み込んで使用する。

Service

本体パス:/src/Eccube/Service/

カスタマイズパス:app/Customize/Service/

サービスクラスの作成やデフォルトの拡張やプラグインのサービスの拡張も可能

app/config/eccube/services.yamlへ追加すれば拡張も可能

YAML
    Customize\Service\新規クラス名:
        decorates: 継承するクラスのパス
YAML
    Customize\Service\RegularOrderServiceCustomizer:
        decorates: Plugin\SlnRegular4\Service\RegularOrderService

・拡張したいサービスのファイルをCustomize/Service/配下へコピー

・namespaceを変更

・useへ拡張元のファイルパス

・extensへ拡張クラス名

※decoratesするとsrcのService処理を通らなくなる為、プラグインとの競合が発生する可能性あり

データベースへ項目追加

下記2種類の方法があるみたいですね。
今回は1の方法で行っていきます。

1.Entityクラスに項目を追加しコマンドでデータベースに反映する方法

2.Entityをテーブルから逆再生する方法
https://qiita.com/haruna-nagayoshi/items/27108c75eaf9511f3524

今回は「商品情報」へ「項目の追加」をしていきたいと思います。

エンティティの拡張

商品エンティティの拡張をしていきます。

商品エンティティを拡張するので「ProductTrait.php」を作成する。

商品マスタ:dtb_product
商品エンティティ:/src/Eccube/Entity/Product
ProductTraitの作成する場所:/app/Customize/Entity/ProductTrait.php

PHP
<?php
namespace Customize\Entity;
 
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;
 
/**
 * @Eccube\EntityExtension("Eccube\Entity\Product")
 */
trait ProductTrait
{
    /**
     * @var string|null
     *
     * @ORM\Column(name="product_symbol", type="string", length=45, nullable=true, options={"comment":"商品記号"})
     */
    public $product_symbol;

    /**
     * @var string|null
     *
     * @ORM\Column(name="packing_cost", type="decimal", precision=12, scale=2, nullable=true, options={"comment":"梱包料金"})
     */
    public $packing_cost;
}

コメントは入れるだけでもデータ構成の理解が早くなるのでなるべく書く٩(•̤̀ᵕ•̤́๑)

Proxyクラスの生成

Bash
cd プロジェクト配下
php bin/console eccube:generate:proxies
gen -> /Users/xxxxx/project/ec-cube/app/proxy/entity/src/Eccube/Entity/Product.php

ファイル変更後はキャッシュをクリア

Bash
bin/console cache:clear --no-warmup 

実行するSQLの確認

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

エラー!!!

In AbstractMySQLDriver.php line 93:
 An exception occurred in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known 

めちゃくちゃハマりましたο(´・ω・`o)

こちらの記事の原因と対応に感謝します─=≡Σ((( つ•̀ω•́)つ

https://qiita.com/kilica/items/6739b7a3d9992b593857

原因はDockerの知識が少ないところにありました。

macのターミナルでコマンド叩いてました。

EC-CUBE起動しているコンテナにログインしてコマンドを叩けば解決٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ

と思いましたが変更が反映されずダメでした。

[OK] Nothing to update - your database is already in sync with the current entity metadata.

結局先ほどコマンドで作成したProxyへ「カラムの定義」を追加
場所:ec-cube/app/proxy/entity/src/Eccube/Entity/Product.php

// キャッシュクリア
bin/console cache:clear --no-warmup
// テーブルとの差分で実行するSQL確認
php bin/console doctrine:schema:update --dump-sql
// 結果↓
The following SQL statements will be executed:
「実行するSQL」
// テーブルとの差分でSQLを実行する
bin/console doctrine:schema:update --dump-sql --force
//結果
「実行したSQL」
[OK] Database schema updated successfully!

Entityの更新が反映されない

Entityの修正した時に発生した◟꒰◍´Д‵◍꒱◞

キャッシュクリアすれば出来るって記事はあったけど関係なかった、、、

bin/console cache:clear --no-warmup

composerで依存関係が管理されていてそれを更新すれば、エラーを解消できた!!

EC-CUBE起動しているコンテナにログインしてコマンドを叩けば解決٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ

composer install

以上─=≡Σ((( つ•̀ω•́)つ

Dockerのコンテナにログインする方法

Dockerの下記画面で、黄色の枠のCLIを押せばコンテナへログインしたコマンドラインが起動します。

エンティティの作成

新規テーブル追加

app/config/eccube/pakages/devへ

maker.yamlファイルの追加

下記内容で保存

maker:
  root_namespace: 'Customize'

あとはターミナルのコマンドで解決
対話形式で作成していく

エンティティ作成コマンド

bin/console make:entity

コントローラー作成コマンド

bin/console make:controller

実行クエリ確認

どんなSQLを投げたのか確認したい事ありますよね!

dump($qb->getQuery()->getSQL());
exit;

こんな感じで確認できます٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ

商品登録画面

追加項目への必須が機能しない

いろいろ調べたら、required属性が機能していなかった。

formタグに「novalidate」検証無効の設定がされていた、、、

アノテーションの自動生成で実装していたので「Assert\NotBlank()」を追加し解決

商品の非公開設定

商品データ関連を入れた際に確認した情報

商品「dtb_product:product_status_id」で非公開が可能

結論を言うと「dtb_product:product_status_id=2」

product_status_id 1:公開, 2:非公開 3:廃止

ただ、関連テーブルに非表示がある「dtb_class_category・dtb_product_class」「visible」、、、

情報も非表示にした方が良いのか?

dtb_productと関連した情報を持っていた場合は、管理画面の商品検索でエラーになります。

商品一覧の検索にヒットしないなど、余計な事になるのでやらない方が良いです。

カテゴリー
EC-CUBE

【EC-CUBE4】メモ

バージョン:EC-CUBE4.0

初めて触れるものは、わからない事だらけですね。

何度も探すのはナンセンスなので、メモしておきます。

書籍も買いました!

読んだ感想としては、EC-CUBEってものの6割ぐらいはわかるんじゃないかな٩(•̤̀ᵕ•̤́๑)

https://amzn.to/3ierEXx

EC-CUBE4の設定関連はこちらにまとめています↓↓↓

【EC-CUBE4】設定

デフォルト設定

envファイル見れば良いのですが、一応記載

管理画面URL

http://プロジェクト名/admin
ログインID:admin
パスワード:password

SQL初期設定

mysql, postgresql
ユーザー名:dbuser
パスワード:secret
データベース名:eccubedb

クラス構成

Controller:ルーティング・サービス・モデル・ビューとのやりとり

Entity:SQLのテーブルをPHPにしたクラス
    ゲッターセッター
    アノテーションでいろいろ出来る

Repository:SQLを組んでリスト取得や表示順変更など行う

Service:注文や消費税など複数箇所で使用したり特定の機能として独立しているクラス

デバック方法

これ知らないと開発できませんね!

var_dump

devモードならdumpだけで、綺麗に整形してくれます。

dump($array);

実行クエリ確認

どんなSQLを投げたのか確認したい事ありますよね!

dump($qb->getQuery()->getSQL());
exit;

こんな感じで確認できます٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ

パラメータはないから、dumpで別途確認して下さい。

Doctrineのdump

パラメータを当て込んだSQLが確認できます。

PHP
    public function checkSql($qb) {

        $replaceTargets = [];
        foreach ($qb->getQuery()->getParameters()->toArray() as $key => $parameters) {
    
            $value = $parameters->getValue();
    
            $replaceTarget = '';
            if (is_array($value)) {
                $n = [];
                foreach ($value as $row) {
                    // exit;
                    if (is_array($row)) {
                        // array[1]で渡すパラメータ対応
                        $n[] = "'".$row[1]."'";
                    } elseif (is_object($row)) {
                        // オブジェクト指定はID、違う場合は変更する
                        $n[] = "'".$row->getId()."'";
                    } else {
                        $n[] = "'".$row."'";
                    }
                }
                $replaceTarget = implode(',', $n);
            } elseif (is_object($value)) {
                $replaceTarget = "'".$value->getId()."'";
            } else {
                $replaceTarget = "'".$value."'";
            }
            $replaceTargets[] = $replaceTarget;
        }
    
        $replace = vsprintf(str_replace('?', '%s', $qb->getQuery()->getSQL()), $replaceTargets);
    
        dump($replace);
    exit;
    }

Entity&Repositoryの確認

Controllerであれば「entityManager」は、親クラスで定義済み

$orderRepository = $this->entityManager->getRepository('Eccube\Entity\Order'); 
$order = $orderRepository->findAll();
dump($order); 

別途定義が必要な場合は、下記コードで使用する

use Doctrine\ORM\EntityManagerInterface;

Docker

今回は初めてDockerで、環境構築

開発環境構築途中でエラー

こちらのコマンド実行後にエラー

docker-compose up -d

エラー内容

Unknown SSL protocol error in connection to XXX

ウィルス対策ソフトのカスペルスキー入れているのですが、、、それ?
macを再起動してすぐにコマンド実行したら解決しました٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 6291464 bytes) in /var/www/html/vendor/easycorp/easy-log-handler/src/EasyLogFormatter.php on line 84

docker-compose exec eccube composer run-script compile

メモリ不足で発生します。

php.iniファイルでメモリを増やせばOK

Dockerはコンテナで設定

cd /usr/local/etc/php/
vi php.ini
memory_limit = 128M
↓
memory_limit = 512M

SQLへ初期データの登録

初期データは、EC-CUBEが用意しているデモ用の最低限のデータ

# スキーマ作成+初期データ投入
docker-compose exec ec-cube composer run-script compile

途中で初期化したくなったら

eccubeのサンプルデータも入ってます。

データベース削除:eccubedb デフォルト

データベース作成:CREATE DATABES eccubedb;

あとはさっきのコマンド流せば完了

# スキーマ作成+初期データ投入
docker-compose exec ec-cube composer run-script compile

Workbenchで接続

情報はenvファイルにあります。

 DATABASE_URL=mysql://dbuser:secret@mysql/eccubedb

Hostnameとport番号は、Dockerから確認しました。

パスワードは、「secret」です。