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];