Guest User

exbtase 6.2 patched typo3dbbackend

a guest
Feb 10th, 2014
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.13 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Vendor\Extension\Persistence\Generic\Storage;
  4.  
  5. /**
  6.  * @author Philipp Wrann <[email protected]>
  7.  * @package TYPO3.CMS
  8.  */
  9. class PatchedTypo3DbBackend extends \TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend {
  10.  
  11.     /**
  12.      * Here we added the possibility of makeing joins on the same table,
  13.      * This is important to filter regionalobjects for their location
  14.      * as locations as well as regionalobjects are stored in the same table.
  15.      *
  16.      * @param string &$className
  17.      * @param string &$tableName
  18.      * @param array &$propertyPath
  19.      * @param array &$sql
  20.      * @param string &$parent
  21.      * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception
  22.      * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidRelationConfigurationException
  23.      * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\MissingColumnMapException
  24.      */
  25.     protected function addUnionStatement(&$className, &$tableName, &$propertyPath, array &$sql, &$parent) {
  26.        
  27.         $explodedPropertyPath = explode('.', $propertyPath, 2);
  28.         $propertyName = $explodedPropertyPath[0];
  29.         $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
  30.         $tableName = $this->dataMapper->convertClassNameToTableName($className);
  31.         $columnMap = $this->dataMapper->getDataMap($className)->getColumnMap($propertyName);
  32.  
  33.         if ($columnMap === NULL) {
  34.             throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\MissingColumnMapException('The ColumnMap for property "' . $propertyName . '" of class "' . $className . '" is missing.', 1355142232);
  35.         }
  36.  
  37.         // MODIFICATION START
  38.         $parentKeyFieldName = $columnMap->getParentKeyFieldName();
  39.         $childTableName = $columnMap->getChildTableName();
  40.         $realTableName = $childTableName;
  41.         $alias = (isset($sql['unions'][$propertyName])) ? $propertyName.uniqid() : $propertyName;
  42.         $parent = ($parent=='') ? $tableName : $parent;
  43.  
  44.         if ($childTableName === NULL) {
  45.             throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidRelationConfigurationException('The relation information for property "' . $propertyName . '" of class "' . $className . '" is missing.', 1353170925);
  46.         }
  47.        
  48.         if ($columnMap->getTypeOfRelation() === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_ONE) {
  49.             if (isset($parentKeyFieldName)) {
  50.                 $sql['unions'][$alias] = 'LEFT JOIN ' . $realTableName . ' AS ' . $alias . ' ON ' . $parent . '.uid=' . $alias . '.' . $parentKeyFieldName;
  51.             } else {
  52.                 $sql['unions'][$alias] = 'LEFT JOIN ' . $realTableName . ' AS '. $alias . ' ON ' . $parent . '.' . $columnName . '=' . $alias . '.uid';
  53.             }
  54.             $className = $this->dataMapper->getType($className, $propertyName);
  55.         } elseif ($columnMap->getTypeOfRelation() === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_MANY) {
  56.             if (isset($parentKeyFieldName)) {
  57.                 $sql['unions'][$alias] = 'LEFT JOIN ' . $realTableName . ' AS ' . $alias . ' ON ' . $parent . '.uid=' . $alias . '.' . $parentKeyFieldName;
  58.             } else {
  59.                 // @todo !!!needs tesing!!!
  60.                 $onStatement = '(FIND_IN_SET(' . $childTableName . '.uid, ' . $tableName . '.' . $columnName . '))';
  61.                 $sql['unions'][$alias] = 'LEFT JOIN ' . $childTableName . ' ON ' . $onStatement;
  62.             }
  63.             $className = $this->dataMapper->getType($className, $propertyName);
  64.         } elseif ($columnMap->getTypeOfRelation() === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
  65.             $relationTableName = $columnMap->getRelationTableName();
  66.             // @todo !!!needs tesing!!!
  67.             $sql['unions'][$relationTableName] = 'LEFT JOIN ' . $relationTableName . ' ON ' . $parent . '.uid=' . $relationTableName . '.' . $columnMap->getParentKeyFieldName();
  68.             $sql['unions'][$alias] = 'LEFT JOIN ' . $childTableName . ' ON ' . $relationTableName . '.' . $columnMap->getChildKeyFieldName() . '=' . $childTableName . '.uid';
  69.             $className = $this->dataMapper->getType($className, $propertyName);
  70.         } else {
  71.             throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('Could not determine type of relation.', 1252502725);
  72.         }
  73.        
  74.         $parent = $alias;
  75.         $sql['keywords']['distinct'] = 'DISTINCT';
  76.         $propertyPath = $explodedPropertyPath[1];
  77.         $tableName = $alias;
  78.     }
  79.  
  80.     /**
  81.      * Parse a DynamicOperand into SQL and parameter arrays.
  82.      *
  83.      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\DynamicOperandInterface $operand
  84.      * @param string $operator One of the JCR_OPERATOR_* constants
  85.      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source The source
  86.      * @param array &$sql The query parts
  87.      * @param array &$parameters The parameters that will replace the markers
  88.      * @param string $valueFunction an optional SQL function to apply to the operand value
  89.      * @param null $operand2
  90.      * @return void
  91.      */
  92.     protected function parseDynamicOperand(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\DynamicOperandInterface $operand, $operator, \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source, array &$sql, array &$parameters, $valueFunction = NULL, $operand2 = NULL) {
  93.         if ($operand instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\LowerCaseInterface) {
  94.             $this->parseDynamicOperand($operand->getOperand(), $operator, $source, $sql, $parameters, 'LOWER');
  95.         } elseif ($operand instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\UpperCaseInterface) {
  96.             $this->parseDynamicOperand($operand->getOperand(), $operator, $source, $sql, $parameters, 'UPPER');
  97.         } elseif ($operand instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\PropertyValueInterface) {
  98.             $propertyName = $operand->getPropertyName();
  99.             if ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
  100.                 // FIXME Only necessary to differ from  Join
  101.                 $className = $source->getNodeTypeName();
  102.                 $tableName = $this->dataMapper->convertClassNameToTableName($className);
  103.                 $parent = '';
  104.                 while (strpos($propertyName, '.') !== FALSE) {
  105.                     $this->addUnionStatement($className, $tableName, $propertyName, $sql, $parent);
  106.                 }
  107.             } elseif ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface) {
  108.                 $tableName = $source->getJoinCondition()->getSelector1Name();
  109.             }
  110.             $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
  111.             $operator = $this->resolveOperator($operator);
  112.             $constraintSQL = '';
  113.             if ($valueFunction === NULL) {
  114.                 $constraintSQL .= (!empty($tableName) ? $tableName . '.' : '') . $columnName . ' ' . $operator . ' ?';
  115.             } else {
  116.                 $constraintSQL .= $valueFunction . '(' . (!empty($tableName) ? $tableName . '.' : '') . $columnName . ') ' . $operator . ' ?';
  117.             }
  118.             $sql['where'][] = $constraintSQL;
  119.         }
  120.     }
  121.  
  122.     /**
  123.      * Parse a Comparison into SQL and parameter arrays.
  124.      *
  125.      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface $comparison The comparison to parse
  126.      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source The source
  127.      * @param array &$sql SQL query parts to add to
  128.      * @param array &$parameters Parameters to bind to the SQL
  129.      * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException
  130.      * @return void
  131.      */
  132.     protected function parseComparison(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface $comparison, \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source, array &$sql, array &$parameters) {
  133.         $operand1 = $comparison->getOperand1();
  134.         $operator = $comparison->getOperator();
  135.         $operand2 = $comparison->getOperand2();
  136.         if ($operator === \TYPO3\CMS\Extbase\Persistence\QueryInterface::OPERATOR_IN) {
  137.             $items = array();
  138.             $hasValue = FALSE;
  139.             foreach ($operand2 as $value) {
  140.                 $value = $this->getPlainValue($value);
  141.                 if ($value !== NULL) {
  142.                     $items[] = $value;
  143.                     $hasValue = TRUE;
  144.                 }
  145.             }
  146.             if ($hasValue === FALSE) {
  147.                 $sql['where'][] = '1<>1';
  148.             } else {
  149.                 $this->parseDynamicOperand($operand1, $operator, $source, $sql, $parameters, NULL, $operand2);
  150.                 $parameters[] = $items;
  151.             }
  152.         } elseif ($operator === \TYPO3\CMS\Extbase\Persistence\QueryInterface::OPERATOR_CONTAINS) {
  153.             if ($operand2 === NULL) {
  154.                 $sql['where'][] = '1<>1';
  155.             } else {
  156.                 $className = $source->getNodeTypeName();
  157.                 $tableName = $this->dataMapper->convertClassNameToTableName($className);
  158.                 $propertyName = $operand1->getPropertyName();
  159.                 $parent = '';
  160.                 while (strpos($propertyName, '.') !== FALSE) {
  161.                     $this->addUnionStatement($className, $tableName, $propertyName, $sql, $parent);
  162.                 }
  163.                 $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
  164.                 $dataMap = $this->dataMapper->getDataMap($className);
  165.                 $columnMap = $dataMap->getColumnMap($propertyName);
  166.                 $typeOfRelation = $columnMap instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap ? $columnMap->getTypeOfRelation() : NULL;
  167.                 if ($typeOfRelation === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
  168. //                  $relationTableName = $columnMap->getRelationTableName();
  169. //                  $sql['where'][] = $tableName . '.uid IN (SELECT ' . $columnMap->getParentKeyFieldName() . ' FROM ' . $relationTableName . ' WHERE ' . $columnMap->getChildKeyFieldName() . '=?)';
  170.                     // MODIFICATION START
  171.                     $relationTableName = $columnMap->getRelationTableName();
  172.                     if($matchFields = $columnMap->getRelationTableMatchFields()) {
  173.                         $matchFieldsQuery = '';
  174.                         foreach ($matchFields as $matchField => $matchValue) {
  175.                             $matchFieldsQuery .= ' '.$matchField.' = \''.$matchValue.'\' AND ';
  176.                         }
  177.                     }
  178.                     $sql['where'][] = $tableName . '.uid IN (SELECT ' . $columnMap->getParentKeyFieldName() . ' FROM ' . $relationTableName . ' WHERE ' . $matchFieldsQuery . $columnMap->getChildKeyFieldName() . '=?)';
  179.                     $parameters[] = intval($this->getPlainValue($operand2));
  180.                     // MODIFICATION END
  181.                 } elseif ($typeOfRelation === \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_MANY) {
  182.                     $parentKeyFieldName = $columnMap->getParentKeyFieldName();
  183.                     if (isset($parentKeyFieldName)) {
  184.                         $childTableName = $columnMap->getChildTableName();
  185.                         $sql['where'][] = $tableName . '.uid=(SELECT ' . $childTableName . '.' . $parentKeyFieldName . ' FROM ' . $childTableName . ' WHERE ' . $childTableName . '.uid=?)';
  186.                         $parameters[] = intval($this->getPlainValue($operand2));
  187.                     } else {
  188.                         $sql['where'][] = 'FIND_IN_SET(?,' . $tableName . '.' . $columnName . ')';
  189.                         $parameters[] = intval($this->getPlainValue($operand2));
  190.                     }
  191.                 } else {
  192.                     throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745);
  193.                 }
  194.             }
  195.         } else {
  196.             if ($operand2 === NULL) {
  197.                 if ($operator === \TYPO3\CMS\Extbase\Persistence\QueryInterface::OPERATOR_EQUAL_TO) {
  198.                     $operator = self::OPERATOR_EQUAL_TO_NULL;
  199.                 } elseif ($operator === \TYPO3\CMS\Extbase\Persistence\QueryInterface::OPERATOR_NOT_EQUAL_TO) {
  200.                     $operator = self::OPERATOR_NOT_EQUAL_TO_NULL;
  201.                 }
  202.             }
  203.             $this->parseDynamicOperand($operand1, $operator, $source, $sql, $parameters);
  204.             $parameters[] = $this->getPlainValue($operand2);
  205.         }
  206.     }
  207.  
  208.     /**
  209.      * Transforms orderings into SQL.
  210.      *
  211.      * @param array $orderings An array of orderings (Tx_Extbase_Persistence_QOM_Ordering)
  212.      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source The source
  213.      * @param array &$sql The query parts
  214.      * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException
  215.      * @return void
  216.      */
  217.     protected function parseOrderings(array $orderings, \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source, array &$sql) {
  218.         foreach ($orderings as $propertyName => $order) {
  219.             switch ($order) {
  220.                 case \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING:
  221.  
  222.                 case \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING:
  223.                     $order = 'ASC';
  224.                     break;
  225.                 case \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING:
  226.  
  227.                 case \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING:
  228.                     $order = 'DESC';
  229.                     break;
  230.                 default:
  231.                     throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException('Unsupported order encountered.', 1242816074);
  232.             }
  233.             $className = '';
  234.             $tableName = '';
  235.            
  236.             /**
  237.              * MODIFICATION START
  238.              * This way we enable the use of a function inside ordering
  239.              * this is mysql specific but its needed for our listMode Priority feature
  240.              * This way we can get a ordered list but put some specific objects on top of the list
  241.              */
  242.             if (stripos($propertyName,'FIELD(') !== FALSE) {
  243.                 $parts = explode(',',str_replace(')','',$propertyName));
  244.                 $property = str_ireplace('FIELD(','',array_shift($parts));
  245.                 $values = array_filter(array_filter($parts,function($value){
  246.                     return !preg_match_all("/[^\w]/",$value);
  247.                 }));
  248.                 $className = $source->getNodeTypeName();
  249.                 $tableName = $this->dataMapper->convertClassNameToTableName($className);
  250.                 $columnName = $this->dataMapper->convertPropertyNameToColumnName($property, $className);
  251.                 $fieldString = 'FIELD('.$tableName.'.'.$columnName.','.implode(',',$values).')';
  252.                 $sql['orderings'][] = $fieldString. ' ' . $order;
  253.             } else {
  254.                 /**
  255.                  * MODIFICATION END
  256.                  */
  257.                 if ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
  258.                     $className = $source->getNodeTypeName();
  259.                     $tableName = $this->dataMapper->convertClassNameToTableName($className);
  260.                     $parent = '';
  261.                     while (strpos($propertyName, '.') !== FALSE) {
  262.                         $this->addUnionStatement($className, $tableName, $propertyName, $sql, $parent);
  263.                     }
  264.                 } elseif ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface) {
  265.                     $tableName = $source->getLeft()->getSelectorName();
  266.                 }
  267.                 $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className);
  268.                 if (strlen($tableName) > 0) {
  269.                     $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order;
  270.                 } else {
  271.                     $sql['orderings'][] = $columnName . ' ' . $order;
  272.                 }
  273.             }
  274.         }
  275.     }
  276.    
  277. }
  278.  
  279. ?>
Advertisement
Add Comment
Please, Sign In to add comment