From bba4857d643ce1b44a165ba861f2100a9a7b3e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20B=C3=BClter?= Date: Fri, 27 Sep 2024 13:08:23 +0200 Subject: [PATCH] [TASK] Migrate database queries Includes removing of the getTableFields() method in FilterOptionRepository.php. The method getSchemaManager() is not available anymore and getTableFields() was only used to check if the database columns do actually exist in the filter option table. That's not necessary, at least in ke_search itself. Third-party extensions which use the create() function should check the fields by themselves. --- ChangeLog | 1 + .../Controller/BackendModuleController.php | 75 ++++++++++++------- .../Repository/FilterOptionRepository.php | 37 ++------- Classes/Indexer/IndexerBase.php | 2 + Classes/Indexer/IndexerRunner.php | 56 +++++++------- 5 files changed, 84 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96c2c157..4e955842 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Upcoming version for TYPO3 13 [TASK] Migrate database queries to use type constants from Connection instead of PDO, https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Database/QueryBuilder/Index.html#database-query-builder-create-named-parameter [TASK] Remove obsolete code for TYPO3 11 and below [TASK] Migrate FlexfForm definition +[TASK] Migrate database queries Version 5.5.2, 23 August 2024 [BUGFIX] Fix cropping if "resultChars" is empty. Thanks to Andreas Kießling. https://github.com/tpwd/ke_search/issues/242 diff --git a/Classes/Controller/BackendModuleController.php b/Classes/Controller/BackendModuleController.php index 0911f1d4..d31c57a8 100644 --- a/Classes/Controller/BackendModuleController.php +++ b/Classes/Controller/BackendModuleController.php @@ -37,6 +37,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Database\Connection; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Pagination\ArrayPaginator; use TYPO3\CMS\Core\Pagination\SlidingWindowPagination; @@ -575,7 +576,7 @@ public function getSearchwordStatistics($pageUid, $days) $isSysFolder = $this->checkSysfolder(); // set folder or single page where the data is selected from - $pidWhere = $isSysFolder ? ' AND pid=' . (int)$pageUid . ' ' : ' AND pageid=' . (int)$pageUid . ' '; + $isSysFolder ? $pageColumn = 'pid' : $pageColumn = 'pageid'; // get languages $queryBuilder = Db::getQueryBuilder('tx_kesearch_stat_word'); @@ -597,7 +598,6 @@ public function getSearchwordStatistics($pageUid, $days) ->executeQuery() ->fetchAllAssociative(); - $content = ''; if (!count($languageResult)) { $statisticData['error'] = 'No statistic data found! Please select the sysfolder @@ -611,7 +611,8 @@ public function getSearchwordStatistics($pageUid, $days) 'tx_kesearch_stat_search', $languageRow['language'], $timestampStart, - $pidWhere, + $pageColumn, + $pageUid, 'searchphrase' ); } else { @@ -622,7 +623,8 @@ public function getSearchwordStatistics($pageUid, $days) 'tx_kesearch_stat_word', $languageRow['language'], $timestampStart, - $pidWhere, + $pageColumn, + $pageUid, 'word' ); } @@ -630,33 +632,48 @@ public function getSearchwordStatistics($pageUid, $days) return $statisticData; } - /** - * @param string $table - * @param int $language - * @param int $timestampStart - * @param string $pidWhere - * @param string $tableCol - */ - public function getStatisticTableData($table, $language, $timestampStart, $pidWhere, $tableCol) + public function getStatisticTableData( + string $table, + int $language, + int $timestampStart, + string $pageColumn, + int $pageUid, + string $tableCol + ): array { - // get statistic data from db $queryBuilder = Db::getQueryBuilder($table); $queryBuilder->getRestrictions()->removeAll(); - $statisticData = $queryBuilder - ->add('select', 'count(' . $tableCol . ') as num, ' . $tableCol) - ->from($table) - ->add( - 'where', - 'tstamp > ' . $queryBuilder->quote($timestampStart, \PDO::PARAM_INT) . - ' AND language=' . $queryBuilder->quote($language, \PDO::PARAM_INT) . ' ' . - $pidWhere - ) - ->add('groupBy', $tableCol . ' HAVING count(' . $tableCol . ')>0') - ->add('orderBy', 'num desc') - ->executeQuery() - ->fetchAllAssociative(); + if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 13) { + $pidWhere = ' AND ' . $pageColumn . '=' . $pageUid; + // @phpstan-ignore-next-line + $query = $queryBuilder + ->add('select', 'count(' . $tableCol . ') as num, ' . $tableCol) + ->from($table) + ->add( + 'where', + // @phpstan-ignore-next-line + 'tstamp > ' . $queryBuilder->quote($timestampStart, \PDO::PARAM_INT) . + // @phpstan-ignore-next-line + ' AND language=' . $queryBuilder->quote($language, \PDO::PARAM_INT) . ' ' . + $pidWhere + ) + ->add('groupBy', $tableCol . ' HAVING count(' . $tableCol . ')>0') + ->add('orderBy', 'num desc'); + } else { + $query = $queryBuilder + ->selectLiteral('count(' . $tableCol . ') as num, ' . $tableCol) + ->from($table) + ->where( + $queryBuilder->expr()->gt('tstamp', $queryBuilder->createNamedParameter($timestampStart, Connection::PARAM_INT)), + $queryBuilder->expr()->eq('language', $queryBuilder->createNamedParameter($language, Connection::PARAM_INT)), + $queryBuilder->expr()->eq($pageColumn, $queryBuilder->createNamedParameter($pageUid, Connection::PARAM_INT)) + ) + ->groupBy($tableCol) + ->having('count(' . $tableCol . ')>0') + ->orderBy('num', 'desc'); + } - return $statisticData; + return $query->executeQuery()->fetchAllAssociative(); } /* @@ -664,7 +681,7 @@ public function getStatisticTableData($table, $language, $timestampStart, $pidWh * * @return boolean */ - public function checkSysfolder() + public function checkSysfolder(): bool { $queryBuilder = Db::getQueryBuilder('pages'); $page = $queryBuilder @@ -680,7 +697,7 @@ public function checkSysfolder() ->executeQuery() ->fetchAssociative(); - return $page['doktype'] == 254 ? true : false; + return $page['doktype'] == 254; } /** diff --git a/Classes/Domain/Repository/FilterOptionRepository.php b/Classes/Domain/Repository/FilterOptionRepository.php index 93a50692..ec70ed0e 100644 --- a/Classes/Domain/Repository/FilterOptionRepository.php +++ b/Classes/Domain/Repository/FilterOptionRepository.php @@ -7,6 +7,7 @@ use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\GeneralUtility; /*************************************************************** @@ -32,23 +33,11 @@ */ class FilterOptionRepository extends BaseRepository { - /** - * Internal storage for database table fields - * - * @var array - */ - protected $tableFields = []; - /** * @var string */ protected $tableName = 'tx_kesearch_filteroptions'; - /** - * @var string - */ - protected $parentTableName = 'tx_kesearch_filters'; - /** * @param string $tagPrefix * @param bool $includeHiddenAndTimeRestricted @@ -248,7 +237,6 @@ public function create(int $filterUid, array $additionalFields = []) 'cruser_id' => isset($GLOBALS['BE_USER']->user['uid']) ? (int)$GLOBALS['BE_USER']->user['uid'] : 0, 'l10n_diffsource' => '', ]; - $additionalFields = array_intersect_key($additionalFields, $this->getTableFields()); $newRecord = array_merge($newRecord, $additionalFields); $connection = GeneralUtility::makeInstance(ConnectionPool::class) ->getConnectionForTable($this->tableName); @@ -258,7 +246,12 @@ public function create(int $filterUid, array $additionalFields = []) ['l10n_diffsource' => Connection::PARAM_LOB] ); $record = $newRecord; - $record['uid'] = (int)$connection->lastInsertId($this->tableName); + if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 13) { + // @phpstan-ignore-next-line + $record['uid'] = (int)$connection->lastInsertId($this->tableName); + } else { + $record['uid'] = (int)$connection->lastInsertId(); + } // Create slug $this->update($record['uid'], ['slug' => SearchHelper::createFilterOptionSlug($record)]); @@ -314,22 +307,6 @@ public function deleteByTag(string $tag) } } - /** - * Gets the fields that are available in the table - * - * @return array - */ - protected function getTableFields(): array - { - if (empty($this->tableFields)) { - $this->tableFields = GeneralUtility::makeInstance(ConnectionPool::class) - ->getConnectionForTable($this->tableName) - ->getSchemaManager() - ->listTableColumns($this->tableName); - } - return $this->tableFields; - } - /** * @param int $uid * @param array $updateFields diff --git a/Classes/Indexer/IndexerBase.php b/Classes/Indexer/IndexerBase.php index fb37c1eb..6f4780ae 100644 --- a/Classes/Indexer/IndexerBase.php +++ b/Classes/Indexer/IndexerBase.php @@ -261,10 +261,12 @@ public function addTagsToRecords($uids, $pageWhere = '') $where .= ' AND FIND_IN_SET(tx_kesearch_filteroptions.uid, pages.tx_kesearch_tags)'; if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 13) { + // @phpstan-ignore-next-line $tagQuery = $queryBuilder ->add('select', $fields) ->from('pages') ->from('tx_kesearch_filteroptions') + // @phpstan-ignore-next-line ->add('where', $where) ->groupBy('pages.uid') ->executeQuery(); diff --git a/Classes/Indexer/IndexerRunner.php b/Classes/Indexer/IndexerRunner.php index af740fe4..d8d05fb8 100644 --- a/Classes/Indexer/IndexerRunner.php +++ b/Classes/Indexer/IndexerRunner.php @@ -853,20 +853,20 @@ public function insertRecordIntoIndex($fieldValues, bool $debugOnly = false) $queryArray = []; $queryArray['set'] = 'SET - @pid = ' . $queryBuilder->quote($fieldValues['pid'], PDO::PARAM_INT) . ', - @title = ' . $queryBuilder->quote($fieldValues['title'], PDO::PARAM_STR) . ', - @type = ' . $queryBuilder->quote($fieldValues['type'], PDO::PARAM_STR) . ', - @targetpid = ' . $queryBuilder->quote($fieldValues['targetpid']) . ', - @content = ' . $queryBuilder->quote($fieldValues['content'], PDO::PARAM_STR) . ', - @tags = ' . $queryBuilder->quote($fieldValues['tags'], PDO::PARAM_STR) . ', - @params = ' . $queryBuilder->quote($fieldValues['params'], PDO::PARAM_STR) . ', - @abstract = ' . $queryBuilder->quote($fieldValues['abstract'], PDO::PARAM_STR) . ', - @language = ' . $queryBuilder->quote($fieldValues['language'], PDO::PARAM_INT) . ', - @starttime = ' . $queryBuilder->quote($fieldValues['starttime'], PDO::PARAM_INT) . ', - @endtime = ' . $queryBuilder->quote($fieldValues['endtime'], PDO::PARAM_INT) . ', - @fe_group = ' . $queryBuilder->quote($fieldValues['fe_group'], PDO::PARAM_INT) . ', - @tstamp = ' . $queryBuilder->quote($fieldValues['tstamp'], PDO::PARAM_INT) . ', - @crdate = ' . $queryBuilder->quote($fieldValues['crdate'], PDO::PARAM_INT) + @pid = ' . $queryBuilder->quote((string)$fieldValues['pid']) . ', + @title = ' . $queryBuilder->quote((string)$fieldValues['title']) . ', + @type = ' . $queryBuilder->quote((string)$fieldValues['type']) . ', + @targetpid = ' . $queryBuilder->quote((string)$fieldValues['targetpid']) . ', + @content = ' . $queryBuilder->quote((string)$fieldValues['content']) . ', + @tags = ' . $queryBuilder->quote((string)$fieldValues['tags']) . ', + @params = ' . $queryBuilder->quote((string)$fieldValues['params']) . ', + @abstract = ' . $queryBuilder->quote((string)$fieldValues['abstract']) . ', + @language = ' . $queryBuilder->quote((string)$fieldValues['language']) . ', + @starttime = ' . $queryBuilder->quote((string)$fieldValues['starttime']) . ', + @endtime = ' . $queryBuilder->quote((string)$fieldValues['endtime']) . ', + @fe_group = ' . $queryBuilder->quote((string)$fieldValues['fe_group']) . ', + @tstamp = ' . $queryBuilder->quote((string)$fieldValues['tstamp']) . ', + @crdate = ' . $queryBuilder->quote((string)$fieldValues['crdate']) . $addQueryPartFor['set'] . ' ;'; @@ -914,19 +914,19 @@ public function updateRecordInIndex($fieldValues, bool $debugOnly = false) $queryArray = []; $queryArray['set'] = 'SET - @pid = ' . $queryBuilder->quote($fieldValues['pid'], PDO::PARAM_INT) . ', - @title = ' . $queryBuilder->quote($fieldValues['title'], PDO::PARAM_STR) . ', - @type = ' . $queryBuilder->quote($fieldValues['type'], PDO::PARAM_STR) . ', - @targetpid = ' . $queryBuilder->quote($fieldValues['targetpid']) . ', - @content = ' . $queryBuilder->quote($fieldValues['content'], PDO::PARAM_STR) . ', - @tags = ' . $queryBuilder->quote($fieldValues['tags'], PDO::PARAM_STR) . ', - @params = ' . $queryBuilder->quote($fieldValues['params'], PDO::PARAM_STR) . ', - @abstract = ' . $queryBuilder->quote($fieldValues['abstract'], PDO::PARAM_STR) . ', - @language = ' . $queryBuilder->quote($fieldValues['language'], PDO::PARAM_INT) . ', - @starttime = ' . $queryBuilder->quote($fieldValues['starttime'], PDO::PARAM_INT) . ', - @endtime = ' . $queryBuilder->quote($fieldValues['endtime'], PDO::PARAM_INT) . ', - @fe_group = ' . $queryBuilder->quote($fieldValues['fe_group'], PDO::PARAM_INT) . ', - @tstamp = ' . $queryBuilder->quote($fieldValues['tstamp'], PDO::PARAM_INT) . + @pid = ' . $queryBuilder->quote((string)$fieldValues['pid']) . ', + @title = ' . $queryBuilder->quote((string)$fieldValues['title']) . ', + @type = ' . $queryBuilder->quote((string)$fieldValues['type']) . ', + @targetpid = ' . $queryBuilder->quote((string)$fieldValues['targetpid']) . ', + @content = ' . $queryBuilder->quote((string)$fieldValues['content']) . ', + @tags = ' . $queryBuilder->quote((string)$fieldValues['tags']) . ', + @params = ' . $queryBuilder->quote((string)$fieldValues['params']) . ', + @abstract = ' . $queryBuilder->quote((string)$fieldValues['abstract']) . ', + @language = ' . $queryBuilder->quote((string)$fieldValues['language']) . ', + @starttime = ' . $queryBuilder->quote((string)$fieldValues['starttime']) . ', + @endtime = ' . $queryBuilder->quote((string)$fieldValues['endtime']) . ', + @fe_group = ' . $queryBuilder->quote((string)$fieldValues['fe_group']) . ', + @tstamp = ' . $queryBuilder->quote((string)$fieldValues['tstamp']) . $addQueryPartFor['set'] . ', @uid = ' . $this->currentRow['uid'] . ' '; @@ -973,7 +973,7 @@ public function getQueryPartForAdditionalFields(array $fieldValues) $queryBuilder = Db::getQueryBuilder('tx_kesearch_index'); foreach ($this->additionalFields as $value) { - $queryForSet .= ', @' . $value . ' = ' . $queryBuilder->quote($fieldValues[$value], PDO::PARAM_STR); + $queryForSet .= ', @' . $value . ' = ' . $queryBuilder->quote((string)$fieldValues[$value]); $queryForExecute .= ', @' . $value; } return ['set' => $queryForSet, 'execute' => $queryForExecute];