Created
June 29, 2017 09:48
-
-
Save motin/2b00295ca71bb876f9873712544dd077 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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