New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.0(旧3.n)ドキュメント化に向けた情報や実装の参考にしたい情報 #3380

Closed
t-nagahashi opened this Issue Jul 23, 2018 · 16 comments

Comments

Projects
None yet
5 participants
@t-nagahashi
Contributor

t-nagahashi commented Jul 23, 2018

概要(Overview)

http://doc3n.ec-cube.net/ に追加していきたい内容や、
今後の実装の参考にしたいネタを書き留めておくためのIssue
随時、コメントなどで貯めていきます。好きにコメントいただいてもいいです。
見づらくなってきたりしたら、調整します。

関連情報 (Ref)

#1330

@t-nagahashi t-nagahashi added this to the 3.n.0 milestone Jul 23, 2018

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Jul 23, 2018

3.nのプラグインとして推奨する実装方針や参考情報

利用者の方々により安心して使っていただけるプラグインを作っていただくために、3.nのプラグインとして推奨する実装方針や参考情報をまとめました。

※ご注意※
まだ3.nが開発途中であることと、これからプラグイン開発者の皆様からのフィードバックを頂き改善を進めていくため、記載内容に変更が発生する可能性がございます。


命名規約について

プラグイン同士での名前の衝突(ルーティング名/テーブル名/定数名など)を避けるため、
命名規約への準拠をお願いします。

EC-CUBE/sample-payment-plugin#6


フロント/管理画面へのUI要素の追加について

デザインカスタマイズ時に表示がされなくなるなどのトラブルを避けるため、
以下の方法でのUI要素の追加を推奨します。

TwigBlockを提供する方法 (フロント画面向け)

プラグインで独自のBlockを定義できます。
プラグイン利用者が、Twigファイル内にBlock表示用のコードを記述することでUI要素を追加できます。

詳細/サンプルコード
https://github.com/EC-CUBE/sample-payment-plugin#twig%E3%83%A6%E3%83%BC%E3%82%B6%E5%AE%9A%E7%BE%A9%E9%96%A2%E6%95%B0%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF

2018/8/5 EC-CUBE 3.n-β 以降では、TwigBlockではなく下記のincludeの利用を推奨します。

includeを利用する方法 (フロント画面向け)

プラグインで独自のtwigファイルを追加できます。
プラグイン利用者が、Twigファイル内にincludeコードを記述することでUI要素を追加できます。

以下のようにすることで、プラグイン側から独自の変数を追加することもできます。

class Event implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            'Product/detail.twig' => 'onDetail',
        ];
    }

    public function onDetail(TemplateEvent $event)
    {
        $event->setParameter('hoge', 'hello!! ');
    }
}

詳細/サンプルコード
https://github.com/EC-CUBE/ProductReview-plugin/tree/experimental/sf

TemplateEventでUI要素を追加する方法 (フロント画面/管理画面向け)

TemplateEventを利用することで「</body>タグ直前」または「<head></head>内」に出力するコードを追加できます。
ここにJavaScriptのコードを出力することでUI要素を追加できます。

詳細/サンプルコード
https://github.com/EC-CUBE/sample-payment-plugin#%E7%94%BB%E9%9D%A2%E3%81%B8%E3%81%AE%E4%BB%8B%E5%85%A5%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

非推奨

3.0系プラグインで利用されていた「Twigファイルの内容を正規表現で置き換える」方法は、
デザインカスタマイズ時や複数プラグイン導入時に表示されなくなるなどのトラブルが起きやすいため、
3.n系では非推奨となります。


3.n系で追加された拡張機構について

3.n系ではプラグインからも利用できる拡張機構が追加になりました。

従来のフックポイントを使った拡張も可能ですが、
拡張機構を使うことで、3.0系よりも少ないコードで、他のプラグインとも共存しやすい実装が可能になります。

カラムの追加

Entityの拡張機構を使うことで、
既存のテーブルに対してプラグイン独自のカラムを追加することが可能になりました。
http://doc3n.ec-cube.net/customize_entity

ソート順や検索条件の変更

Repositoryの拡張機構を使うことで、
ソート順や検索条件のカスタマイズを行いやすくなりました。
http://doc3n.ec-cube.net/customize_repository

購入フローのカスタマイズ

Serviceの拡張機構を使うことで、
カートや購入処理のカスタマイズが可能になります。
http://doc3n.ec-cube.net/customize_service


プラグインのサンプルについて

サンプルプラグインでは、以下のような拡張を行っています。

商品レビュープラグイン

https://github.com/EC-CUBE/ProductReview-plugin/tree/experimental/sf

  • フロント画面/管理画面への新規ページの追加
  • TwigBlockによるUI要素の追加
  • TemplateEventによるUI要素の追加
  • プラグイン用テーブルの追加
  • 管理画面サイドメニューへの項目追加
  • プラグイン有効時/削除時の処理
  • CSVの出力

メーカー管理プラグイン

https://github.com/EC-CUBE/maker-plugin/tree/experimental/sf

  • フォーム(ProductType)への項目の追加
  • プラグイン用テーブルの追加
  • Product(dtb_product)へのカラムの追加
  • TwigBlockによるUI要素の追加
  • 管理画面サイドメニューへの項目追加

その他参考となる情報

EC-CUBE 3.n 開発ドキュメント
http://doc3n.ec-cube.net/

決済プラグイン向けサンプルのREADME
https://github.com/EC-CUBE/sample-payment-plugin/

GitHubで"document"ラベルの付いたIssue/Pullrequest
https://github.com/EC-CUBE/ec-cube/issues?utf8=%E2%9C%93&q=label%3Adocument+milestone%3A3.n.0+

@Yangsin

This comment has been minimized.

Contributor

Yangsin commented Jul 26, 2018

ログ出力方法

ログ出力のグローバル関数が用意されているのでどこからでも呼び出せる。

log_info('ログメッセージ');

ログレベル別に関数がわかれているので適切な関数を利用すること。

log_emergency()
log_alert()
log_critical()
log_error()
log_warning()
log_notice()
log_info()
log_debug()

関数の定義は以下

/src/Eccube/Resource/functions/log.php

ログの出力先

/var/log/ 配下に出力される。

環境に合わせてさらにディレクトリが別れる。
環境の設定は .env ファイルの APP_ENV で指定可能。

例えば

  • 本番環境( APP_ENV=prod )のときは /var/log/prod 配下にログ出力される。
  • 開発環境( APP_ENV=dev )のときは /var/log/dev 配下にログ出力される。

ログの設定変更

環境ごとの設定ファイルを修正してログの設定変更が可能。

例えば

  • 本番環境( APP_ENV=prod )の設定は /app/config/eccube/packages/prod/monolog.yml に記載されている。
  • 開発環境( APP_ENV=dev )の設定は /app/config/eccube/packages/dev/monolog.yml に記載されている。

参考

log_info('ログメッセージ'); でログメッセージを出力可能です。特別な設定は不要ですが、 .env ファイルの APP_ENV の値で設定が若干変わります。

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 6, 2018

プラグインで管理画面のメニューを追加する方法

ルート階層に追加できないなどの課題があったため #3450 で修正を行いました。
これに伴い、EccubeNavインターフェイスのgetNav関数の仕様が変更となります。

新しい実装例

<?php

namespace Customize;

use Eccube\Common\EccubeNav;

class CustomizeNav implements EccubeNav
{
    /**
     * @return array
     */
    public static function getNav()
    {
        return [
            // 商品管理に子メニューを追加する場合のサンプル
            'product' => [
                'children' => [
                    'sampleplugin_my_product_menu_item' => [
                        'name' => '商品管理の子(追加)',
                        'url' => 'admin_homepage',
                    ],
                ],
            ],
            // 第一階層からオリジナルのメニューを追加する場合のサンプル
            'sampleplugin_my_root_menu' => [
                'name' => '1階層メニュー(追加)',
                'icon' => 'fa-cube',
                'children' => [
                    'sampleplugin_my_menu_item' => [
                        'name' => '2階層メニュー(子なし)',
                        'url' => 'admin_homepage',
                    ],
                    'sampleplugin_my_menu' => [
                        'name' => '2階層メニュー(子あり)',
                        'children' => [
                            'sampleplugin_my_menu_item1' => [
                                'name' => '3階層メニュー1',
                                'url' => 'admin_homepage',
                            ],
                            'sampleplugin_my_menu_item2' => [
                                'name' => '3階層メニュー2',
                                'url' => 'admin_homepage',
                            ],
                        ],
                    ],
                ],
            ],
        ];
    }
}

EC-CUBE 3.n alpha-5 までの実装方法との差分は、以下リンク先のSamplePaymentNav.phpの差分をご確認ください。
https://github.com/EC-CUBE/sample-payment-plugin/pull/21/files#diff-e3a85f9690175ca0da690d9eaec5c7b8

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 6, 2018

コントローラの無いtwigの拡張方法

EC-CUBE 3.n alpha-5 までは拡張できませんでしたが、 #3441 の修正で「コントローラのあるtwig」 と同じ実装方法で拡張できるようになりました。

実装例: https://github.com/EC-CUBE/ProductReview-plugin/blob/038b915c815f786c5ff5c22c1a3c94ae15f0dc54/ProductReviewEvent.php#L60

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 6, 2018

フロント画面の拡張についてですが、「includeを利用する方法」が推奨となりました。
(「TwigBlockを提供する方法」はincludeで代替ができます)

記載UPdateしております。
#3380 (comment)

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 7, 2018

受注のステートマシン

4.0-beta 以降の受注は以下のステートマシンに則って実装してあります。
#3325

@Yangsin Yangsin changed the title from 3.nドキュメント化に向けた情報や実装の参考にしたい情報 to 4.0(旧3.n)ドキュメント化に向けた情報や実装の参考にしたい情報 Aug 7, 2018

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 10, 2018

コントローラのRoute/Methodアノテーションの記述方法について

背景

Sensio\Bundle\FrameworkExtraBundle\Configuration\Route
Sensio\Bundle\FrameworkExtraBundle\Configuration\Method
がdeprecatedのため、以下の新しい記載方法を推奨します。

Routeアノテーションの変更

ルーティング定義に
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
を利用していたのを
use Symfony\Component\Routing\Annotation\Route;
に変更。

※アノテーションの記述方法は今までと同じ

Methodアノテーションの変更

廃止:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
を利用して
@Method('DELETE')
等のようにHTTPメソッドを宣言していたのを廃止。

新:
Routeアノテーション定義の中にあるmethodsパラメータに対して設定
@Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})

※宣言が必要なければmethodsは省略可能

EC-CUBE本体も #3517 で対応済みです。

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 11, 2018

管理画面とマイページの受注ステータスの対応表

ID OrderStatus
管理画面
CustomerOrderStatus
マイページ受注詳細
1 新規受付 注文受付
6 入金済み 注文受付
4 対応中 注文受付
3 注文取り消し 注文取消し
5 発送済み 発送済み
8 購入処理中 注文未完了
7 決済処理中 注文受付
9 返品 返品
@okazy

This comment has been minimized.

Contributor

okazy commented Aug 14, 2018

プラグインから独自にログファイルを出力する方法

対応したPR

#3530

プラグインでの利用方法

  1. [プラグインディレクトリ]/Resource/config/services.yaml というファイルを作成する。
  2. 作成したservices.yamlに対して以下の内容を記述する。
monolog:
    channels: ['プラグインコード名']
    handlers:
        プラグインコード名:
            type: fingers_crossed
            action_level: error
            passthru_level: info
            handler: プラグインコード名_rotating_file
            channels: ['プラグインコード名']
            channels: ['!event', '!doctrine']
        プラグインコード名_rotating_file:
            type: rotating_file
            max_files: 60
            path: '%kernel.logs_dir%/%kernel.environment%/出力したファイル名.log'
            formatter: eccube.log.formatter.line
            level: debug
  1. プラグインからは以下のように呼び出す
logs('プラグインコード名')->info('ああああああ');
  1. ログの内容が出力されているかどうか確認
[EC-CUBEのディレクトリ]/var/log/[prodまたはdev等]/出力したファイル名-YYYY-MM-DD.log
  1. ログフォーマッットの記述を変更したい時は以下を設定する。
services:
    プラグインコード名.log.formatter.line:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "[%%datetime%%] %%level_name%% [%%extra.session_id%%] %%message%% [%%extra.ip%%, %%extra.referrer%%, %%extra.user_agent%%]\n"

monolog:
    channels: ['プラグインコード名']
    handlers:
        プラグインコード名:
            type: fingers_crossed
            action_level: error
            passthru_level: info
            handler: プラグインコード名_rotating_file
            channels: ['プラグインコード名']
            channels: ['!event', '!doctrine']
        プラグインコード名_rotating_file:
            type: rotating_file
            max_files: 60
            path: '%kernel.logs_dir%/%kernel.environment%/出力したファイル名.log'
            formatter: プラグインコード名.log.formatter.line
            level: debug

上記のargumentsにある設定で出力する内容が変更可能。

logs('プラグインコード名')->info('ああああああ');

と出力した場合、%%message%% ああああああ が出力される。

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 23, 2018

プラグインのconfig.yml廃止とcomposer.jsonの追加

以下のPullRequestにてプラグインの情報を記載するファイルが、config.ymlからcomposer.jsonに変更となりました。

プラグインのcomfig.ymlを廃止してcomposer.jsonに記述を統一 by kiy0taka
#3630

config.yml(廃止)

name: 商品レビュープラグイン	
code: ProductReview	
version: 4.0.0


composer.json(新規)

{
    "name": "ec-cube/ProductReview",
    "version": "4.0.0",
    "description": "商品レビュープラグイン",
    "type": "eccube-plugin",
    "require": {
        "ec-cube/plugin-installer": "~0.0.6"
    },
    "extra": {
        "code": "ProductReview"
    }
}
@okazy

This comment has been minimized.

Contributor

okazy commented Aug 24, 2018

PostgeSQL10に対応に伴うシステム要件の変更
#3401

@okazy

This comment has been minimized.

Contributor

okazy commented Aug 29, 2018

PurchaseFlowへのプロセッサの追加方法

#3289

PurchaseFlowに追加する新しいProcessorを作成する

追加できるプロセッサ

以下のクラスまたはインタフェースを継承または実装している必要がある

  • ItemPreprocessor
  • ItemValidator
  • ItemHolderPreprocessor
  • ItemHolderValidator
  • PurchaseProcessor

追加対象のフローの指定方法

  • カートのPurchaseFlowにProcessorを追加する場合は @CartFlow アノテーションを追加
  • 購入フローのPurchaseFlowにProcessorを追加する場合は @ShoppingFlow アノテーションを追加
  • 管理画面でのPurchaseFlowにProcessorを追加する場合は @OrderFlow アノテーションを追加

商品を1個のみしか購入できないようにするサンプル

<?php
namespace Plugin\PurchaseProcessors\Service\PurchaseFlow\Processor;

use Eccube\Annotation\CartFlow;
use Eccube\Annotation\OrderFlow;
use Eccube\Annotation\ShoppingFlow;
use Eccube\Entity\ItemInterface;
use Eccube\Service\PurchaseFlow\InvalidItemException;
use Eccube\Service\PurchaseFlow\PurchaseContext;
use Eccube\Service\PurchaseFlow\ItemValidator;

/**
 * 商品を1個のみしか購入できないようにするサンプル
 *
 * @CartFlow
 * @ShoppingFlow
 * @OrderFlow
 */
class SaleLimitOneValidator extends ItemValidator
{
    /**
     * @param ItemInterface $item
     * @param PurchaseContext $context
     *
     * @throws InvalidItemException
     */
    protected function validate(ItemInterface $item, PurchaseContext $context)
    {
        if (!$item->isProduct()) {
            return;
        }

        $quantity = $item->getQuantity();
        if (1 < $quantity) {
            $this->throwInvalidItemException('商品は1個しか購入できません。');
        }
    }

    protected function handle(ItemInterface $item, PurchaseContext $context)
    {
        $item->setQuantity(1);
    }
}
@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 31, 2018

購入フローのエラーハンドリングおよびPurchaseFlowの実行順序見直し

概要(Overview・Refs Issue)

購入フローで、エラーがあっても復旧可能であれば極力注文を継続できるよう、カートのように丸め処理を行い、注文手続き画面から再開できるようにエラーハンドリングを見直しました。
上記の変更に伴い、PurchaseFlow::validateの実行順序を変更しています。
PurchaseFlow::validateの実行順序
PurchaseFlow::validateは、以下の順で実行されます。

ItemValidator
ItemHolderValidator
ItemPreprocessor
ItemHolderProcessor
DiscountProcessor(新設)
ItemHolderPostValidator(新設)

詳細はこちら #3714

@ryo-endo

This comment has been minimized.

Contributor

ryo-endo commented Aug 31, 2018

PluginManagerの関数の引数変更について

#3707

対象関数: install,update,enable,disable,uninstall
変更内容:引数の変更
サンプル:
public function install($meta = null, Application $app = null, ContainerInterface $container)

public function install(array $meta, ContainerInterface $container)

変更の背景ですが、
$appは3系との互換性のために残していしたが利用は非推奨となっています。
引数に非推奨のインスタンスがあることで実装時の混乱や、プラグインの互換性を損なってしまわないためにも、
PluginManagerの関数の引数から$appは削除することとなりました。

お手数をおかけしますが、
PluginManagerの中でinstall/update/enable/disable/uninstall関数を定義している場合は、
上記サンプルを参考に引数の変更をお願いいたします。
(※関数を定義していない場合はとくに対応不要です)

なお、やむを得ず$appをしたい場合は以下のコードでcontainerから取得可能です。
$app = $container->get('app');

サンプルプラグインでの変更例

EC-CUBE/sample-payment-plugin#25
EC-CUBE/ProductReview-plugin#36

@okazy

This comment has been minimized.

Contributor

okazy commented Oct 16, 2018

rank 等の不適切なカラム名の変更

下記のプルリクでカラム名の変更をしています。

#2643

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment