Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Triggering beforeFind for attachable associations
  • Loading branch information
lorenzo committed Feb 9, 2014
1 parent 4fa3bb1 commit 148033f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
19 changes: 19 additions & 0 deletions src/ORM/Association.php
Expand Up @@ -14,6 +14,7 @@
*/
namespace Cake\ORM;

use Cake\Event\Event;
use Cake\ORM\Entity;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
Expand Down Expand Up @@ -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];
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ORM/Query.php
Expand Up @@ -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)) {
Expand Down
46 changes: 46 additions & 0 deletions tests/TestCase/ORM/Association/BelongsToTest.php
Expand Up @@ -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.