Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motin/2b00295ca71bb876f9873712544dd077 to your computer and use it in GitHub Desktop.
Save motin/2b00295ca71bb876f9873712544dd077 to your computer and use it in GitHub Desktop.
<?php
/**
* Helper trait to throw an exception instead of getting affected by Propel's automagic cross-join-"fixing" of a query.
* Most often, the cross join is an unwanted consequence of a typo or incorrect usage of the query methods related to relation aliases.
*
* Use this trait in the *Query classes and manually execute the following method on query objects wherever automatic cross joins are unwanted:
*
* $query->throwExceptionIfPropelCrossJoinQueryFixWillBeTriggered();
*
* Trait PropelModelPreventCrossJoinQueryFixTrait
*/
trait PropelModelPreventCrossJoinQueryFixTrait
{
/**
* Replicates the parts from vendor/propel/propel/src/Propel/Runtime/ActiveQuery/Criteria.php
* that determines whether or not Propel will "fix" the query by inserting a CROSS JOIN and
* throws an exception if such is the case
* @throws Exception
*/
public function throwExceptionIfPropelCrossJoinQueryFixWillBeTriggered()
{
/** @var \Propel\Runtime\ActiveQuery\Criteria $this */
$fromClause = [];
$joinTables = [];
foreach ($this->keys() as $key) {
$criterion = $this->getCriterion($key);
$table = null;
foreach ($criterion->getAttachedCriterion() as $attachedCriterion) {
$tableName = $attachedCriterion->getTable();
$table = $this->getTableForAlias($tableName);
if ($table !== null) {
$fromClause[] = $table . ' ' . $tableName;
} else {
$fromClause[] = $tableName;
}
}
}
// Handle joins
// joins with a null join type will be added to the FROM clause and the condition added to the WHERE clause.
// joins of a specified type: the LEFT side will be added to the fromClause and the RIGHT to the joinClause
foreach ($this->getJoins() as $join) {
// add 'em to the queues..
if (!$fromClause) {
$fromClause[] = $join->getLeftTableWithAlias();
}
$joinTables[] = $join->getRightTableWithAlias();
}
// tables should not exist in both the from and join clauses
if ($joinTables && $fromClause) {
foreach ($fromClause as $fi => $ftable) {
if (in_array($ftable, $joinTables)) {
unset($fromClause[$fi]);
}
}
}
if (!empty($joinTables) && count($fromClause) > 1) {
throw new \Exception(
'Propel CROSS JOIN automagic fix will be triggered for this query - check your joins logic making sure that relation aliases are setup properly'
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment