|
@@ -9,6 +9,8 @@ use Doctrine\ORM\Query\SqlWalker;
|
|
|
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
|
|
use Doctrine\ORM\Query\AST\SelectStatement;
|
|
|
use Doctrine\ORM\Query\Exec\SingleSelectExecutor;
|
|
|
+use Doctrine\ORM\Query\AST\RangeVariableDeclaration;
|
|
|
+use Doctrine\ORM\Query\AST\Join;
|
|
|
|
|
|
/**
|
|
|
* The translation sql output walker makes it possible
|
|
@@ -91,19 +93,11 @@ class TranslationWalker extends SqlWalker
|
|
|
private $replacements = array();
|
|
|
|
|
|
/**
|
|
|
- * Translation joins on current query
|
|
|
- * components
|
|
|
+ * List of joins for translated components in query
|
|
|
*
|
|
|
* @var array
|
|
|
*/
|
|
|
- private $translationJoinSql = array();
|
|
|
-
|
|
|
- /**
|
|
|
- * Processed subselect number
|
|
|
- *
|
|
|
- * @var integer
|
|
|
- */
|
|
|
- private $processedNestingLevel = 0;
|
|
|
+ private $components = array();
|
|
|
|
|
|
/**
|
|
|
* {@inheritDoc}
|
|
@@ -125,7 +119,7 @@ class TranslationWalker extends SqlWalker
|
|
|
if (!$AST instanceof SelectStatement) {
|
|
|
throw new \Gedmo\Exception\UnexpectedValueException('Translation walker should be used only on select statement');
|
|
|
}
|
|
|
- $this->translationJoinSql = $this->getTranslationJoinsSql();
|
|
|
+ $this->prepareTranslatedComponents();
|
|
|
return new SingleSelectExecutor($AST, $this);
|
|
|
}
|
|
|
|
|
@@ -176,9 +170,7 @@ class TranslationWalker extends SqlWalker
|
|
|
public function walkFromClause($fromClause)
|
|
|
{
|
|
|
$result = parent::walkFromClause($fromClause);
|
|
|
- if (count($this->translationJoinSql)) {
|
|
|
- $result .= $this->translationJoinSql[0];
|
|
|
- }
|
|
|
+ $result .= $this->joinTranslations($fromClause);
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
@@ -214,7 +206,6 @@ class TranslationWalker extends SqlWalker
|
|
|
*/
|
|
|
public function walkSubselect($subselect)
|
|
|
{
|
|
|
- $this->processedNestingLevel++;
|
|
|
$result = parent::walkSubselect($subselect);
|
|
|
return $result;
|
|
|
}
|
|
@@ -225,9 +216,7 @@ class TranslationWalker extends SqlWalker
|
|
|
public function walkSubselectFromClause($subselectFromClause)
|
|
|
{
|
|
|
$result = parent::walkSubselectFromClause($subselectFromClause);
|
|
|
- if (isset($this->translationJoinSql[$this->processedNestingLevel])) {
|
|
|
- $result .= $this->translationJoinSql[$this->processedNestingLevel];
|
|
|
- }
|
|
|
+ $result .= $this->joinTranslations($subselectFromClause);
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
@@ -240,6 +229,33 @@ class TranslationWalker extends SqlWalker
|
|
|
return $this->replace($this->replacements, $result);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Walks from clause, and creates translation joins
|
|
|
+ * for the translated components
|
|
|
+ *
|
|
|
+ * @param Doctrine\ORM\Query\AST\FromClause $from
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function joinTranslations($from)
|
|
|
+ {
|
|
|
+ $result = '';
|
|
|
+ foreach ($from->identificationVariableDeclarations as $decl) {
|
|
|
+ if ($decl->rangeVariableDeclaration instanceof RangeVariableDeclaration) {
|
|
|
+ if (isset($this->components[$decl->rangeVariableDeclaration->aliasIdentificationVariable])) {
|
|
|
+ $result .= $this->components[$decl->rangeVariableDeclaration->aliasIdentificationVariable];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach ($decl->joinVariableDeclarations as $joinDecl) {
|
|
|
+ if ($joinDecl->join instanceof Join) {
|
|
|
+ if (isset($this->components[$joinDecl->join->aliasIdentificationVariable])) {
|
|
|
+ $result .= $this->components[$joinDecl->join->aliasIdentificationVariable];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Creates a left join list for translations
|
|
|
* on used query components
|
|
@@ -247,18 +263,14 @@ class TranslationWalker extends SqlWalker
|
|
|
* @todo: make it cleaner
|
|
|
* @return string
|
|
|
*/
|
|
|
- private function getTranslationJoinsSql()
|
|
|
+ private function prepareTranslatedComponents()
|
|
|
{
|
|
|
- $result = array();
|
|
|
$em = $this->getEntityManager();
|
|
|
$ea = new TranslatableEventAdapter;
|
|
|
$locale = $this->listener->getListenerLocale();
|
|
|
$defaultLocale = $this->listener->getDefaultLocale();
|
|
|
|
|
|
foreach ($this->translatedComponents as $dqlAlias => $comp) {
|
|
|
- if (!isset($result[$comp['nestingLevel']])) {
|
|
|
- $result[$comp['nestingLevel']] = '';
|
|
|
- }
|
|
|
$meta = $comp['metadata'];
|
|
|
$config = $this->listener->getConfiguration($em, $meta->name);
|
|
|
$transClass = $this->listener->getTranslationClass($ea, $meta->name);
|
|
@@ -280,7 +292,7 @@ class TranslationWalker extends SqlWalker
|
|
|
$colName = $meta->getQuotedColumnName($identifier, $this->platform);
|
|
|
$sql .= ' AND '.$tblAlias.'.'.$transMeta->getQuotedColumnName('foreignKey', $this->platform)
|
|
|
.' = '.$compTblAlias.'.'.$colName;
|
|
|
- $result[$comp['nestingLevel']] .= $sql;
|
|
|
+ isset($this->components[$dqlAlias]) ? $this->components[$dqlAlias] .= $sql : $this->components[$dqlAlias] = $sql;
|
|
|
if ($this->needsFallback()) {
|
|
|
// COALESCE with the original record columns
|
|
|
$this->replacements[$compTblAlias.'.'.$meta->getQuotedColumnName($field, $this->platform)]
|
|
@@ -295,7 +307,6 @@ class TranslationWalker extends SqlWalker
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return $result;
|
|
|
}
|
|
|
|
|
|
/**
|