/**
  * Creates a left join list for translations
  * on used query components
  *
  * @todo: make it cleaner
  * @return string
  */
 private function prepareTranslatedComponents()
 {
     $q = $this->getQuery();
     $locale = $q->getHint(TranslatableListener::HINT_TRANSLATABLE_LOCALE);
     if (!$locale) {
         // use from listener
         $locale = $this->listener->getListenerLocale();
     }
     $defaultLocale = $this->listener->getDefaultLocale();
     if ($locale === $defaultLocale && !$this->listener->getPersistDefaultLocaleTranslation()) {
         // Skip preparation as there's no need to translate anything
         return;
     }
     $em = $this->getEntityManager();
     $ea = new TranslatableEventAdapter();
     $ea->setEntityManager($em);
     $joinStrategy = $q->getHint(TranslatableListener::HINT_INNER_JOIN) ? 'INNER' : 'LEFT';
     foreach ($this->translatedComponents as $dqlAlias => $comp) {
         $meta = $comp['metadata'];
         $config = $this->listener->getConfiguration($em, $meta->name);
         $transClass = $this->listener->getTranslationClass($ea, $meta->name);
         $transMeta = $em->getClassMetadata($transClass);
         $transTable = $transMeta->getQuotedTableName($this->platform);
         foreach ($config['fields'] as $field) {
             $compTblAlias = $this->walkIdentificationVariable($dqlAlias, $field);
             $tblAlias = $this->getSQLTableAlias('trans' . $compTblAlias . $field);
             $sql = " {$joinStrategy} JOIN " . $transTable . ' ' . $tblAlias;
             $sql .= ' ON ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('locale', $this->platform) . ' = ' . $this->conn->quote($locale);
             $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('field', $this->platform) . ' = ' . $this->conn->quote($field);
             $identifier = $meta->getSingleIdentifierFieldName();
             $idColName = $meta->getQuotedColumnName($identifier, $this->platform);
             if ($ea->usesPersonalTranslation($transClass)) {
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getSingleAssociationJoinColumnName('object') . ' = ' . $compTblAlias . '.' . $idColName;
             } else {
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('objectClass', $this->platform) . ' = ' . $this->conn->quote($meta->name);
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('foreignKey', $this->platform) . ' = ' . $compTblAlias . '.' . $idColName;
             }
             isset($this->components[$dqlAlias]) ? $this->components[$dqlAlias] .= $sql : ($this->components[$dqlAlias] = $sql);
             $originalField = $compTblAlias . '.' . $meta->getQuotedColumnName($field, $this->platform);
             $substituteField = $tblAlias . '.' . $transMeta->getQuotedColumnName('content', $this->platform);
             // If original field is integer - treat translation as integer (for ORDER BY, WHERE, etc)
             $fieldMapping = $meta->getFieldMapping($field);
             if (in_array($fieldMapping["type"], array("integer", "bigint", "tinyint", "int"))) {
                 $substituteField = 'CAST(' . $substituteField . ' AS SIGNED)';
             }
             // Fallback to original if was asked for
             if ($this->needsFallback() && (!isset($config['fallback'][$field]) || $config['fallback'][$field]) || !$this->needsFallback() && isset($config['fallback'][$field]) && $config['fallback'][$field]) {
                 $substituteField = 'COALESCE(' . $substituteField . ', ' . $originalField . ')';
             }
             $this->replacements[$originalField] = $substituteField;
         }
     }
 }
Example #2
0
 /**
  * {@inheritDoc}
  */
 public function setTranslationValue($object, $field, $value)
 {
     return $this->ea->setTranslationValue($object, $field, $value);
 }
 /**
  * Creates a left join list for translations
  * on used query components
  *
  * @todo: make it cleaner
  * @return string
  */
 private function prepareTranslatedComponents()
 {
     $q = $this->getQuery();
     $locale = $q->getHint(TranslatableListener::HINT_TRANSLATABLE_LOCALE);
     if (!$locale) {
         // use from listener
         $locale = $this->listener->getListenerLocale();
     }
     $defaultLocale = $this->listener->getDefaultLocale();
     if ($locale === $defaultLocale && !$this->listener->getPersistDefaultLocaleTranslation()) {
         // Skip preparation as there's no need to translate anything
         return;
     }
     $em = $this->getEntityManager();
     $ea = new TranslatableEventAdapter();
     $ea->setEntityManager($em);
     $joinStrategy = $q->getHint(TranslatableListener::HINT_INNER_JOIN) ? 'INNER' : 'LEFT';
     foreach ($this->translatedComponents as $dqlAlias => $comp) {
         $meta = $comp['metadata'];
         $config = $this->listener->getConfiguration($em, $meta->name);
         $transClass = $this->listener->getTranslationClass($ea, $meta->name);
         $transMeta = $em->getClassMetadata($transClass);
         $transTable = $em->getConfiguration()->getQuoteStrategy()->getTableName($transMeta, $this->platform);
         foreach ($config['fields'] as $field) {
             $compTblAlias = $this->walkIdentificationVariable($dqlAlias, $field);
             $tblAlias = $this->getSQLTableAlias('trans' . $compTblAlias . $field);
             $sql = " {$joinStrategy} JOIN " . $transTable . ' ' . $tblAlias;
             $sql .= ' ON ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('locale', $this->platform) . ' = ' . $this->conn->quote($locale);
             $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('field', $this->platform) . ' = ' . $this->conn->quote($field);
             $identifier = $meta->getSingleIdentifierFieldName();
             $idColName = $meta->getQuotedColumnName($identifier, $this->platform);
             if ($ea->usesPersonalTranslation($transClass)) {
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getSingleAssociationJoinColumnName('object') . ' = ' . $compTblAlias . '.' . $idColName;
             } else {
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('objectClass', $this->platform) . ' = ' . $this->conn->quote($config['useObjectClass']);
                 $mappingFK = $transMeta->getFieldMapping('foreignKey');
                 $mappingPK = $meta->getFieldMapping($identifier);
                 $fkColName = $this->getCastedForeignKey($compTblAlias . '.' . $idColName, $mappingFK['type'], $mappingPK['type']);
                 $sql .= ' AND ' . $tblAlias . '.' . $transMeta->getQuotedColumnName('foreignKey', $this->platform) . ' = ' . $fkColName;
             }
             isset($this->components[$dqlAlias]) ? $this->components[$dqlAlias] .= $sql : ($this->components[$dqlAlias] = $sql);
             $originalField = $compTblAlias . '.' . $meta->getQuotedColumnName($field, $this->platform);
             $substituteField = $tblAlias . '.' . $transMeta->getQuotedColumnName('content', $this->platform);
             // Treat translation as original field type
             $fieldMapping = $meta->getFieldMapping($field);
             if ($this->platform instanceof MySqlPlatform && in_array($fieldMapping["type"], array("decimal")) || !$this->platform instanceof MySqlPlatform && !in_array($fieldMapping["type"], array("datetime", "datetimetz", "date", "time"))) {
                 $type = Type::getType($fieldMapping["type"]);
                 $castType = $type->getSQLDeclaration($fieldMapping, $this->platform);
                 if ($this->platform instanceof \Doctrine\DBAL\Platforms\MySqlPlatform && in_array($fieldMapping["type"], array("decimal"))) {
                     $castType = preg_replace("/NUMERIC/", "DECIMAL", $castType);
                 }
                 $substituteField = 'CAST(' . $substituteField . ' AS ' . $castType . ')';
             }
             // Fallback to original if was asked for
             if ($this->needsFallback() && (!isset($config['fallback'][$field]) || $config['fallback'][$field]) || !$this->needsFallback() && isset($config['fallback'][$field]) && $config['fallback'][$field]) {
                 $substituteField = 'COALESCE(' . $substituteField . ', ' . $originalField . ')';
             }
             $this->replacements[$originalField] = $substituteField;
         }
     }
 }