Ticket #1692 (closed 新規開発: 修正済)

Opened 8 years ago

Last modified 8 years ago

プラグイン機能

Reported by: h_yoshimoto Owned by: h_yoshimoto
Priority: Milestone: EC-CUBE2.12.0
Component: その他 Version: 2.12.0 α
Keywords: Cc:
修正済み: yes

Description (last modified by AMUAMU) (diff)

■プラグイン機能仕様書

 http://downloads.ec-cube.net/src/manual/12.0_plugin/plugin.pdf

 http://downloads.ec-cube.net/src/manual/12.0_plugin/hook_point.pdf
※動的なフックポイント生成に r21743 にて切り替えた為、もし一覧にあって呼出が無いフックポイントがありましたら、御報告を下さい。

●プラグイン・エンジン
プラグイン機能のコア

●フックポイント
フックポイントを使ってプラグインは処理に介入します。

●トランスフォーマー(ヘルパー)
プラグインがテンプレートを変更する際に仕様するインターフェイス

以下のチケットを統合しました
#1603 #1632 #1686 #1687

Attachments

RecordIPaddress.tar Download (27.0 KB) - added by eccuore 8 years ago.
uninstall時の処理追加、addActionでpriority追加、prefilterTransformにreplaceElementのパターンとinsertAfterのパターンを追加
SampleClassHook.tar.gz Download (15.4 KB) - added by AMUAMU 8 years ago.
SC系クラスフックのサンプル
CategoryContents.tar.gz Download (4.4 KB) - added by h_yoshimoto 8 years ago.
カテゴリコンテンツ
TopicPath.tar.gz Download (11.3 KB) - added by h_yoshimoto 8 years ago.
パンくず

Change History

comment:1 Changed 8 years ago by h_yoshimoto

  • Description modified (diff)

comment:2 Changed 8 years ago by h_yoshimoto

  • Status changed from new to assigned

comment:3 Changed 8 years ago by h_yoshimoto

  • Version changed from 2.11.4 to 2.12.0 α

comment:4 Changed 8 years ago by h_yoshimoto

  • Description modified (diff)

comment:5 Changed 8 years ago by kajiwara

  • Description modified (diff)

comment:6 follow-up: ↓ 7 Changed 8 years ago by Seasoft

動作未確認ですが、ソース査読にて lc_page_products_list_action_end が2連続実行しているように思います。

comment:7 in reply to: ↑ 6 Changed 8 years ago by h_yoshimoto

Seasoft への返信

動作未確認ですが、ソース査読にて lc_page_products_list_action_end が2連続実行しているように思います。

ありがとうございます。r21669 にて対応させて頂きました。

comment:8 Changed 8 years ago by h_yoshimoto

r21671 にて各プラグインの設定画面を呼び出し方を変更。モジュール同様に認証可否判定を通るようにしました。

comment:9 follow-up: ↓ 11 Changed 8 years ago by h_yoshimoto

プラグイン機能のクラス設計について

現状のSC_Helper_Pluginには
プラグインエンジンとしての役割(各Pageクラスで使用)と
DBからデータ取得などの役割(Pageクラス・エンジン部分で使用)
が混同しています。

そこで、エンジン部分とデータ取得部分を分離させようかと考えています。
以下の仕様で考えていますが、いかがでしょうか?

エンジン部分→SC_Helper_Plugin
データ取得部分→data/plugin/SC_Plugin.phpを作成。

ご懸念される点がございましたら、ご意見頂ければと思います。

問題無ければ進めさせて頂きます。

comment:10 Changed 8 years ago by h_yoshimoto

r21672 にてregistをregisterに変更
合わせてサンプルプラグインも修正

Changed 8 years ago by eccuore

uninstall時の処理追加、addActionでpriority追加、prefilterTransformにreplaceElementのパターンとinsertAfterのパターンを追加

comment:11 in reply to: ↑ 9 Changed 8 years ago by h_yoshimoto

h_yoshimoto への返信

プラグイン機能のクラス設計について

現状のSC_Helper_Pluginには
プラグインエンジンとしての役割(各Pageクラスで使用)と
DBからデータ取得などの役割(Pageクラス・エンジン部分で使用)
が混同しています。

そこで、エンジン部分とデータ取得部分を分離させようかと考えています。
以下の仕様で考えていますが、いかがでしょうか?

エンジン部分→SC_Helper_Plugin
データ取得部分→data/plugin/SC_Plugin.phpを作成。

ご懸念される点がございましたら、ご意見頂ければと思います。

問題無ければ進めさせて頂きます。

r21681 にて対応しました。

comment:12 Changed 8 years ago by h_yoshimoto

r21689 にてプラグインエンジンのインスタンス生成時の処理を統一

comment:13 Changed 8 years ago by h_yoshimoto

21693 r21694 にてフックポイント名を変更

comment:14 Changed 8 years ago by h_yoshimoto

  • Description modified (diff)

comment:15 Changed 8 years ago by h_yoshimoto

  • Description modified (diff)

comment:16 Changed 8 years ago by Yammy

SLTEXT_LEN という TYPO があったので、r21705 で修正しておきました。

comment:17 Changed 8 years ago by adachi

TO:h_yoshimoto

SC_Plugin_Util::deletePluginByPluginIdで、commitし忘れているようにみえるのですが、これはあってます?

    function deletePluginByPluginId($plugin_id) {
        $objQuery =& SC_Query_Ex::getSingletonInstance();
        $objQuery->begin();
        $where = 'plugin_id = ?';
        $objQuery->delete('dtb_plugin', $where, array($plugin_id));
        $objQuery->delete('dtb_plugin_hookpoint', $where, array($plugin_id));
    }

comment:18 follow-up: ↓ 19 Changed 8 years ago by adachi

CategoryContents?でWaringがぽろぽろ

2012/04/09 01:06:21 [/products/list.php] Warning(E_WARNING): Missing argument 3 for SC_Helper_Plugin::addAction(), called in /mnt/NetBeans/version-2_12-dev/data/downloads/plugin/CategoryContents/CategoryContents.php on line 168 and defined on [/mnt/NetBeans/version-2_12-dev/data/class/helper/SC_Helper_Plugin.php(154)] from 192.168.56.1
2012/04/09 01:06:22 [/products/list.php] Warning(E_WARNING): array_key_exists() [<a href='function.array-key-exists'>function.array-key-exists</a>]: The second argument should be either an array or an object on [/mnt/NetBeans/version-2_12-dev/data/class/helper/SC_Helper_Transform.php(483)] from 192.168.56.1

comment:19 in reply to: ↑ 18 Changed 8 years ago by h_yoshimoto

adachi さんへの返信

CategoryContents?でWaringがぽろぽろ

2012/04/09 01:06:21 [/products/list.php] Warning(E_WARNING): Missing argument 3 for SC_Helper_Plugin::addAction(), called in /mnt/NetBeans/version-2_12-dev/data/downloads/plugin/CategoryContents/CategoryContents.php on line 168 and defined on [/mnt/NetBeans/version-2_12-dev/data/class/helper/SC_Helper_Plugin.php(154)] from 192.168.56.1
2012/04/09 01:06:22 [/products/list.php] Warning(E_WARNING): array_key_exists() [<a href='function.array-key-exists'>function.array-key-exists</a>]: The second argument should be either an array or an object on [/mnt/NetBeans/version-2_12-dev/data/class/helper/SC_Helper_Transform.php(483)] from 192.168.56.1

ご報告ありがとうございます。
r21728 にて対応致しました。

comment:20 Changed 8 years ago by h_yoshimoto

  • Description modified (diff)
  • Summary changed from プラグイン機能(α版) to プラグイン機能

comment:21 Changed 8 years ago by AMUAMU

r21742 にて、SC_系のクラス読込をフックする機能を追加しました。

●概要
クラスの読み込み変更は、PHPのオートロード機能に介入する形で行われます。

●使用方法
使用するには他のフックポイントと同様にプラグインのregist関数に定義します。フックポイント名は「loadClassFileChange」

        $objHelperPlugin->addAction('loadClassFileChange', array(&$this, 'loadClassFileChange'), 1);

対応するコールバック関数を定義します。
定義されたコールバック関数には以下のパラメーターが渡されます。
$classname / 読み込む事を要求されたクラスの名前
$classpath / 本来読み込む予定であるクラスファイルのパス
処理例

    function loadClassFileChange(&$classname, &$classpath) {
        if($classname == 'SC_Customer_Ex') { // 変えたいクラス名でフィルタ,*_Exにフィルタ推奨
            // 代替読み込みされるクラスファイルを用意
            $classpath = PLUGIN_UPLOAD_REALDIR . "CategoryContents/SC_MyCustomer.php";
            // 上で指定した代替読み込みされるファイル内のクラス名が、本来の読み込み先と違うクラス名の場合、$classname を変更するクラス名にする。
            $classname = 'SC_MyCustomer';
        }
    }

このコールバック関数では、特別な処理がされますので注意が必要です。
(1)$classname が本来読み込むクラスと別の名前を設定して関数が終わった場合

→ 自動的に、本来読み込む予定だったSC_XXXX_Exのextends を新しく指定された$classname に書き換えます。これにより、下記のようなextends関係になります。

SC_XXXX_Ex -> SC_XXXX の関係から、 SC_XXXX_Ex -> $classname (-> SC_XXXX) と変える。

$classname で新しく指定されたクラスは、_ExではないSC_をextendsしていることが推奨される。

(2)$classname が本来読み込むクラスと同名の場合

新しく指定された$classpath のみが読み込まれます。
_Exは無視されますが、_Ex無視はカスタマイズをする人から分かりにくくなるため(1)の利用方法が望ましいです。

comment:22 Changed 8 years ago by AMUAMU

SC_系のクラス読込をフックする機能の注意点 ・全てのクラスがフックされるわけではないです。
現状ではDB接続が有効になった後に遅延ロードされるクラスのみとなります。
代表的な部分: SC_Customer_Ex 、SC_View_Ex、SC_SiteView_Ex、SC_AdminView_Ex、SC_Helper_Customer_Ex、SC_PageNavi_Ex、SC_CheckError_Ex、SC_Product_Ex、SC_FormParam_Ex、SC_Cookie_Ex、SC_SiteSession_Ex、SC_Helper_Purchase_Ex、SC_SendMail_Ex、SC_Helper_Mail_Ex、PEARモジュール系、などなど

comment:23 Changed 8 years ago by AMUAMU

補足:クラス読込をフックする機能は、動作の根幹に介入する処理のため慎重に取り扱いをしましょう

Changed 8 years ago by AMUAMU

SC系クラスフックのサンプル

comment:24 Changed 8 years ago by AMUAMU

  • Description modified (diff)

comment:25 Changed 8 years ago by shutta

横からすみません。
コンストラクタを継承しやすくするために、SC_Plugin_Baseのコンストラクタ名をPHP5以降で標準的な__constructに修正しました。(r21766)

comment:26 follow-up: ↓ 27 Changed 8 years ago by eccuore

SC系クラスをフック出来るのは素晴らしいですね。
新たにプラグインを2個ほど作成しております。
その中でエラーが発生しておりましたのでご報告させて頂きます。
PC,スマホは問題無く動いたのですが、モバイルのみ下記エラーが出ております

2012/04/20 11:48:48 [/version-2_12-dev/html/index.php] Warning(E_WARNING): include(/html/../data/class/plugin/SC_Plugin_Base.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory on [/data/class/SC_ClassAutoloader.php(99)] from 127.0.0.1
customer_id = 
/html/index.php(24): require_once
/html/require.php(35): require_once
/data/require_base.php(45): SC_SessionFactory_UseRequest->initSession
/data/class/sessionfactory/SC_SessionFactory_UseRequest.php(213): LC_UseRequest_State_Mobile->inisializeSessionData
/data/class/sessionfactory/SC_SessionFactory_UseRequest.php(526): LC_UseRequest_State_Mobile->updateModel
/data/class/sessionfactory/SC_SessionFactory_UseRequest.php(486): spl_autoload_call(): SC_ClassAutoloader::autoload
/data/class/SC_ClassAutoloader.php(73): SC_Helper_Plugin::getSingletonInstance
/data/class/helper/SC_Helper_Plugin.php(83): SC_Helper_Plugin->load
/data/class/helper/SC_Helper_Plugin.php(59): require_once
/data/downloads/plugin/XXXX/XXXX.php(5): spl_autoload_call(): SC_ClassAutoloader::autoload
/data/class/SC_ClassAutoloader.php(99): SC_ClassAutoloader::autoload
/data/class/SC_ClassAutoloader.php(99): SC_Helper_HandleError::handle_warning

comment:27 in reply to: ↑ 26 Changed 8 years ago by adachi

eccuore さんへの返信

こちらでも再現いたしました。

SC_Plugin_BaseをAutoLoaderでrequireするようにすることで対処可能かと思います。

詳細はのちほど記載いたします。 取り急ぎ以下にチケットを作成しました。

http://svn.ec-cube.net/open_trac/ticket/1775

comment:28 Changed 8 years ago by eccuore

スマホの購入確認画面(/data/Smarty/templates/sphone/shopping/payment.tpl)に対してinsertAfterなどでタグを追加するとHTML出力がおかしくなります。

<!--▼検索バー -->
<section id="search_area">
        <input type="hidden" name="transactionid" value="af0d4d86d9af30a1200e0af400dec8a5524c33be"><input type="hidden" name="mode" value="search"><div class="ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield ui-body-f"><input type="text" data-type="search" name="name" id="search" value="" placeholder="キーワードを入力" class="searchbox ui-input-text ui-body-f"><a href="#" class="ui-input-clear ui-btn ui-btn-up-f ui-btn-icon-notext ui-btn-corner-all ui-shadow ui-input-clear-hidden" title="clear text" data-theme="f"><span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">clear text</span><span class="ui-icon ui-icon-delete ui-icon-shadow"></span></span></a></div>

</section><!--▲検索バー --><!--▲コンテンツここまで -->            <!-- ▲メイン -->

                                            </section></form></section></div>

具体的には、下記formがform1の中に入り込む状態になっており、

<!--▼検索バー -->
<section id="search_area">
    <form method="get" action="<!--{$smarty.const.ROOT_URLPATH}-->products/list.php">
        <input type="hidden" name="<!--{$smarty.const.TRANSACTION_ID_NAME}-->" value="<!--{$transactionid}-->" />
        <input type="hidden" name="mode" value="search" />
        <input type="search" name="name" id="search" value="" placeholder="キーワードを入力" class="searchbox" >
    </form>
</section>
<!--▲検索バー -->

下記formタグが無い状態になっています

<form method="get" action="<!--{$smarty.const.ROOT_URLPATH}-->products/list.php">

comment:29 follow-up: ↓ 30 Changed 8 years ago by Seasoft

アップデートした時に、plugin_info.php の内容が反映されていないように思います。

詳細な動作は未確認ですが、取り急ぎご報告。

comment:30 in reply to: ↑ 29 Changed 8 years ago by Seasoft

アップデートした時に、plugin_info.php の内容が反映されていないように思います。

そもそも、何も反映されないかも。

plugin_update.php 辺りでの定義が必要なんですかね。

comment:31 Changed 8 years ago by Seasoft

「オーナーズストア>プラグイン管理」画面で、plugin_info::AUTHOR_SITE_URL が正しく適用されないようです。

CategoryContents.tar.gz Download で確認。

Changed 8 years ago by h_yoshimoto

カテゴリコンテンツ

Changed 8 years ago by h_yoshimoto

パンくず

comment:32 Changed 8 years ago by h_yoshimoto

  • Status changed from assigned to closed
  • 修正済み set
  • Resolution set to 修正済
Note: See TracTickets for help on using tickets.