Permalink
Browse files

Triggering beforeFind for attachable associations

  • Loading branch information...
1 parent 4fa3bb1 commit 148033fa270580faa707f0eedd98c0b6ccbf0984 @lorenzo lorenzo committed Feb 2, 2014
Showing with 66 additions and 1 deletion.
  1. +19 −0 src/ORM/Association.php
  2. +1 −1 src/ORM/Query.php
  3. +46 −0 tests/TestCase/ORM/Association/BelongsToTest.php
View
@@ -14,6 +14,7 @@
*/
namespace Cake\ORM;
+use Cake\Event\Event;
use Cake\ORM\Entity;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
@@ -408,11 +409,13 @@ public function attachTo(Query $query, array $options = []) {
}
$options['conditions'] = $query->newExpr()->add($options['conditions']);
+ $extraOptions = [];
if (!empty($options['queryBuilder'])) {
$newQuery = $options['queryBuilder']($target->query());
$options['fields'] = $newQuery->clause('select') ?: $options['fields'];
$options['conditions']->add($newQuery->clause('where') ?: []);
+ $extraOptions = $newQuery->getOptions();
}
$joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1];
@@ -428,6 +431,8 @@ public function attachTo(Query $query, array $options = []) {
if (!empty($options['fields'])) {
$query->select($query->aliasFields($options['fields'], $target->alias()));
}
+
+ $this->_dispatchBeforeFind($query, $extraOptions);
}
/**
@@ -472,6 +477,20 @@ public function find($type = 'all', $options = []) {
->where($this->conditions());
}
+/**
+ * Triggers beforeFind on the target table for the query this association is
+ * attaching to
+ *
+ * @param \Cake\ORM\Query $query the query this association is attaching itself to
+ * @param array $options extra options to passed to the association
+ * @return void
+ */
+ protected function _dispatchBeforeFind($query, $options) {
+ $table = $this->target();
+ $event = new Event('Model.beforeFind', $table, [$query, $options, false]);
+ $table->getEventManager()->dispatch($event);
+ }
+
/**
* Returns a single or multiple condition(s) to be appended to the generated join
* clause for getting the results on the target table. If false is returned then
View
@@ -512,7 +512,7 @@ public function getResults() {
}
$table = $this->repository();
- $event = new Event('Model.beforeFind', $table, [$this, $this->_options]);
+ $event = new Event('Model.beforeFind', $table, [$this, $this->_options, true]);
$table->getEventManager()->dispatch($event);
if (isset($this->_results)) {
@@ -328,4 +328,50 @@ public function testPropertyNoPlugin() {
$this->assertEquals('company', $association->property());
}
+/**
+ * Tests that attaching an association to a query will trigger beforeFind
+ * for the target table
+ *
+ * @return void
+ */
+ public function testAttachToBeforeFind() {
+ $query = $this->getMock('\Cake\ORM\Query', ['join', 'select'], [null, null]);
+ $config = [
+ 'foreignKey' => 'company_id',
+ 'sourceTable' => $this->client,
+ 'targetTable' => $this->company
+ ];
+ $listener = $this->getMock('stdClass', ['__invoke']);
+ $this->company->getEventManager()->attach($listener, 'Model.beforeFind');
+ $association = new BelongsTo('Companies', $config);
+ $listener->expects($this->once())->method('__invoke')
+ ->with($this->isInstanceOf('\Cake\Event\Event'), $query, [], false);
+ $association->attachTo($query);
+ }
+
+/**
+ * Tests that attaching an association to a query will trigger beforeFind
+ * for the target table
+ *
+ * @return void
+ */
+ public function testAttachToBeforeFindExtraOptions() {
+ $query = $this->getMock('\Cake\ORM\Query', ['join', 'select'], [null, null]);
+ $config = [
+ 'foreignKey' => 'company_id',
+ 'sourceTable' => $this->client,
+ 'targetTable' => $this->company
+ ];
+ $listener = $this->getMock('stdClass', ['__invoke']);
+ $this->company->getEventManager()->attach($listener, 'Model.beforeFind');
+ $association = new BelongsTo('Companies', $config);
+ $options = ['something' => 'more'];
+ $listener->expects($this->once())->method('__invoke')
+ ->with($this->isInstanceOf('\Cake\Event\Event'), $query, $options, false);
+ $association->attachTo($query, ['queryBuilder' => function($q) {
+ return $q->applyOptions(['something' => 'more']);
+ }]);
+ }
+
+
}

0 comments on commit 148033f

Please sign in to comment.