public function replaceLinks(EntityInterface $sourceEntity, array $targetEntities, array $options = [])
{
$bindingKey = (array) $this->bindingKey();
$primaryValue = $sourceEntity->extract($bindingKey);
if (count(array_filter($primaryValue, 'strlen')) !== count($bindingKey)) {
$message = 'Could not find primary key value for source entity';
throw new InvalidArgumentException($message);
}
return $this->junction()->connection()->transactional(function () use($sourceEntity, $targetEntities, $primaryValue, $options) {
$foreignKey = array_map([$this->_junctionTable, 'aliasField'], (array) $this->foreignKey());
$hasMany = $this->source()->association($this->_junctionTable->alias());
$existing = $hasMany->find('all')->where(array_combine($foreignKey, $primaryValue));
$associationConditions = $this->conditions();
if ($associationConditions) {
$existing->contain($this->target()->alias());
$existing->andWhere($associationConditions);
}
$jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
$inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities, $options);
if ($inserts && !$this->_saveTarget($sourceEntity, $inserts, $options)) {
return false;
}
$property = $this->property();
if (count($inserts)) {
$inserted = array_combine(array_keys($inserts), (array) $sourceEntity->get($property));
$targetEntities = $inserted + $targetEntities;
}
ksort($targetEntities);
$sourceEntity->set($property, array_values($targetEntities));
$sourceEntity->dirty($property, false);
return true;
});
}