public function attachTo(Query $query, array $options = [])
{
if (!empty($options['negateMatch'])) {
$this->_appendNotMatching($query, $options);
return;
}
$junction = $this->junction();
$belongsTo = $junction->association($this->source()->alias());
$cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->foreignKey()]);
$cond += $this->junctionConditions();
if (isset($options['includeFields'])) {
$includeFields = $options['includeFields'];
}
// Attach the junction table as well we need it to populate _joinData.
$assoc = $this->_targetTable->association($junction->alias());
$newOptions = array_intersect_key($options, ['joinType' => 1, 'fields' => 1]);
$newOptions += ['conditions' => $cond, 'includeFields' => $includeFields, 'foreignKey' => false];
$assoc->attachTo($query, $newOptions);
$query->eagerLoader()->addToJoinsMap($junction->alias(), $assoc, true);
parent::attachTo($query, $options);
$foreignKey = $this->targetForeignKey();
$thisJoin = $query->clause('join')[$this->name()];
$thisJoin['conditions']->add($assoc->_joinCondition(['foreignKey' => $foreignKey]));
}
/** * 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 = ['sourceTable' => $this->article, 'targetTable' => $this->tag]; $table = TableRegistry::get('ArticlesTags'); $association = new BelongsToMany('Tags', $config); $listener = $this->getMock('stdClass', ['__invoke']); $this->tag->getEventManager()->attach($listener, 'Model.beforeFind'); $opts = ['something' => 'more']; $listener->expects($this->once())->method('__invoke')->with($this->isInstanceOf('\\Cake\\Event\\Event'), $this->isInstanceOf('\\Cake\\ORM\\Query'), $opts, false); $listener2 = $this->getMock('stdClass', ['__invoke']); $table->getEventManager()->attach($listener2, 'Model.beforeFind'); $listener2->expects($this->once())->method('__invoke')->with($this->isInstanceOf('\\Cake\\Event\\Event'), $this->isInstanceOf('\\Cake\\ORM\\Query'), [], false); $association->attachTo($query, ['queryBuilder' => function ($q) { return $q->applyOptions(['something' => 'more']); }]); }