/** * Returns the selectorn name or an empty string, if the source is not a selector * TODO This has to be checked at another place * * @return string The selector name */ protected function getSelectorName() { if ($this->getSource() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) { return $this->source->getSelectorName(); } else { return ''; } }
/** * Performs workspace and language overlay on the given row array. The language and workspace id is automatically * detected (depending on FE or BE context). You can also explicitly set the language/workspace id. * * @param Qom\SourceInterface $source The source (selector od join) * @param array $rows * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The TYPO3 CMS specific query settings * @param null|int $workspaceUid * @return array */ protected function doLanguageAndWorkspaceOverlay(Qom\SourceInterface $source, array $rows, \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings, $workspaceUid = NULL) { if ($source instanceof Qom\SelectorInterface) { $tableName = $source->getSelectorName(); } elseif ($source instanceof Qom\JoinInterface) { $tableName = $source->getRight()->getSelectorName(); } else { // No proper source, so we do not have a table name here // we cannot do an overlay and return the original rows instead. return $rows; } $pageRepository = $this->getPageRepository(); if (is_object($GLOBALS['TSFE'])) { if ($workspaceUid !== NULL) { $pageRepository->versioningWorkspaceId = $workspaceUid; } } else { if ($workspaceUid === NULL) { $workspaceUid = $GLOBALS['BE_USER']->workspace; } $pageRepository->versioningWorkspaceId = $workspaceUid; } // Fetches the move-placeholder in case it is supported // by the table and if there's only one row in the result set // (applying this to all rows does not work, since the sorting // order would be destroyed and possible limits not met anymore) if (!empty($pageRepository->versioningWorkspaceId) && !empty($GLOBALS['TCA'][$tableName]['ctrl']['versioningWS']) && $GLOBALS['TCA'][$tableName]['ctrl']['versioningWS'] >= 2 && count($rows) === 1) { $movePlaceholder = $this->databaseHandle->exec_SELECTgetSingleRow($tableName . '.*', $tableName, 't3ver_state=3 AND t3ver_wsid=' . $pageRepository->versioningWorkspaceId . ' AND t3ver_move_id=' . $rows[0]['uid']); if (!empty($movePlaceholder)) { $rows = array($movePlaceholder); } } $overlaidRows = array(); foreach ($rows as $row) { // If current row is a translation select its parent if (isset($tableName) && isset($GLOBALS['TCA'][$tableName]) && isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']) && !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])) { if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]) && $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) { $row = $this->databaseHandle->exec_SELECTgetSingleRow($tableName . '.*', $tableName, $tableName . '.uid=' . (int) $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] . ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0'); } } $pageRepository->versionOL($tableName, $row, TRUE); if ($tableName == 'pages') { $row = $pageRepository->getPageOverlay($row, $querySettings->getLanguageUid()); } elseif (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== '' && !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])) { if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], array(-1, 0))) { $overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : ''; $row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode); } } if ($row !== NULL && is_array($row)) { $overlaidRows[] = $row; } } return $overlaidRows; }
/** * Transforms orderings into SQL. * * @param array $orderings An array of orderings (Qom\Ordering) * @param Qom\SourceInterface $source The source * @param array &$sql The query parts * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException * @return void */ protected function parseOrderings(array $orderings, Qom\SourceInterface $source, array &$sql) { foreach ($orderings as $propertyName => $order) { switch ($order) { case Qom\QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING: case QueryInterface::ORDER_ASCENDING: $order = 'ASC'; break; case Qom\QueryObjectModelConstantsInterface::JCR_ORDER_DESCENDING: case QueryInterface::ORDER_DESCENDING: $order = 'DESC'; break; default: throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException('Unsupported order encountered.', 1242816074); } $className = ''; $tableName = ''; if ($source instanceof Qom\SelectorInterface) { $className = $source->getNodeTypeName(); $tableName = $this->dataMapper->convertClassNameToTableName($className); while (strpos($propertyName, '.') !== FALSE) { $this->addUnionStatement($className, $tableName, $propertyName, $sql); } } elseif ($source instanceof Qom\JoinInterface) { $tableName = $source->getLeft()->getSelectorName(); } $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className); if ($tableName !== '') { $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order; } else { $sql['orderings'][] = $columnName . ' ' . $order; } } }
/** * Performs workspace and language overlay on the given row array. The language and workspace id is automatically * detected (depending on FE or BE context). You can also explicitly set the language/workspace id. * * @param SourceInterface $source The source (selector od join) * @param array $row * @param QuerySettingsInterface $querySettings The TYPO3 CMS specific query settings * @return array */ protected function doLanguageAndWorkspaceOverlay(SourceInterface $source, array $row, $querySettings) { /** @var SelectorInterface $source */ $tableName = $source->getSelectorName(); $pageRepository = $this->getPageRepository(); if (is_object($GLOBALS['TSFE'])) { $languageMode = $GLOBALS['TSFE']->sys_language_mode; if ($this->isBackendUserLogged() && $this->getBackendUser()->workspace !== 0) { $pageRepository->versioningWorkspaceId = $this->getBackendUser()->workspace; } } else { $languageMode = ''; $workspaceUid = $this->getBackendUser()->workspace; $pageRepository->versioningWorkspaceId = $workspaceUid; if ($this->getBackendUser()->workspace !== 0) { $pageRepository->versioningPreview = 1; } } // If current row is a translation select its parent if (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])) { if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]) && $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) { $row = $this->databaseHandle->exec_SELECTgetSingleRow($tableName . '.*', $tableName, $tableName . '.uid=' . (int) $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] . ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0'); } } // Retrieve the original uid // @todo It looks for me this code will never be used! "_ORIG_uid" is something from extbase. Adjust me or remove me in 0.4 + 2 version! $pageRepository->versionOL($tableName, $row, TRUE); if ($pageRepository->versioningPreview && isset($row['_ORIG_uid'])) { $row['uid'] = $row['_ORIG_uid']; } // Special case for table "pages" if ($tableName == 'pages') { $row = $pageRepository->getPageOverlay($row, $querySettings->getLanguageUid()); } elseif (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== '') { if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], array(-1, 0))) { $overlayMode = $languageMode === 'strict' ? 'hideNonTranslated' : ''; $row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode); } } return $row; }
/** * Performs workspace and language overlay on the given row array. The language and workspace id is automatically * detected (depending on FE or BE context). You can also explicitly set the language/workspace id. * * @param Qom\SourceInterface $source The source (selector od join) * @param array $rows * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The TYPO3 CMS specific query settings * @param null|int $workspaceUid * @return array */ protected function doLanguageAndWorkspaceOverlay(Qom\SourceInterface $source, array $rows, \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings, $workspaceUid = null) { if ($source instanceof Qom\SelectorInterface) { $tableName = $source->getSelectorName(); } elseif ($source instanceof Qom\JoinInterface) { $tableName = $source->getRight()->getSelectorName(); } else { // No proper source, so we do not have a table name here // we cannot do an overlay and return the original rows instead. return $rows; } $pageRepository = $this->getPageRepository(); if (is_object($GLOBALS['TSFE'])) { if ($workspaceUid !== null) { $pageRepository->versioningWorkspaceId = $workspaceUid; } } else { if ($workspaceUid === null) { $workspaceUid = $GLOBALS['BE_USER']->workspace; } $pageRepository->versioningWorkspaceId = $workspaceUid; } // Fetches the move-placeholder in case it is supported // by the table and if there's only one row in the result set // (applying this to all rows does not work, since the sorting // order would be destroyed and possible limits not met anymore) if (!empty($pageRepository->versioningWorkspaceId) && BackendUtility::isTableWorkspaceEnabled($tableName) && count($rows) === 1) { $versionId = $pageRepository->versioningWorkspaceId; $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName); $queryBuilder->getRestrictions()->removeAll(); $movePlaceholder = $queryBuilder->select($tableName . '.*')->from($tableName)->where($queryBuilder->expr()->eq('t3ver_state', $queryBuilder->createNamedParameter(3, \PDO::PARAM_INT)), $queryBuilder->expr()->eq('t3ver_wsid', $queryBuilder->createNamedParameter($versionId, \PDO::PARAM_INT)), $queryBuilder->expr()->eq('t3ver_move_id', $queryBuilder->createNamedParameter($rows[0]['uid'], \PDO::PARAM_INT)))->setMaxResults(1)->execute()->fetch(); if (!empty($movePlaceholder)) { $rows = [$movePlaceholder]; } } $overlaidRows = []; foreach ($rows as $row) { // If current row is a translation select its parent if (isset($tableName) && isset($GLOBALS['TCA'][$tableName]) && isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']) && $tableName !== 'pages_language_overlay') { if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]) && $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) { $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName); $queryBuilder->getRestrictions()->removeAll(); $row = $queryBuilder->select($tableName . '.*')->from($tableName)->where($queryBuilder->expr()->eq($tableName . '.uid', $queryBuilder->createNamedParameter($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']], \PDO::PARAM_INT)), $queryBuilder->expr()->eq($tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'], $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)))->setMaxResults(1)->execute()->fetch(); } } $pageRepository->versionOL($tableName, $row, true); if ($tableName == 'pages') { $row = $pageRepository->getPageOverlay($row, $querySettings->getLanguageUid()); } elseif (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== '' && $tableName !== 'pages_language_overlay') { if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], [-1, 0])) { $overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : ''; $row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode); } } if ($row !== null && is_array($row)) { $overlaidRows[] = $row; } } return $overlaidRows; }
/** * Performs workspace and language overlay on the given row array. The language and workspace id is automatically * detected (depending on FE or BE context). You can also explicitly set the language/workspace id. * * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source The source (selector od join) * @param array $rows * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The TYPO3 CMS specific query settings * @param null|integer $workspaceUid * @return array */ protected function doLanguageAndWorkspaceOverlay(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source, array $rows, \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings, $workspaceUid = NULL) { if ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) { $tableName = $source->getSelectorName(); } elseif ($source instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface) { $tableName = $source->getRight()->getSelectorName(); } else { // No proper source, so we do not have a table name here // we cannot do an overlay and return the original rows instead. return $rows; } $pageRepository = $this->getPageRepository(); if (is_object($GLOBALS['TSFE'])) { if ($workspaceUid !== NULL) { $pageRepository->versioningWorkspaceId = $workspaceUid; } } else { if ($workspaceUid === NULL) { $workspaceUid = $GLOBALS['BE_USER']->workspace; } $pageRepository->versioningWorkspaceId = $workspaceUid; } $overlaidRows = array(); foreach ($rows as $row) { // If current row is a translation select its parent if (isset($tableName) && isset($GLOBALS['TCA'][$tableName]) && isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']) && !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])) { if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]) && $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) { $row = $this->databaseHandle->exec_SELECTgetSingleRow($tableName . '.*', $tableName, $tableName . '.uid=' . (int) $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] . ' AND ' . $tableName . '.' . $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] . '=0'); } } $pageRepository->versionOL($tableName, $row, TRUE); if ($pageRepository->versioningPreview && isset($row['_ORIG_uid'])) { $row['uid'] = $row['_ORIG_uid']; } if ($tableName == 'pages') { $row = $pageRepository->getPageOverlay($row, $querySettings->getLanguageUid()); } elseif (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField']) && $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== '' && !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])) { if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], array(-1, 0))) { $overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : ''; $row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode); } } if ($row !== NULL && is_array($row)) { $overlaidRows[] = $row; } } return $overlaidRows; }
/** * Parse a Comparison into SQL and parameter arrays. * * @param Qom\ComparisonInterface $comparison The comparison to parse * @param Qom\SourceInterface $source The source * @throws \RuntimeException * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException * @return string */ protected function parseComparison(Qom\ComparisonInterface $comparison, Qom\SourceInterface $source) { if ($comparison->getOperator() === QueryInterface::OPERATOR_CONTAINS) { if ($comparison->getOperand2() === null) { return '1<>1'; } else { $value = $this->dataMapper->getPlainValue($comparison->getOperand2()); if (!$source instanceof Qom\SelectorInterface) { throw new \RuntimeException('Source is not of type "SelectorInterface"', 1395362539); } $className = $source->getNodeTypeName(); $tableName = $this->dataMapper->convertClassNameToTableName($className); $operand1 = $comparison->getOperand1(); $propertyName = $operand1->getPropertyName(); $fullPropertyPath = ''; while (strpos($propertyName, '.') !== false) { $this->addUnionStatement($className, $tableName, $propertyName, $fullPropertyPath); } $columnName = $this->dataMapper->convertPropertyNameToColumnName($propertyName, $className); $dataMap = $this->dataMapper->getDataMap($className); $columnMap = $dataMap->getColumnMap($propertyName); $typeOfRelation = $columnMap instanceof ColumnMap ? $columnMap->getTypeOfRelation() : null; if ($typeOfRelation === ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY) { $relationTableName = $columnMap->getRelationTableName(); $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder(); $queryBuilderForSubselect->select($columnMap->getParentKeyFieldName())->from($relationTableName)->where($queryBuilderForSubselect->expr()->eq($columnMap->getChildKeyFieldName(), $this->queryBuilder->createNamedParameter($value))); $additionalWhereForMatchFields = $this->getAdditionalMatchFieldsStatement($queryBuilderForSubselect->expr(), $columnMap, $relationTableName, $relationTableName); if ($additionalWhereForMatchFields) { $queryBuilderForSubselect->andWhere($additionalWhereForMatchFields); } return $this->queryBuilder->expr()->comparison($this->queryBuilder->quoteIdentifier($tableName . '.uid'), 'IN', '(' . $queryBuilderForSubselect->getSQL() . ')'); } elseif ($typeOfRelation === ColumnMap::RELATION_HAS_MANY) { $parentKeyFieldName = $columnMap->getParentKeyFieldName(); if (isset($parentKeyFieldName)) { $childTableName = $columnMap->getChildTableName(); // Build the SQL statement of the subselect $queryBuilderForSubselect = $this->queryBuilder->getConnection()->createQueryBuilder(); $queryBuilderForSubselect->select($parentKeyFieldName)->from($childTableName)->where($queryBuilderForSubselect->expr()->eq('uid', (int) $value)); // Add it to the main query return $this->queryBuilder->expr()->eq($tableName . '.uid', $queryBuilderForSubselect->getSQL()); } else { return $this->queryBuilder->expr()->inSet($tableName . '.' . $columnName, $this->queryBuilder->createNamedParameter($value)); } } else { throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745); } } } else { return $this->parseDynamicOperand($comparison, $source); } }