Created
August 14, 2017 14:11
-
-
Save anonymous/7e307e73e6842fd6d94f28ba62ab2a7d to your computer and use it in GitHub Desktop.
Typo3 Abstract Item Provider workaround
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
abstract class AbstractItemProvider | |
{ | |
/** | |
* Replace markers in a where clause from TCA foreign_table_where | |
* | |
* ###REC_FIELD_[field name]### | |
* ###THIS_UID### - is current element uid (zero if new). | |
* ###CURRENT_PID### - is the current page id (pid of the record). | |
* ###SITEROOT### | |
* ###PAGE_TSCONFIG_ID### - a value you can set from Page TSconfig dynamically. | |
* ###PAGE_TSCONFIG_IDLIST### - a value you can set from Page TSconfig dynamically. | |
* ###PAGE_TSCONFIG_STR### - a value you can set from Page TSconfig dynamically. | |
* | |
* @param array $result Result array | |
* @param string $foreignTableName Name of foreign table | |
* @param string $localFieldName Current handle field name | |
* @return array Query parts with keys WHERE, ORDERBY, GROUPBY, LIMIT | |
*/ | |
protected function processForeignTableClause(array $result, $foreignTableName, $localFieldName) | |
{ | |
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($foreignTableName); | |
$localTable = $result['tableName']; | |
$effectivePid = $result['effectivePid']; | |
$foreignTableClause = ''; | |
if (!empty($result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where']) | |
&& is_string($result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where']) | |
) { | |
$foreignTableClause = $result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where']; | |
// Replace possible markers in query | |
if (strstr($foreignTableClause, '###REC_FIELD_')) { | |
// " AND table.field='###REC_FIELD_field1###' AND ..." -> array(" AND table.field='", "field1###' AND ...") | |
$whereClauseParts = explode('###REC_FIELD_', $foreignTableClause); | |
foreach ($whereClauseParts as $key => $value) { | |
if ($key !== 0) { | |
// "field1###' AND ..." -> array("field1", "' AND ...") | |
$whereClauseSubParts = explode('###', $value, 2); | |
// @todo: Throw exception if there is no value? What happens for NEW records? | |
$databaseRowKey = empty($result['flexParentDatabaseRow']) ? 'databaseRow' : 'flexParentDatabaseRow'; | |
$rowFieldValue = isset($result[$databaseRowKey][$whereClauseSubParts[0]]) ? $result[$databaseRowKey][$whereClauseSubParts[0]] : ''; | |
if (is_array($rowFieldValue)) { | |
// If a select or group field is used here, it may have been processed already and | |
// is now an array. Use first selected value in this case. | |
$rowFieldValue = $rowFieldValue[0]; | |
} | |
if (substr($whereClauseParts[0], -1) === '\'' && $whereClauseSubParts[1][0] === '\'') { | |
$whereClauseParts[0] = substr($whereClauseParts[0], 0, -1); | |
$whereClauseSubParts[1] = substr($whereClauseSubParts[1], 1); | |
} | |
$whereClauseParts[$key] = $connection->quote($rowFieldValue) . $whereClauseSubParts[1]; | |
} | |
} | |
$foreignTableClause = implode('', $whereClauseParts); | |
} | |
if (strpos($foreignTableClause, '###CURRENT_PID###') !== false) { | |
// Use pid from parent page clause if in flex form context | |
if (!empty($result['flexParentDatabaseRow']['pid'])) { | |
$effectivePid = $result['flexParentDatabaseRow']['pid']; | |
// Use pid from database row if in inline context | |
} elseif (!$effectivePid && !empty($result['databaseRow']['pid'])) { | |
$effectivePid = $result['databaseRow']['pid']; | |
} | |
} | |
$siteRootUid = 0; | |
foreach ($result['rootline'] as $rootlinePage) { | |
if (!empty($rootlinePage['is_siteroot'])) { | |
$siteRootUid = (int)$rootlinePage['uid']; | |
break; | |
} | |
} | |
$pageTsConfigId = 0; | |
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID']) { | |
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess | |
$pageTsConfigId = (int)$result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID']; | |
} | |
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']) { | |
$pageTsConfigId = (int)$result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']; | |
} | |
$pageTsConfigIdList = 0; | |
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST']) { | |
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess | |
$pageTsConfigIdList = $result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST']; | |
} | |
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']) { | |
$pageTsConfigIdList = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']; | |
} | |
$pageTsConfigIdListArray = GeneralUtility::trimExplode(',', $pageTsConfigIdList, true); | |
$pageTsConfigIdList = []; | |
foreach ($pageTsConfigIdListArray as $pageTsConfigIdListElement) { | |
if (MathUtility::canBeInterpretedAsInteger($pageTsConfigIdListElement)) { | |
$pageTsConfigIdList[] = (int)$pageTsConfigIdListElement; | |
} | |
} | |
$pageTsConfigIdList = implode(',', $pageTsConfigIdList); | |
$pageTsConfigString = ''; | |
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR']) { | |
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess | |
$pageTsConfigString = $connection->quote($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR']); | |
} | |
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']) { | |
$pageTsConfigString = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']; | |
$pageTsConfigString = $connection->quote($pageTsConfigString); | |
} | |
$foreignTableClause = str_replace( | |
[ | |
'###CURRENT_PID###', | |
'###THIS_UID###', | |
'###SITEROOT###', | |
'###PAGE_TSCONFIG_ID###', | |
'###PAGE_TSCONFIG_IDLIST###', | |
'\'###PAGE_TSCONFIG_STR###\'', | |
'###PAGE_TSCONFIG_STR###' | |
], | |
[ | |
(int)$effectivePid, | |
(int)$result['databaseRow']['uid'], | |
$siteRootUid, | |
$pageTsConfigId, | |
$pageTsConfigIdList, | |
$pageTsConfigString, | |
$pageTsConfigString | |
], | |
$foreignTableClause | |
); | |
} | |
if (!empty($result['processedTca']['columns'][$localFieldName]['config']['foreign_table_where']) && | |
!empty($result['isInlineChild']) && | |
!empty($result['inlineParentConfig']['foreign_table']) && | |
!empty($result['inlineParentConfig']['foreign_field']) && | |
!empty($result['inlineParentUid']) | |
) { | |
$parentUid = $result['inlineParentUid']; | |
$foreignTable = $result['inlineParentConfig']['foreign_table']; | |
$foreignField = $result['inlineParentConfig']['foreign_field']; | |
$foreignTableClause .= ' AND (' . $foreignTable . '.'.$foreignField . '=' .$parentUid.')'; | |
} | |
// Split the clause into an array with keys WHERE, GROUPBY, ORDERBY, LIMIT | |
// Prepend a space to make sure "[[:space:]]+" will find a space there for the first element. | |
$foreignTableClause = ' ' . $foreignTableClause; | |
$foreignTableClauseArray = [ | |
'WHERE' => '', | |
'GROUPBY' => '', | |
'ORDERBY' => '', | |
'LIMIT' => '', | |
]; | |
// Find LIMIT | |
$reg = []; | |
if (preg_match('/^(.*)[[:space:]]+LIMIT[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) { | |
$foreignTableClauseArray['LIMIT'] = GeneralUtility::intExplode(',', trim($reg[2]), true); | |
$foreignTableClause = $reg[1]; | |
} | |
// Find ORDER BY | |
$reg = []; | |
if (preg_match('/^(.*)[[:space:]]+ORDER[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) { | |
$foreignTableClauseArray['ORDERBY'] = QueryHelper::parseOrderBy(trim($reg[2])); | |
$foreignTableClause = $reg[1]; | |
} | |
// Find GROUP BY | |
$reg = []; | |
if (preg_match('/^(.*)[[:space:]]+GROUP[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i', $foreignTableClause, $reg)) { | |
$foreignTableClauseArray['GROUPBY'] = QueryHelper::parseGroupBy(trim($reg[2])); | |
$foreignTableClause = $reg[1]; | |
} | |
// Rest is assumed to be "WHERE" clause | |
$foreignTableClauseArray['WHERE'] = QueryHelper::stripLogicalOperatorPrefix($foreignTableClause); | |
return $foreignTableClauseArray; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment