Enhancement(機能追加・改善) #2916
完了op_doctrine.pre_save 等のnotifyイベントで、発生元のモデルオブジェクトを受信側で取得できるようにする
Youichi Kimura さんが12年以上前に追加. 12年以上前に更新.
100%
説明
Overview (概要)¶
lib/util/opDoctrineEventNotifier.class.php
で送出される op_doctrine.pre_save 等のイベントで、現行の実装では sfEvent のパラメータにイベント発生元のオブジェクトが渡されていないため受信側で対象となるオブジェクト (pre_save の場合は永続化されようとしているモデルのインスタンス) を操作することができない。
これを改善するために、notifyイベント送出時に発生元のオブジェクトをパラメータとして渡すように修正する。
Spec (仕様)¶
sfEvent オブジェクト生成時に array('object' => $doctrineEvent->getInvoker())
をパラメータとして渡すように変更する。
Shouta Kashiwagi さんが12年以上前に更新
- ステータス を New(新規) から Pending Review(レビュー待ち) に変更
- 進捗率 を 0 から 50 に変更
更新履歴 08f8be6cc6211177c60a11e849261306e2056321 で適用されました。
Yuya Watanabe さんが12年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Rejected(差し戻し) に変更
差し戻し理由¶
object という名称が適切ではないのではないかと思いました.これが適切なのであればこのままもう一度ステータスをレビュー待ちにしてください.
lib/util/opDoctrineEventNotifier.class.php
28 $dispatcher->notify(new sfEvent(null, sprintf('op_doctrine.%s_%s_%s', $when, $action, get_class($doctrineEvent->getInvoker())), array('object' => $doctrineEvent->getInvoker())));
メモ¶
パラメータとして渡された値を取得するには以下のようにする?
$event->offsetGet('object');
lib/vendor/symfony/lib/event_dispatcher/sfEvent.php
125 /** 126 * Returns a parameter value (implements the ArrayAccess interface). 127 * 128 * @param string $name The parameter name 129 * 130 * @return mixed The parameter value 131 */ 132 public function offsetGet($name) 133 { 134 if (!array_key_exists($name, $this->parameters)) 135 { 136 throw new InvalidArgumentException(sprintf('The event "%s" has no "%s" parameter.', $this->name, $name)); 137 } 138 139 return $this->parameters[$name]; 140 }
Shouta Kashiwagi さんが12年以上前に更新
- ステータス を Rejected(差し戻し) から Pending Review(レビュー待ち) に変更
更新履歴 8dfe7feb83fa26173344dfdf84480286de51498a で適用されました。
Yuya Watanabe さんが12年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更
レビューOKとします.下記に改善内容を示します.
改善内容¶
sfEvent を継承した opDoctrineEvent というDoctrineのレコードを扱うイベントを新たに作成し,これを投げるように変更.
この opDoctrineEvent は変更を行ったモデルのオブジェクトを Subject として保持し,利用できるような仕様となっている,もとものと Doctrine_Event が必要な場合は getDoctrineEvent() メソッドを呼び出すことで利用可能となっている.
Kiwa Sakai さんが12年以上前に更新
- ステータス を Pending Testing(テスト待ち) から Fixed(完了) に変更
- 進捗率 を 70 から 100 に変更
テスト対象外のためこのチケットは閉じます
Youichi Kimura さんが12年以上前に更新
note-4 の指摘について。
まず僕がチケットに記載した仕様はsymfonyのadminモジュールで使われている doctrine.admin.save_object 等の既存のイベントに似せて書いたものです。
パラメータの object
というキーも既存のものに合わせた名前となっています。これについては record
なり適切な名称に変更することは問題ないと思います。
しかし、修正コミット (bfc258b3) に含まれている opDoctrineEvent
を用いた方法は適切ではないと思います。これは、 opDoctrineEvent
というクラスを作成する設計が悪いという意味ではなく、「他のイベントがそうではない」ためです。現状の、パラメータに連想配列を使うスタイルが綺麗でないとして別の方法を使ったとしても、以前のスタイルに慣れ親しんでいる側としては $event->getHogehoge()
という書き方はいささか不自然に感じます。それに、イベントによって $event["hogehoge"]
と $event->getHogehoge()
が混在することは決して良いとは思いません。
要約: 下記の修正で十分ではないでしょうか。
@@ -25,7 +25,7 @@ class opDoctrineEventNotifier extends Doctrine_Record_Listener
}
$dispatcher = sfContext::getInstance()->getEventDispatcher();
- $dispatcher->notify(new sfEvent(null, sprintf('op_doctrine.%s_%s_%s', $when, $action, get_class($doctrineEvent->getInvoker())), array('object' => $doctrineEvent->getInvoke
+ $dispatcher->notify(new sfEvent(null, sprintf('op_doctrine.%s_%s_%s', $when, $action, get_class($doctrineEvent->getInvoker())), array('record' => $doctrineEvent->getInvoke
}
public function preSave(Doctrine_Event $event)
Youichi Kimura さんが12年以上前に更新
- ステータス を Fixed(完了) から Rejected(差し戻し) に変更
- 進捗率 を 100 から 50 に変更
note-9の理由で、一旦ステータスを戻します。
Yuya Watanabe さんが12年以上前に更新
Youichi Kimura は書きました:
note-4 の指摘について。
まず僕がチケットに記載した仕様はsymfonyのadminモジュールで使われている doctrine.admin.save_object 等の既存のイベントに似せて書いたものです。
パラメータのobject
というキーも既存のものに合わせた名前となっています。これについてはrecord
なり適切な名称に変更することは問題ないと思います。しかし、修正コミット (bfc258b3) に含まれている
opDoctrineEvent
を用いた方法は適切ではないと思います。これは、opDoctrineEvent
というクラスを作成する設計が悪いという意味ではなく、「他のイベントがそうではない」ためです。現状の、パラメータに連想配列を使うスタイルが綺麗でないとして別の方法を使ったとしても、以前のスタイルに慣れ親しんでいる側としては$event->getHogehoge()
という書き方はいささか不自然に感じます。それに、イベントによって$event["hogehoge"]
と$event->getHogehoge()
が混在することは決して良いとは思いません。要約: 下記の修正で十分ではないでしょうか。
[...]
以前のスタイルとして連想配列から値を取ってくるという使い方を提供すべきという点については理解しました.これについては note-9 の方法もいいと思います.ただ今回の修正が悪いというわけでもないため,今回の修正に以前のスタイルの値の取得方法を提供するという案でどうでしょうか?
Youichi Kimura さんが12年以上前に更新
note-11は opDoctrineEvent
にArrayAccessによるパラメータの取得とgetterメソッドを両方備える折衷案という解釈でよろしいでしょうか? もしそうであれば僕は問題ないと思います。
Yuya Watanabe さんが12年以上前に更新
note-12 の通りです.懸念点としては getSubject() の値と ArrayAccess で取得された内容に差異が出る可能性があるため, getSubject() をオーバーライドして ArrayAccess で得られる値を返すようにすべきという点でしょうか.
Shouta Kashiwagi さんが12年以上前に更新
修正案
diff --git a/lib/event/opDoctrineEvent.class.php b/lib/event/opDoctrineEvent.class.php index 912c28e..1fc78a9 100644 --- a/lib/event/opDoctrineEvent.class.php +++ b/lib/event/opDoctrineEvent.class.php @@ -21,7 +21,10 @@ class opDoctrineEvent extends sfEvent public function __construct(Doctrine_Event $event, $when, $action, $parameters = array()) { - parent::__construct($event->getInvoker(), sprintf('op_doctrine.%s_%s_%s', $when, $action, get_class($event->getInvoker())), $parameters); + $invoker = $event->getInvoker(); + $parameters['record'] = $invoker; + + parent::__construct($invoker, sprintf('op_doctrine.%s_%s_%s', $when, $action, get_class($invoker)), $parameters); $this->doctrineEvent = $event; } @@ -29,4 +32,9 @@ class opDoctrineEvent extends sfEvent { return $this->doctrineEvent; } + + public function getSubject() + { + return $this['record']; + } }
Shouta Kashiwagi さんが12年以上前に更新
- ステータス を Rejected(差し戻し) から Accepted(着手) に変更
- 進捗率 を 50 から 0 に変更
Yuya Watanabe さんが12年以上前に更新
sfEvent では subject を変更する手段がコンストラクタでのみ提供されていますが, opDoctrineRecord の note-14 の実装だと $parameters の値を変更することで subject を変更で来てしまうというハックができてしまいますが,これは想定されない使い方として扱うものとします.
Shouta Kashiwagi さんが12年以上前に更新
- ステータス を Accepted(着手) から Pending Review(レビュー待ち) に変更
- 進捗率 を 0 から 50 に変更
更新履歴 6807fa548f8167ba08ffe9efa2376e3a666e7e97 で適用されました。
Shouta Kashiwagi さんが12年以上前に更新
static function tetete(opDoctrineEvent $event) { var_dump($event->getSubject()->getId()); var_dump($event['record']->getId()); }
↑のような使い方をすることによって,期待する値を取得することができます.
Yuya Watanabe さんが12年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更
note-9 で指摘された内容も考慮されたものと考えてレビューOKとします.
master¶
6807fa548f8167ba08ffe9efa2376e3a666e7e97
release-3.8beta1¶
Shouta Kashiwagi さんが12年以上前に更新
- ステータス を Pending Testing(テスト待ち) から Fixed(完了) に変更
- 進捗率 を 70 から 100 に変更
テストOKです.
(note-19コードサンプルで検証済み)