ECCube3 プラグイン開発 自分用メモ

間違いがあるかもしれないけど、動くものは作れたのでメモ。

## ■ 事前準備
- /app/config/eccube/database.ymlに記載されている情報を元に作る

1. DB作成 
 - `CREATE DATABASE データベース名;`
2. DBユーザー作成 + 権限付与
 - `GRANT ALL PRIVILEGES ON データベース名.*TO ユーザー名@ホスト名 IDENTIFIED BY 'パスワード';`

##  ■ プラグインの作り方の説明
- [非公式]http://oweleo.hatenablog.com/entry/2018/05/21/193009

##  ■ プラグインインストーラーの仕様
- http://doc.ec-cube.net/plugin_installer
 
## ■ デバッグモード
- ECCubeには、Symfonyのデバッグツールバーを表示するモードが用意されている。

【設定方法】
1.index_dev.phpファイルを開く
2.以下の内容にする

 ```php:html/index_dev.php
$allow = array(
    '127.0.0.1',
    'fe80::1',
    '::1',
    'xxx.xxx.xxx.xxx' ← ここに自分の環境のIPを設定
);
```
3.アクセスする際のURLに「index_dev」を挟んで接続する
例）
【通常】：http\://localhost/index.php/admin/
【デバッグモード】：http\://localhost/index_dev.php/admin/

## ■ ルーティング
```console:登録されているルーティングの一覧
php app/console router:debug
```

■ プラグインのルーティング

- Plugin/ServiceProvider/ 以下のphpファイルに記述する
- 【重要】<br>bindに使用する名称は、他の名称と重複禁止。重複すると使えない。
- ページ番号をURL渡し(GET)したい場合、別途ルーティングを用意するので、名前の重複には注意が必要

## ■ プラグインインストール/アンインストールコマンド

```console:インストールコマンド
php app/console plugin:develop install --code <ここにプラグインコード>
```

```console:アンインストールコマンド
php app/console plugin:develop uninstall --code <ここにプラグインコード>
```
※ プラグインコードは、config.ymlの「code」で指定した値を入れる

## ■ サイドメニューへの追加

```php:ServiceProvider.php
// サイドメニューへの登録
$app['config'] = $app->share($app->extend('config', function($config){
            // $config['nav'][A]
            // A：サイドバーへの表示順序
            $config['nav'][] = array(
                'id' => 'menu1',
                'name' => 'menu1_name',
                'url' => '',
                'has_child' => 'true',
                'child' => array(
                    array(
                        'id' => 'child_menu1',
                        'url' => 'ここにbindに使用する名称',
                        'name' => 'ここに画面に表示するメニュー名',
                    ),
                    array(
                        'id' => 'child_menu2',
                        'url' => 'ここにbindに使用する名称',
                        'name' => 'ここに画面に表示するメニュー名',
                    ),
                ),
            );

            return $config;
        }));
```


## ■ プラグインの設定
- app/cache/config_cache.phpに記載されている内容が優先的に読み込まれている為、プラグインのconfig.yml等に変更を行った場合、config_cache.phpも該当箇所を消さないと上書きされない。
- 特にEvent等を後から追加したりした場合は要注意

## ■ Doctrine関連
■ テーブルの作成〜リポジトリの生成までの手順

- YAMLでマッピング情報を作るのは大変なのでDBファースト方式で行いました。

【手順】
1. DBのツールを使いテーブルを作成<br>
【注意事項】<br>必ずDB側には「id」列が必要。<br>これがないとEntity作成時及びデータをInsertする際にもエラーが発生しハマる。
2. orm:convert:mappingコマンドを使用しデータベースからdcm.ymlを生成する。<br>

```console:orm:convert:mapping
php vendor/doctrine/orm/bin/doctrine orm:convert:mapping --namespace="Plugin\【1】\Entity\\" --from-database yml --filter=【2】 app/Plugin/FAQ/Resource/doctrine/
```

|引数|説明|
|---|---|
|【1】|--namespaceオプション。<br>namespaceを入力。<br>生成するYAMLファイルの先頭に記載される。|
|【2】|--filterオプション。<br>migrationで作ったテーブル名を指定するplg_hogehogeならPlgHogehogeと指定|
|出力先|app/Plugin/FAQ/Resource/doctrine/ この部分に指定した場所にマッピング用のYAMLファイルが出力される|

3.Entityファイルの作成

- orm:generate:entitiesコマンドを使用し、Entityファイルを生成する。

```console:orm:generate:entities
php vendor/doctrine/orm/bin/doctrine orm:generate:entities --filter="Plugin\【1】\Entity\【2】" --extend="Eccube\Entity\AbstractEntity" app/
```


|引数|説明|
|---|---|
|【1】|--filterオプション。<br>プラグインコード|
|【2】|--filterオプション。<br>エンティティ名|
|extendオプション|生成するEntityの継承元を指定|
|出力先|appと指定するとapp/Plugin/【1】/Entity/【2】に出力される|

■ よく使うコマンド
```console:doctrineのコマンド一覧
php vendor/doctrine/orm/bin/doctrine list
```

```console:マッピングファイルのチェックコマンド
php vendor/doctrine/orm/bin/doctrine orm:validate-schema
```

■ SQLの確認方法
クエリビルダーを使用した場合、SQLの内容を確認したい場合は以下の処理をDump/Echoなりすると表示される。

- `$qb->getQuery()->getDQL()`　<br>※$qb= Doctrine\ORM\QueryBuilderオブジェクト
  
■ リレーション

- https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html
- YAMLで記載するのは大変なので、なれるまではDBファーストの方が早いかも。

■ テンプレートエンジン

- https://symfony.com/doc/2.7/reference/forms/twig_reference.html
- View側でコントローラ側で設定したformの値を使用する方法<br>
`form.プロパティ名.value`

## ■ Form関連
- Type一覧
 - https://symfony.com/doc/current/reference/forms/types.html
- Pagerの説明
 - https://github.com/KnpLabs/KnpPaginatorBundle

### ■ FormType関連
■ フォームの制約

- https://symfony.com/doc/current/reference/constraints.html
- http://symfony.com/doc/2.7/forms.html
- http://symfony.com/doc/2.7/validation.html

■ フォームの描画

- https://doc.ec-cube.net/design_form

■ 入力チェック(isValid)

- isValidを呼び出した際に、見た目上エラーがなかったけど、XDebugでチェックした所 以下のメッセージが表示された。
 
`The CSRF token is invalid. Please try to resubmit the form.
(CSRFトークンが無効です。フォームを再送信してください。)`

対処として、twigに以下を追加で解消。

`{{ form_row(form._token) }}`

symfony2の場合、Formクラスを使用してFromを生成した場合Hiddenパラメーターに自動的にトークンが生成されるみたい。
しかし、Twig側に上記のコードを埋め込む必要がある。

## ■ PHPの言語仕様メモ

- use 使用するコンポーネントのパス as 別名 でエイリアス
- extends 継承

## ■ Plugin ブロック管理

- ブロックの追加とブロック用ファイルのコピー 
 - https://gist.github.com/kurozumi/c824508f0ad4aef2d406062d1a6e8868
- PluginManagerの注意
 -  ->setLogicFlg(Constant::ENABLED)    // これを有効にしないとテンプレートの描画イベントが引っかからない
- BlockPositionについて
 - https://inexio.jp/20150210-509/
- 各コピー先のフォルダは以下のパスに記載されているものからピックアップして使う
 - /app/config/eccube/path.yml
- プラグインの処理
 - 特にフックする必要がない場合、Event.php 系は使用しない
 - app/Plugin/ServiceProvider/ServiceProvider.php<br>上記にルーティングを記載し、必要であればコントローラー等を追記しFatControllerを避けて実装する 

## ■ 改行コードの扱い

- http://neta-abc.blogspot.com/2013/09/android-studiogitcoreautocrlf.html