private function getReferencingResult($table, $viaColumn = null, Filtering $filtering = null, $strategy = self::STRATEGY_IN)
{
$strategy = $this->translateStrategy($strategy);
if ($this->isDetached) {
throw new InvalidStateException('Cannot get referencing Result for detached Result.');
}
if ($viaColumn === null) {
$viaColumn = $this->mapper->getRelationshipColumn($table, $this->table);
}
$key = "{$table}({$viaColumn}){$strategy}";
if (isset($this->referencing[$forcedKey = $key . '#' . self::KEY_FORCED])) {
$ids = $this->extractIds($this->mapper->getPrimaryKey($this->table));
foreach ($this->referencing[$forcedKey] as $filteringResult) {
if ($filteringResult->isValidFor($ids, $filtering->getArgs())) {
return $filteringResult->getResult();
}
}
}
if (isset($this->referencing[$preloadedKey = $key . '#' . self::KEY_PRELOADED])) {
return $this->referencing[$preloadedKey];
}
if ($strategy === self::STRATEGY_IN) {
if ($filtering === null) {
if (!isset($this->referencing[$key])) {
isset($ids) or $ids = $this->extractIds($this->mapper->getPrimaryKey($this->table));
$statement = $this->createTableSelection($table, $ids);
if ($this->isAlias($viaColumn)) {
$statement->where('%n IN %in', $this->trimAlias($viaColumn), $ids);
} else {
$statement->where('%n.%n IN %in', $table, $viaColumn, $ids);
}
$data = $statement->execute()->setRowClass(null)->fetchAll();
$this->referencing[$key] = self::createInstance($data, $table, $this->connection, $this->mapper);
}
} else {
isset($ids) or $ids = $this->extractIds($this->mapper->getPrimaryKey($this->table));
$statement = $this->createTableSelection($table, $ids);
if ($this->isAlias($viaColumn)) {
$statement->where('%n IN %in', $this->trimAlias($viaColumn), $ids);
} else {
$statement->where('%n.%n IN %in', $table, $viaColumn, $ids);
}
$filteringResult = $this->applyFiltering($statement, $filtering);
if ($filteringResult instanceof FilteringResultDecorator) {
if (!isset($this->referencing[$forcedKey])) {
$this->referencing[$forcedKey] = [];
}
$this->referencing[$forcedKey][] = $filteringResult;
return $filteringResult->getResult();
}
$args = $statement->_export();
$key .= '#' . $this->calculateArgumentsHash($args);
if (!isset($this->referencing[$key])) {
$data = $this->connection->query($args)->setRowClass(null)->fetchAll();
$this->referencing[$key] = self::createInstance($data, $table, $this->connection, $this->mapper);
}
}
return $this->referencing[$key];
}
// $strategy === self::STRATEGY_UNION
if ($filtering === null) {
if (!isset($this->referencing[$key])) {
isset($ids) or $ids = $this->extractIds($this->mapper->getPrimaryKey($this->table));
if (count($ids) === 0) {
$data = [];
} else {
$data = $this->connection->query($this->buildUnionStrategySql($ids, $table, $viaColumn))->setRowClass(null)->fetchAll();
}
$this->referencing[$key] = self::createInstance($data, $table, $this->connection, $this->mapper);
}
} else {
isset($ids) or $ids = $this->extractIds($this->mapper->getPrimaryKey($this->table));
if (count($ids) === 0) {
$this->referencing[$key] = self::createInstance([], $table, $this->connection, $this->mapper);
} else {
$firstStatement = $this->createTableSelection($table, [reset($ids)]);
if ($this->isAlias($viaColumn)) {
$firstStatement->where('%n = ?', $this->trimAlias($viaColumn), reset($ids));
} else {
$firstStatement->where('%n.%n = ?', $table, $viaColumn, reset($ids));
}
$filteringResult = $this->applyFiltering($firstStatement, $filtering);
if ($filteringResult instanceof FilteringResultDecorator) {
if (!isset($this->referencing[$forcedKey])) {
$this->referencing[$forcedKey] = [];
}
$this->referencing[$forcedKey][] = $filteringResult;
return $filteringResult->getResult();
}
$args = $firstStatement->_export();
$key .= '#' . $this->calculateArgumentsHash($args);
if (!isset($this->referencing[$key])) {
$sql = $this->buildUnionStrategySql($ids, $table, $viaColumn, $filtering);
$data = $this->connection->query($sql)->setRowClass(null)->fetchAll();
$result = self::createInstance($data, $table, $this->connection, $this->mapper);
$this->referencing[$key] = $result;
}
}
}
return $this->referencing[$key];
}