‪TYPO3CMS  11.5
Typo3DbQueryParser.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
25 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
55 
61 {
63 
69  protected ‪$pageRepository;
70 
76  protected ‪$queryBuilder;
77 
86  protected ‪$tablePropertyMap = [];
87 
94  protected $tableAliasMap = [];
95 
101  protected $unionTableAliasCache = [];
102 
106  protected $tableName = '';
107 
111  protected $suggestDistinctQuery = false;
112 
113  public function __construct(‪DataMapper ‪$dataMapper)
114  {
115  $this->‪dataMapper = ‪$dataMapper;
116  }
117 
125  public function ‪isDistinctQuerySuggested(): bool
126  {
127  return $this->suggestDistinctQuery;
128  }
129 
137  {
138  // Reset all properties
139  $this->tablePropertyMap = [];
140  $this->tableAliasMap = [];
141  $this->unionTableAliasCache = [];
142  $this->tableName = '';
143 
144  if ($query->‪getStatement() && $query->‪getStatement()->getStatement() instanceof QueryBuilder) {
145  $this->queryBuilder = clone $query->‪getStatement()->getStatement();
146  return ‪$this->queryBuilder;
147  }
148  // Find the right table name
149  $source = $query->‪getSource();
150  $this->‪initializeQueryBuilder($source);
151 
152  $constraint = $query->‪getConstraint();
153  if ($constraint instanceof ‪ConstraintInterface) {
154  $wherePredicates = $this->‪parseConstraint($constraint, $source);
155  if (!empty($wherePredicates)) {
156  $this->queryBuilder->andWhere($wherePredicates);
157  }
158  }
159 
160  $this->‪parseOrderings($query->‪getOrderings(), $source);
161  $this->‪addTypo3Constraints($query);
162 
163  return ‪$this->queryBuilder;
164  }
165 
171  protected function ‪initializeQueryBuilder(‪SourceInterface $source)
172  {
173  if ($source instanceof ‪SelectorInterface) {
174  $className = $source->getNodeTypeName();
175  $tableName = $this->‪dataMapper->getDataMap($className)->getTableName();
176  $this->tableName = $tableName;
177 
178  $this->queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
179  ->getQueryBuilderForTable($tableName);
180 
181  $this->queryBuilder
182  ->getRestrictions()
183  ->removeAll();
184 
185  $tableAlias = $this->‪getUniqueAlias($tableName);
186 
187  $this->queryBuilder
188  ->select($tableAlias . '.*')
189  ->from($tableName, $tableAlias);
190 
191  $this->‪addRecordTypeConstraint($className);
192  } elseif ($source instanceof JoinInterface) {
193  $leftSource = $source->getLeft();
194  $leftTableName = $leftSource->getSelectorName();
195 
196  $this->queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
197  ->getQueryBuilderForTable($leftTableName);
198  $leftTableAlias = $this->‪getUniqueAlias($leftTableName);
199  $this->queryBuilder
200  ->select($leftTableAlias . '.*')
201  ->from($leftTableName, $leftTableAlias);
202  $this->‪parseJoin($source, $leftTableAlias);
203  }
204  }
205 
214  protected function ‪parseConstraint(ConstraintInterface $constraint, SourceInterface $source)
215  {
216  if ($constraint instanceof AndInterface) {
217  return $this->queryBuilder->expr()->andX(
218  $this->‪parseConstraint($constraint->getConstraint1(), $source),
219  $this->parseConstraint($constraint->getConstraint2(), $source)
220  );
221  }
222  if ($constraint instanceof OrInterface) {
223  return $this->queryBuilder->expr()->orX(
224  $this->‪parseConstraint($constraint->getConstraint1(), $source),
225  $this->parseConstraint($constraint->getConstraint2(), $source)
226  );
227  }
228  if ($constraint instanceof NotInterface) {
229  return ' NOT(' . $this->‪parseConstraint($constraint->getConstraint(), $source) . ')';
230  }
231  if ($constraint instanceof ComparisonInterface) {
232  return $this->‪parseComparison($constraint, $source);
233  }
234  throw new \RuntimeException('not implemented', 1476199898);
235  }
236 
244  protected function ‪parseOrderings(array $orderings, SourceInterface $source)
245  {
246  foreach ($orderings as $propertyName => $order) {
248  throw new UnsupportedOrderException('Unsupported order encountered.', 1242816074);
249  }
250  $className = null;
251  $tableName = '';
252  if ($source instanceof SelectorInterface) {
253  $className = $source->getNodeTypeName();
254  $tableName = $this->‪dataMapper->convertClassNameToTableName($className);
255  $fullPropertyPath = '';
256  while (str_contains($propertyName, '.')) {
257  $this->‪addUnionStatement($className, $tableName, $propertyName, $fullPropertyPath);
258  }
259  } elseif ($source instanceof JoinInterface) {
260  $tableName = $source->getLeft()->getSelectorName();
261  }
262  $columnName = $this->‪dataMapper->convertPropertyNameToColumnName($propertyName, $className);
263  if ($tableName !== '') {
264  $this->queryBuilder->addOrderBy($tableName . '.' . $columnName, $order);
265  } else {
266  $this->queryBuilder->addOrderBy($columnName, $order);
267  }
268  }
269  }
270 
276  protected function ‪addTypo3Constraints(‪QueryInterface $query)
277  {
278  $index = 0;
279  foreach ($this->tableAliasMap as $tableAlias => $tableName) {
280  if ($index === 0) {
281  // We only add the pid and language check for the first table (aggregate root).
282  // We know the first table is always the main table for the current query run.
283  $additionalWhereClauses = $this->‪getAdditionalWhereClause($query->‪getQuerySettings(), $tableName, $tableAlias);
284  } else {
285  $additionalWhereClauses = [];
286  }
287  $index++;
288  $statement = $this->‪getVisibilityConstraintStatement($query->‪getQuerySettings(), $tableName, $tableAlias);
289  if ($statement !== '') {
290  $additionalWhereClauses[] = $statement;
291  }
292  if (!empty($additionalWhereClauses)) {
293  if (in_array($tableAlias, $this->unionTableAliasCache, true)) {
294  $this->queryBuilder->andWhere(
295  $this->queryBuilder->expr()->orX(
296  $this->queryBuilder->expr()->andX(...$additionalWhereClauses),
297  $this->queryBuilder->expr()->isNull($tableAlias . '.uid')
298  )
299  );
300  } else {
301  $this->queryBuilder->andWhere(...$additionalWhereClauses);
302  }
303  }
304  }
305  }
306 
317  protected function ‪parseComparison(‪ComparisonInterface $comparison, ‪SourceInterface $source)
318  {
319  if ($comparison->‪getOperator() === ‪QueryInterface::OPERATOR_CONTAINS) {
320  if ($comparison->‪getOperand2() === null) {
321  throw new BadConstraintException('The value for the CONTAINS operator must not be null.', 1484828468);
322  }
323  $value = $this->‪dataMapper->getPlainValue($comparison->‪getOperand2());
324  if (!$source instanceof SelectorInterface) {
325  throw new \RuntimeException('Source is not of type "SelectorInterface"', 1395362539);
326  }
327  $className = $source->getNodeTypeName();
328  $tableName = $this->‪dataMapper->convertClassNameToTableName($className);
329  $operand1 = $comparison->‪getOperand1();
330  $propertyName = $operand1->‪getPropertyName();
331  $fullPropertyPath = '';
332  while (str_contains($propertyName, '.')) {
333  $this->‪addUnionStatement($className, $tableName, $propertyName, $fullPropertyPath);
334  }
335  $columnName = $this->‪dataMapper->convertPropertyNameToColumnName($propertyName, $className);
336  $dataMap = $this->‪dataMapper->getDataMap($className);
337  $columnMap = $dataMap->getColumnMap($propertyName);
338  $typeOfRelation = $columnMap instanceof ColumnMap ? $columnMap->getTypeOfRelation() : null;
339  if ($typeOfRelation === ‪ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
341  $relationTableName = (string)$columnMap->getRelationTableName();
342  $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder();
343  $queryBuilderForSubselect
344  ->select($columnMap->getParentKeyFieldName())
345  ->from($relationTableName)
346  ->where(
347  $queryBuilderForSubselect->expr()->eq(
348  $columnMap->getChildKeyFieldName(),
349  $this->queryBuilder->createNamedParameter($value)
350  )
351  );
352  $additionalWhereForMatchFields = $this->‪getAdditionalMatchFieldsStatement($queryBuilderForSubselect->expr(), $columnMap, $relationTableName, $relationTableName);
353  if ($additionalWhereForMatchFields) {
354  $queryBuilderForSubselect->andWhere($additionalWhereForMatchFields);
355  }
356 
357  return $this->queryBuilder->expr()->comparison(
358  $this->queryBuilder->quoteIdentifier($tableName . '.uid'),
359  'IN',
360  '(' . $queryBuilderForSubselect->getSQL() . ')'
361  );
362  }
363  if ($typeOfRelation === ‪ColumnMap::RELATION_HAS_MANY) {
364  $parentKeyFieldName = $columnMap->getParentKeyFieldName();
365  if (isset($parentKeyFieldName)) {
366  $childTableName = $columnMap->getChildTableName();
367 
368  // Build the SQL statement of the subselect
369  $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder();
370  $queryBuilderForSubselect
371  ->select($parentKeyFieldName)
372  ->from($childTableName)
373  ->where(
374  $queryBuilderForSubselect->expr()->eq(
375  'uid',
376  (int)$value
377  )
378  );
379 
380  // Add it to the main query
381  return $this->queryBuilder->expr()->eq(
382  $tableName . '.uid',
383  '(' . $queryBuilderForSubselect->getSQL() . ')'
384  );
385  }
386  return $this->queryBuilder->expr()->inSet(
387  $tableName . '.' . $columnName,
388  $this->queryBuilder->quote($value)
389  );
390  }
391  throw new RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745);
392  }
393  return $this->‪parseDynamicOperand($comparison, $source);
394  }
395 
405  protected function ‪parseDynamicOperand(ComparisonInterface $comparison, SourceInterface $source)
406  {
407  $value = $comparison->getOperand2();
408  $fieldName = $this->‪parseOperand($comparison->getOperand1(), $source);
409  $exprBuilder = $this->queryBuilder->expr();
410  switch ($comparison->getOperator()) {
412  $hasValue = false;
413  $plainValues = [];
414  foreach ($value as $singleValue) {
415  $plainValue = $this->‪dataMapper->getPlainValue($singleValue);
416  if ($plainValue !== null) {
417  $hasValue = true;
418  $plainValues[] = $this->‪createTypedNamedParameter($singleValue);
419  }
420  }
421  if (!$hasValue) {
422  throw new BadConstraintException(
423  'The IN operator needs a non-empty value list to compare against. ' .
424  'The given value list is empty.',
425  1484828466
426  );
427  }
428  $expr = $exprBuilder->comparison($fieldName, 'IN', '(' . implode(', ', $plainValues) . ')');
429  break;
431  if ($value === null) {
432  $expr = $fieldName . ' IS NULL';
433  } else {
434  $placeHolder = $this->‪createTypedNamedParameter($value);
435  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::EQ, $placeHolder);
436  }
437  break;
439  $expr = $fieldName . ' IS NULL';
440  break;
442  if ($value === null) {
443  $expr = $fieldName . ' IS NOT NULL';
444  } else {
445  $placeHolder = $this->‪createTypedNamedParameter($value);
446  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::NEQ, $placeHolder);
447  }
448  break;
450  $expr = $fieldName . ' IS NOT NULL';
451  break;
453  $placeHolder = $this->‪createTypedNamedParameter($value);
454  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::LT, $placeHolder);
455  break;
457  $placeHolder = $this->‪createTypedNamedParameter($value);
458  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::LTE, $placeHolder);
459  break;
461  $placeHolder = $this->‪createTypedNamedParameter($value);
462  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::GT, $placeHolder);
463  break;
465  $placeHolder = $this->‪createTypedNamedParameter($value);
466  $expr = $exprBuilder->comparison($fieldName, $exprBuilder::GTE, $placeHolder);
467  break;
469  $placeHolder = $this->‪createTypedNamedParameter($value, ‪Connection::PARAM_STR);
470  $expr = $exprBuilder->comparison($fieldName, 'LIKE', $placeHolder);
471  break;
472  default:
473  throw new Exception(
474  'Unsupported operator encountered.',
475  1242816073
476  );
477  }
478  return $expr;
479  }
480 
489  protected function ‪getParameterType($value): int
490  {
491  $parameterType = gettype($value);
492  switch ($parameterType) {
493  case 'integer':
495  case 'string':
497  default:
498  throw new \InvalidArgumentException(
499  'Unsupported parameter type encountered. Expected integer or string, ' . $parameterType . ' given.',
500  1494878863
501  );
502  }
503  }
504 
515  protected function ‪createTypedNamedParameter($value, int $forceType = null): string
516  {
517  if ($value instanceof AbstractDomainObject
518  && $value->_hasProperty('_localizedUid')
519  && $value->_getProperty('_localizedUid') > 0
520  ) {
521  $plainValue = (int)$value->_getProperty('_localizedUid');
522  } else {
523  $plainValue = $this->‪dataMapper->getPlainValue($value);
524  }
525  $parameterType = $forceType ?? $this->‪getParameterType($plainValue);
526  $placeholder = $this->queryBuilder->createNamedParameter($plainValue, $parameterType);
527 
528  return $placeholder;
529  }
530 
537  protected function ‪parseOperand(‪DynamicOperandInterface $operand, ‪SourceInterface $source)
538  {
539  $tableName = null;
540  if ($operand instanceof ‪LowerCaseInterface) {
541  $constraintSQL = 'LOWER(' . $this->‪parseOperand($operand->getOperand(), $source) . ')';
542  } elseif ($operand instanceof ‪UpperCaseInterface) {
543  $constraintSQL = 'UPPER(' . $this->‪parseOperand($operand->getOperand(), $source) . ')';
544  } elseif ($operand instanceof ‪PropertyValueInterface) {
545  $propertyName = $operand->getPropertyName();
546  $className = '';
547  if ($source instanceof ‪SelectorInterface) {
548  $className = $source->getNodeTypeName();
549  $tableName = $this->‪dataMapper->convertClassNameToTableName($className);
550  $fullPropertyPath = '';
551  while (str_contains($propertyName, '.')) {
552  $this->‪addUnionStatement($className, $tableName, $propertyName, $fullPropertyPath);
553  }
554  } elseif ($source instanceof ‪JoinInterface) {
555  $tableName = $source->getJoinCondition()->getSelector1Name();
556  }
557  $columnName = $this->‪dataMapper->convertPropertyNameToColumnName($propertyName, $className);
558  $constraintSQL = (!empty($tableName) ? $tableName . '.' : '') . $columnName;
559  $constraintSQL = $this->queryBuilder->getConnection()->quoteIdentifier($constraintSQL);
560  } else {
561  throw new \InvalidArgumentException('Given operand has invalid type "' . get_class($operand) . '".', 1395710211);
562  }
563  return $constraintSQL;
564  }
565 
571  protected function ‪addRecordTypeConstraint($className)
572  {
573  if ($className !== null) {
574  $dataMap = $this->‪dataMapper->getDataMap($className);
575  if ($dataMap->getRecordTypeColumnName() !== null) {
576  $recordTypes = [];
577  if ($dataMap->getRecordType() !== null) {
578  $recordTypes[] = $dataMap->getRecordType();
579  }
580  foreach ($dataMap->getSubclasses() as $subclassName) {
581  $subclassDataMap = $this->‪dataMapper->getDataMap($subclassName);
582  if ($subclassDataMap->getRecordType() !== null) {
583  $recordTypes[] = $subclassDataMap->getRecordType();
584  }
585  }
586  if (!empty($recordTypes)) {
587  $recordTypeStatements = [];
588  foreach ($recordTypes as $recordType) {
589  $tableName = $dataMap->getTableName();
590  $recordTypeStatements[] = $this->queryBuilder->expr()->eq(
591  $tableName . '.' . $dataMap->getRecordTypeColumnName(),
592  $this->queryBuilder->createNamedParameter($recordType)
593  );
594  }
595  $this->queryBuilder->andWhere(
596  $this->queryBuilder->expr()->orX(...$recordTypeStatements)
597  );
598  }
599  }
600  }
601  }
602 
613  protected function ‪getAdditionalMatchFieldsStatement($exprBuilder, $columnMap, $childTableAlias, $parentTable = null)
614  {
615  $additionalWhereForMatchFields = [];
616  $relationTableMatchFields = $columnMap->getRelationTableMatchFields();
617  if (is_array($relationTableMatchFields) && !empty($relationTableMatchFields)) {
618  foreach ($relationTableMatchFields as $fieldName => $value) {
619  $additionalWhereForMatchFields[] = $exprBuilder->eq($childTableAlias . '.' . $fieldName, $this->queryBuilder->createNamedParameter($value));
620  }
621  }
622 
623  if (isset($parentTable)) {
624  $parentTableFieldName = $columnMap->getParentTableFieldName();
625  if (!empty($parentTableFieldName)) {
626  $additionalWhereForMatchFields[] = $exprBuilder->eq($childTableAlias . '.' . $parentTableFieldName, $this->queryBuilder->createNamedParameter($parentTable));
627  }
628  }
629 
630  if (!empty($additionalWhereForMatchFields)) {
631  return $exprBuilder->andX(...$additionalWhereForMatchFields);
632  }
633  return '';
634  }
635 
644  protected function ‪getAdditionalWhereClause(QuerySettingsInterface $querySettings, $tableName, $tableAlias = null)
645  {
646  $tableAlias = (string)$tableAlias;
647  // todo: $tableAlias must not be null
648 
649  $whereClause = [];
650  if ($querySettings->getRespectSysLanguage()) {
651  $systemLanguageStatement = $this->‪getLanguageStatement($tableName, $tableAlias, $querySettings);
652  if (!empty($systemLanguageStatement)) {
653  $whereClause[] = $systemLanguageStatement;
654  }
655  }
656 
657  if ($querySettings->getRespectStoragePage()) {
658  $pageIdStatement = $this->‪getPageIdStatement($tableName, $tableAlias, $querySettings->getStoragePageIds());
659  if (!empty($pageIdStatement)) {
660  $whereClause[] = $pageIdStatement;
661  }
662  }
663  if (!empty(‪$GLOBALS['TCA'][$tableName]['ctrl']['versioningWS'])) {
664  // Always prevent workspace records from being returned (except for newly created records)
665  $whereClause[] = $this->queryBuilder->expr()->eq($tableAlias . '.t3ver_oid', 0);
666  }
667 
668  return $whereClause;
669  }
670 
679  protected function ‪getVisibilityConstraintStatement(QuerySettingsInterface $querySettings, $tableName, $tableAlias)
680  {
681  if (!is_array(‪$GLOBALS['TCA'][$tableName]['ctrl'] ?? null)) {
682  return '';
683  }
684 
685  $ignoreEnableFields = $querySettings->getIgnoreEnableFields();
686  $enableFieldsToBeIgnored = $querySettings->getEnableFieldsToBeIgnored();
687  $includeDeleted = $querySettings->getIncludeDeleted();
688  if ((‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
689  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isFrontend()
690  ) {
691  $statement = $this->‪getFrontendConstraintStatement($tableName, $ignoreEnableFields, $enableFieldsToBeIgnored, $includeDeleted);
692  } else {
693  // applicationType backend
694  $statement = $this->‪getBackendConstraintStatement($tableName, $ignoreEnableFields, $includeDeleted);
695  }
696  if (!empty($statement)) {
697  $statement = $this->‪replaceTableNameWithAlias($statement, $tableName, $tableAlias);
698  $statement = strtolower(substr($statement, 1, 3)) === 'and' ? substr($statement, 5) : $statement;
699  }
700  return $statement;
701  }
702 
713  protected function ‪getFrontendConstraintStatement($tableName, $ignoreEnableFields, array $enableFieldsToBeIgnored, $includeDeleted)
714  {
715  $statement = '';
716  if ($ignoreEnableFields && !$includeDeleted) {
717  if (!empty($enableFieldsToBeIgnored)) {
718  // array_combine() is necessary because of the way \TYPO3\CMS\Core\Domain\Repository\PageRepository::enableFields() is implemented
719  $statement .= $this->‪getPageRepository()->‪enableFields($tableName, -1, array_combine($enableFieldsToBeIgnored, $enableFieldsToBeIgnored));
720  } elseif (!empty(‪$GLOBALS['TCA'][$tableName]['ctrl']['delete'])) {
721  $statement .= ' AND ' . $tableName . '.' . ‪$GLOBALS['TCA'][$tableName]['ctrl']['delete'] . '=0';
722  }
723  } elseif (!$ignoreEnableFields && !$includeDeleted) {
724  $statement .= $this->‪getPageRepository()->‪enableFields($tableName);
725  } elseif (!$ignoreEnableFields) {
726  throw new InconsistentQuerySettingsException('Query setting "ignoreEnableFields=FALSE" can not be used together with "includeDeleted=TRUE" in frontend context.', 1460975922);
727  }
728  return $statement;
729  }
730 
739  protected function ‪getBackendConstraintStatement($tableName, $ignoreEnableFields, $includeDeleted)
740  {
741  $statement = '';
742  // In case of versioning-preview, enableFields are ignored (checked in Typo3DbBackend::doLanguageAndWorkspaceOverlay)
743  $isUserInWorkspace = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('workspace', 'isOffline');
744  if (!$ignoreEnableFields && !$isUserInWorkspace) {
745  $statement .= BackendUtility::BEenableFields($tableName);
746  }
747  if (!$includeDeleted && !empty(‪$GLOBALS['TCA'][$tableName]['ctrl']['delete'])) {
748  $statement .= ' AND ' . $tableName . '.' . ‪$GLOBALS['TCA'][$tableName]['ctrl']['delete'] . '=0';
749  }
750  return $statement;
751  }
752 
761  protected function ‪getLanguageStatement($tableName, $tableAlias, QuerySettingsInterface $querySettings)
762  {
763  if (empty(‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField'])) {
764  return '';
765  }
766 
767  // Select all entries for the current language
768  // If any language is set -> get those entries which are not translated yet
769  // They will be removed by \TYPO3\CMS\Core\Domain\Repository\PageRepository::getRecordOverlay if not matching overlay mode
770  $languageField = ‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField'];
771 
772  $transOrigPointerField = ‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] ?? '';
773  if (!$transOrigPointerField || !$querySettings->getLanguageUid()) {
774  return $this->queryBuilder->expr()->in(
775  $tableAlias . '.' . $languageField,
776  [(int)$querySettings->getLanguageUid(), -1]
777  );
778  }
779 
780  $mode = $querySettings->getLanguageOverlayMode();
781  if (!$mode) {
782  return $this->queryBuilder->expr()->in(
783  $tableAlias . '.' . $languageField,
784  [(int)$querySettings->getLanguageUid(), -1]
785  );
786  }
787 
788  $defLangTableAlias = $tableAlias . '_dl';
789  $defaultLanguageRecordsSubSelect = $this->queryBuilder->getConnection()->createQueryBuilder();
790  $defaultLanguageRecordsSubSelect
791  ->select($defLangTableAlias . '.uid')
792  ->from($tableName, $defLangTableAlias)
793  ->where(
794  $defaultLanguageRecordsSubSelect->expr()->andX(
795  $defaultLanguageRecordsSubSelect->expr()->eq($defLangTableAlias . '.' . $transOrigPointerField, 0),
796  $defaultLanguageRecordsSubSelect->expr()->eq($defLangTableAlias . '.' . $languageField, 0)
797  )
798  );
799 
800  $andConditions = [];
801  // records in language 'all'
802  $andConditions[] = $this->queryBuilder->expr()->eq($tableAlias . '.' . $languageField, -1);
803  // translated records where a default language exists
804  $andConditions[] = $this->queryBuilder->expr()->andX(
805  $this->queryBuilder->expr()->eq($tableAlias . '.' . $languageField, (int)$querySettings->getLanguageUid()),
806  $this->queryBuilder->expr()->in(
807  $tableAlias . '.' . $transOrigPointerField,
808  $defaultLanguageRecordsSubSelect->getSQL()
809  )
810  );
811  if ($mode !== 'hideNonTranslated') {
812  // $mode = TRUE
813  // returns records from current language which have default language
814  // together with not translated default language records
815  $translatedOnlyTableAlias = $tableAlias . '_to';
816  $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder();
817  $queryBuilderForSubselect
818  ->select($translatedOnlyTableAlias . '.' . $transOrigPointerField)
819  ->from($tableName, $translatedOnlyTableAlias)
820  ->where(
821  $queryBuilderForSubselect->expr()->andX(
822  $queryBuilderForSubselect->expr()->gt($translatedOnlyTableAlias . '.' . $transOrigPointerField, 0),
823  $queryBuilderForSubselect->expr()->eq($translatedOnlyTableAlias . '.' . $languageField, (int)$querySettings->getLanguageUid())
824  )
825  );
826  // records in default language, which do not have a translation
827  $andConditions[] = $this->queryBuilder->expr()->andX(
828  $this->queryBuilder->expr()->eq($tableAlias . '.' . $languageField, 0),
829  $this->queryBuilder->expr()->notIn(
830  $tableAlias . '.uid',
831  $queryBuilderForSubselect->getSQL()
832  )
833  );
834  }
835 
836  return $this->queryBuilder->expr()->orX(...$andConditions);
837  }
838 
848  protected function ‪getPageIdStatement($tableName, $tableAlias, array $storagePageIds)
849  {
850  if (!is_array(‪$GLOBALS['TCA'][$tableName]['ctrl'] ?? null)) {
851  return '';
852  }
853 
854  $rootLevel = (int)(‪$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] ?? 0);
855  switch ($rootLevel) {
856  // Only in pid 0
857  case 1:
858  $storagePageIds = [0];
859  break;
860  // Pid 0 and pagetree
861  case -1:
862  if (empty($storagePageIds)) {
863  $storagePageIds = [0];
864  } else {
865  $storagePageIds[] = 0;
866  }
867  break;
868  // Only pagetree or not set
869  case 0:
870  if (empty($storagePageIds)) {
871  throw new InconsistentQuerySettingsException('Missing storage page ids.', 1365779762);
872  }
873  break;
874  // Invalid configuration
875  default:
876  return '';
877  }
878  $storagePageIds = array_map('intval', $storagePageIds);
879  if (count($storagePageIds) === 1) {
880  return $this->queryBuilder->expr()->eq($tableAlias . '.pid', reset($storagePageIds));
881  }
882  return $this->queryBuilder->expr()->in($tableAlias . '.pid', $storagePageIds);
883  }
884 
891  protected function ‪parseJoin(‪JoinInterface $join, $leftTableAlias)
892  {
893  $leftSource = $join->‪getLeft();
894  $leftClassName = $leftSource->‪getNodeTypeName();
895  $this->‪addRecordTypeConstraint($leftClassName);
896  $rightSource = $join->‪getRight();
897  if ($rightSource instanceof ‪JoinInterface) {
898  $left = $rightSource->getLeft();
899  $rightClassName = $left->‪getNodeTypeName();
900  $rightTableName = $left->getSelectorName();
901  } else {
902  $rightClassName = $rightSource->getNodeTypeName();
903  $rightTableName = $rightSource->getSelectorName();
904  $this->queryBuilder->addSelect($rightTableName . '.*');
905  }
906  $this->‪addRecordTypeConstraint($rightClassName);
907  $rightTableAlias = $this->‪getUniqueAlias($rightTableName);
908  $joinCondition = $join->‪getJoinCondition();
909  $joinConditionExpression = null;
910  if ($joinCondition instanceof ‪EquiJoinCondition) {
911  $column1Name = $this->‪dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty1Name(), $leftClassName);
912  $column2Name = $this->‪dataMapper->convertPropertyNameToColumnName($joinCondition->getProperty2Name(), $rightClassName);
913 
914  $joinConditionExpression = $this->queryBuilder->expr()->eq(
915  $leftTableAlias . '.' . $column1Name,
916  $this->queryBuilder->quoteIdentifier($rightTableAlias . '.' . $column2Name)
917  );
918  }
919  $this->queryBuilder->leftJoin($leftTableAlias, $rightTableName, $rightTableAlias, $joinConditionExpression);
920  if ($rightSource instanceof ‪JoinInterface) {
921  $this->‪parseJoin($rightSource, $rightTableAlias);
922  }
923  }
924 
933  protected function ‪getUniqueAlias($tableName, $fullPropertyPath = null)
934  {
935  if (isset($fullPropertyPath) && isset($this->tablePropertyMap[$fullPropertyPath])) {
936  return $this->tablePropertyMap[$fullPropertyPath];
937  }
938 
939  $alias = $tableName;
940  $i = 0;
941  while (isset($this->tableAliasMap[$alias])) {
942  $alias = $tableName . $i;
943  $i++;
944  }
945 
946  $this->tableAliasMap[$alias] = $tableName;
947 
948  if (isset($fullPropertyPath)) {
949  $this->tablePropertyMap[$fullPropertyPath] = $alias;
950  }
951 
952  return $alias;
953  }
954 
967  protected function ‪addUnionStatement(&$className, &$tableName, &$propertyPath, &$fullPropertyPath)
968  {
969  $explodedPropertyPath = explode('.', $propertyPath, 2);
970  $propertyName = $explodedPropertyPath[0];
971  $columnName = $this->‪dataMapper->convertPropertyNameToColumnName($propertyName, $className);
972  $realTableName = $this->‪dataMapper->convertClassNameToTableName($className);
973  $tableName = $this->tablePropertyMap[$fullPropertyPath] ?? $realTableName;
974  $columnMap = $this->‪dataMapper->getDataMap($className)->getColumnMap($propertyName);
975 
976  if ($columnMap === null) {
977  throw new MissingColumnMapException('The ColumnMap for property "' . $propertyName . '" of class "' . $className . '" is missing.', 1355142232);
978  }
979 
980  $parentKeyFieldName = $columnMap->getParentKeyFieldName();
981  $childTableName = $columnMap->getChildTableName();
982 
983  if ($childTableName === null) {
984  throw new InvalidRelationConfigurationException('The relation information for property "' . $propertyName . '" of class "' . $className . '" is missing.', 1353170925);
985  }
986 
987  $fullPropertyPath .= ($fullPropertyPath === '') ? $propertyName : '.' . $propertyName;
988  $childTableAlias = $this->‪getUniqueAlias($childTableName, $fullPropertyPath);
989 
990  // If there is already a union with the current identifier we do not need to build it again and exit early.
991  if (in_array($childTableAlias, $this->unionTableAliasCache, true)) {
992  $propertyPath = $explodedPropertyPath[1];
993  $tableName = $childTableAlias;
994  $className = $this->‪dataMapper->getType($className, $propertyName);
995  return;
996  }
997 
998  if ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_ONE) {
999  if (isset($parentKeyFieldName)) {
1000  // @todo: no test for this part yet
1001  $basicJoinCondition = $this->queryBuilder->expr()->eq(
1002  $tableName . '.uid',
1003  $this->queryBuilder->quoteIdentifier($childTableAlias . '.' . $parentKeyFieldName)
1004  );
1005  } else {
1006  $basicJoinCondition = $this->queryBuilder->expr()->eq(
1007  $tableName . '.' . $columnName,
1008  $this->queryBuilder->quoteIdentifier($childTableAlias . '.uid')
1009  );
1010  }
1011  $joinConditionExpression = $this->queryBuilder->expr()->and(
1012  $basicJoinCondition,
1013  $this->‪getAdditionalMatchFieldsStatement($this->queryBuilder->expr(), $columnMap, $childTableAlias, $realTableName)
1014  );
1015  $this->queryBuilder->leftJoin($tableName, $childTableName, $childTableAlias, (string)$joinConditionExpression);
1016  $this->unionTableAliasCache[] = $childTableAlias;
1017  } elseif ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_MANY) {
1018  if (isset($parentKeyFieldName)) {
1019  $basicJoinCondition = $this->queryBuilder->expr()->eq(
1020  $tableName . '.uid',
1021  $this->queryBuilder->quoteIdentifier($childTableAlias . '.' . $parentKeyFieldName)
1022  );
1023  } else {
1024  $basicJoinCondition = $this->queryBuilder->expr()->inSet(
1025  $tableName . '.' . $columnName,
1026  $this->queryBuilder->quoteIdentifier($childTableAlias . '.uid'),
1027  true
1028  );
1029  }
1030  $joinConditionExpression = $this->queryBuilder->expr()->and(
1031  $basicJoinCondition,
1032  $this->‪getAdditionalMatchFieldsStatement($this->queryBuilder->expr(), $columnMap, $childTableAlias, $realTableName)
1033  );
1034  $this->queryBuilder->leftJoin($tableName, $childTableName, $childTableAlias, (string)$joinConditionExpression);
1035  $this->unionTableAliasCache[] = $childTableAlias;
1036  $this->suggestDistinctQuery = true;
1037  } elseif ($columnMap->getTypeOfRelation() === ‪ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) {
1038  $relationTableName = (string)$columnMap->getRelationTableName();
1039  $relationTableAlias = $this->‪getUniqueAlias($relationTableName, $fullPropertyPath . '_mm');
1040 
1041  $joinConditionExpression = $this->queryBuilder->expr()->andX(
1042  $this->queryBuilder->expr()->eq(
1043  $tableName . '.uid',
1044  $this->queryBuilder->quoteIdentifier(
1045  $relationTableAlias . '.' . $columnMap->getParentKeyFieldName()
1046  )
1047  ),
1048  $this->getAdditionalMatchFieldsStatement($this->queryBuilder->expr(), $columnMap, $relationTableAlias, $realTableName)
1049  );
1050  $this->queryBuilder->leftJoin($tableName, $relationTableName, $relationTableAlias, $joinConditionExpression);
1051  $joinConditionExpression = $this->queryBuilder->expr()->eq(
1052  $relationTableAlias . '.' . $columnMap->getChildKeyFieldName(),
1053  $this->queryBuilder->quoteIdentifier($childTableAlias . '.uid')
1054  );
1055  $this->queryBuilder->leftJoin($relationTableAlias, $childTableName, $childTableAlias, $joinConditionExpression);
1056  $this->unionTableAliasCache[] = $childTableAlias;
1057  $this->suggestDistinctQuery = true;
1058  } else {
1059  throw new Exception('Could not determine type of relation.', 1252502725);
1060  }
1061  $propertyPath = $explodedPropertyPath[1];
1062  $tableName = $childTableAlias;
1063  $className = $this->‪dataMapper->getType($className, $propertyName);
1064  }
1065 
1075  protected function ‪replaceTableNameWithAlias($statement, $tableName, $tableAlias)
1076  {
1077  if ($tableAlias !== $tableName) {
1078  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
1079  $quotedTableName = $connection->quoteIdentifier($tableName);
1080  $quotedTableAlias = $connection->quoteIdentifier($tableAlias);
1081  $statement = str_replace(
1082  [$tableName . '.', $quotedTableName . '.'],
1083  [$tableAlias . '.', $quotedTableAlias . '.'],
1084  $statement
1085  );
1086  }
1088  return $statement;
1089  }
1090 
1094  protected function ‪getPageRepository()
1095  {
1096  if (!$this->pageRepository instanceof ‪PageRepository) {
1097  $this->pageRepository = GeneralUtility::makeInstance(PageRepository::class);
1098  }
1099  return ‪$this->pageRepository;
1100  }
1101 }
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getConstraint
‪ConstraintInterface null getConstraint()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface\getLeft
‪SelectorInterface getLeft()
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidRelationConfigurationException
Definition: InvalidRelationConfigurationException.php:25
‪TYPO3\CMS\Core\Http\ApplicationType\fromRequest
‪static static fromRequest(ServerRequestInterface $request)
Definition: ApplicationType.php:62
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\initializeQueryBuilder
‪initializeQueryBuilder(SourceInterface $source)
Definition: Typo3DbQueryParser.php:164
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_LIKE
‪const OPERATOR_LIKE
Definition: QueryInterface.php:73
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface\getOperand1
‪PropertyValueInterface getOperand1()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface\getNodeTypeName
‪string getNodeTypeName()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\createTypedNamedParameter
‪string createTypedNamedParameter($value, int $forceType=null)
Definition: Typo3DbQueryParser.php:508
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_GREATER_THAN_OR_EQUAL_TO
‪const OPERATOR_GREATER_THAN_OR_EQUAL_TO
Definition: QueryInterface.php:68
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getStoragePageIds
‪int[] getStoragePageIds()
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:36
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\replaceTableNameWithAlias
‪string replaceTableNameWithAlias($statement, $tableName, $tableAlias)
Definition: Typo3DbQueryParser.php:1068
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getRespectStoragePage
‪bool getRespectStoragePage()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_NOT_EQUAL_TO_NULL
‪const OPERATOR_NOT_EQUAL_TO_NULL
Definition: QueryInterface.php:48
‪TYPO3\CMS\Extbase\Persistence\QueryInterface
Definition: QueryInterface.php:29
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getBackendConstraintStatement
‪string getBackendConstraintStatement($tableName, $ignoreEnableFields, $includeDeleted)
Definition: Typo3DbQueryParser.php:732
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\_hasProperty
‪bool _hasProperty($propertyName)
Definition: AbstractDomainObject.php:153
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\addRecordTypeConstraint
‪addRecordTypeConstraint($className)
Definition: Typo3DbQueryParser.php:564
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\PropertyValueInterface\getPropertyName
‪string getPropertyName()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_GREATER_THAN
‪const OPERATOR_GREATER_THAN
Definition: QueryInterface.php:63
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getFrontendConstraintStatement
‪string getFrontendConstraintStatement($tableName, $ignoreEnableFields, array $enableFieldsToBeIgnored, $includeDeleted)
Definition: Typo3DbQueryParser.php:706
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
Definition: ColumnMap.php:28
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_DESCENDING
‪const ORDER_DESCENDING
Definition: QueryInterface.php:99
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getLanguageStatement
‪string getLanguageStatement($tableName, $tableAlias, QuerySettingsInterface $querySettings)
Definition: Typo3DbQueryParser.php:754
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseOrderings
‪parseOrderings(array $orderings, SourceInterface $source)
Definition: Typo3DbQueryParser.php:237
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_IN
‪const OPERATOR_IN
Definition: QueryInterface.php:83
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_AND_BELONGS_TO_MANY
‪const RELATION_HAS_AND_BELONGS_TO_MANY
Definition: ColumnMap.php:52
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
Definition: SourceInterface.php:21
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\$pageRepository
‪PageRepository $pageRepository
Definition: Typo3DbQueryParser.php:68
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\convertQueryToDoctrineQueryBuilder
‪QueryBuilder convertQueryToDoctrineQueryBuilder(QueryInterface $query)
Definition: Typo3DbQueryParser.php:129
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getRespectSysLanguage
‪bool getRespectSysLanguage()
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getIncludeDeleted
‪bool getIncludeDeleted()
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException
Definition: RepositoryException.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
Definition: DataMapper.php:51
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getIgnoreEnableFields
‪bool getIgnoreEnableFields()
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getEnableFieldsToBeIgnored
‪string[] getEnableFieldsToBeIgnored()
‪TYPO3\CMS\Core\Http\ApplicationType
Definition: ApplicationType.php:52
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:54
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface
Definition: OrInterface.php:27
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_MANY
‪const RELATION_HAS_MANY
Definition: ColumnMap.php:42
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\RELATION_HAS_ONE
‪const RELATION_HAS_ONE
Definition: ColumnMap.php:37
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_LESS_THAN_OR_EQUAL_TO
‪const OPERATOR_LESS_THAN_OR_EQUAL_TO
Definition: QueryInterface.php:58
‪TYPO3\CMS\Extbase\Exception
Definition: Exception.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\InconsistentQuerySettingsException
Definition: InconsistentQuerySettingsException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getUniqueAlias
‪string getUniqueAlias($tableName, $fullPropertyPath=null)
Definition: Typo3DbQueryParser.php:926
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\PropertyValueInterface
Definition: PropertyValueInterface.php:30
‪TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression
Definition: CompositeExpression.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getPageIdStatement
‪string getPageIdStatement($tableName, $tableAlias, array $storagePageIds)
Definition: Typo3DbQueryParser.php:841
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface
Definition: SelectorInterface.php:30
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_ASCENDING
‪const ORDER_ASCENDING
Definition: QueryInterface.php:98
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\isDistinctQuerySuggested
‪bool isDistinctQuerySuggested()
Definition: Typo3DbQueryParser.php:118
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface\getOperand2
‪StaticOperandInterface getOperand2()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getPageRepository
‪PageRepository getPageRepository()
Definition: Typo3DbQueryParser.php:1087
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseComparison
‪string parseComparison(ComparisonInterface $comparison, SourceInterface $source)
Definition: Typo3DbQueryParser.php:310
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
Definition: AbstractDomainObject.php:31
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_CONTAINS
‪const OPERATOR_CONTAINS
Definition: QueryInterface.php:78
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getVisibilityConstraintStatement
‪string getVisibilityConstraintStatement(QuerySettingsInterface $querySettings, $tableName, $tableAlias)
Definition: Typo3DbQueryParser.php:672
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getLanguageUid
‪int getLanguageUid()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getAdditionalMatchFieldsStatement
‪string getAdditionalMatchFieldsStatement($exprBuilder, $columnMap, $childTableAlias, $parentTable=null)
Definition: Typo3DbQueryParser.php:606
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getStatement
‪TYPO3 CMS Extbase Persistence Generic Qom Statement getStatement()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
Definition: ComparisonInterface.php:62
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\$dataMapper
‪DataMapper $dataMapper
Definition: Typo3DbQueryParser.php:62
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseConstraint
‪CompositeExpression string parseConstraint(ConstraintInterface $constraint, SourceInterface $source)
Definition: Typo3DbQueryParser.php:207
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\dataMapper
‪array< string, $tableAliasMap=array();protected array $unionTableAliasCache=array();protected string $tableName='';protected bool $suggestDistinctQuery=false;public function __construct(DataMapper $dataMapper) { $this-> dataMapper
Definition: Typo3DbQueryParser.php:108
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage
Definition: BackendInterface.php:18
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception
Definition: InconsistentQuerySettingsException.php:18
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getOrderings
‪array< string, string > getOrderings()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface
Definition: JoinInterface.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface
Definition: NotInterface.php:24
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Exception\BadConstraintException
Definition: BadConstraintException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface
Definition: QuerySettingsInterface.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException
Definition: UnsupportedOrderException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface\getOperator
‪string getOperator()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getAdditionalWhereClause
‪array getAdditionalWhereClause(QuerySettingsInterface $querySettings, $tableName, $tableAlias=null)
Definition: Typo3DbQueryParser.php:637
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\enableFields
‪string enableFields($table, $show_hidden=-1, $ignore_array=[])
Definition: PageRepository.php:1427
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_LESS_THAN
‪const OPERATOR_LESS_THAN
Definition: QueryInterface.php:53
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\$tablePropertyMap
‪array $tablePropertyMap
Definition: Typo3DbQueryParser.php:83
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom
Definition: AndInterface.php:16
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_EQUAL_TO
‪const OPERATOR_EQUAL_TO
Definition: QueryInterface.php:33
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getQuerySettings
‪TYPO3 CMS Extbase Persistence Generic QuerySettingsInterface getQuerySettings()
‪TYPO3\CMS\Extbase\Persistence\Generic\Exception\MissingColumnMapException
Definition: MissingColumnMapException.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseDynamicOperand
‪string parseDynamicOperand(ComparisonInterface $comparison, SourceInterface $source)
Definition: Typo3DbQueryParser.php:398
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\UpperCaseInterface
Definition: UpperCaseInterface.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface\getRight
‪SelectorInterface getRight()
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_NOT_EQUAL_TO
‪const OPERATOR_NOT_EQUAL_TO
Definition: QueryInterface.php:43
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface
Definition: ConstraintInterface.php:25
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:53
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\DynamicOperandInterface
Definition: DynamicOperandInterface.php:21
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\OPERATOR_EQUAL_TO_NULL
‪const OPERATOR_EQUAL_TO_NULL
Definition: QueryInterface.php:38
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\getParameterType
‪int getParameterType($value)
Definition: Typo3DbQueryParser.php:482
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseOperand
‪string parseOperand(DynamicOperandInterface $operand, SourceInterface $source)
Definition: Typo3DbQueryParser.php:530
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\addTypo3Constraints
‪addTypo3Constraints(QueryInterface $query)
Definition: Typo3DbQueryParser.php:269
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\getTypeOfRelation
‪string getTypeOfRelation()
Definition: ColumnMap.php:206
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getLanguageOverlayMode
‪bool string getLanguageOverlayMode()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\EquiJoinCondition
Definition: EquiJoinCondition.php:27
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\parseJoin
‪parseJoin(JoinInterface $join, $leftTableAlias)
Definition: Typo3DbQueryParser.php:884
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\LowerCaseInterface
Definition: LowerCaseInterface.php:28
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface
Definition: AndInterface.php:25
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\addUnionStatement
‪addUnionStatement(&$className, &$tableName, &$propertyPath, &$fullPropertyPath)
Definition: Typo3DbQueryParser.php:960
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser\$queryBuilder
‪QueryBuilder $queryBuilder
Definition: Typo3DbQueryParser.php:74
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface\getJoinCondition
‪JoinConditionInterface getJoinCondition()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser
Definition: Typo3DbQueryParser.php:61