Skip to content
Permalink
Browse files

Triggering beforeFind for attachable associations

  • Loading branch information...
lorenzo committed Feb 2, 2014
1 parent 4fa3bb1 commit 148033fa270580faa707f0eedd98c0b6ccbf0984
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
@@ -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
@@ -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.
You can’t perform that action at this time.