diff --git a/.gitignore b/.gitignore index f6db3ceb..3403a5d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -composer.lock -.Build +/composer.lock +/.Build +/var/ diff --git a/.travis.yml b/.travis.yml index 7e83e4dc..bf0024e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,9 +7,8 @@ before_install: language: php php: - - 7.0 - - 7.1 - 7.2 + - 7.3 env: global: @@ -22,8 +21,7 @@ env: - typo3DatabaseUsername="travis" - typo3DatabasePassword="" matrix: - - TYPO3_VERSION="~7.6" - - TYPO3_VERSION="~8.7" + - TYPO3_VERSION="^9.5" matrix: fast_finish: true diff --git a/Classes/Compatibility/ImplementationRegistrationService.php b/Classes/Compatibility/ImplementationRegistrationService.php deleted file mode 100644 index fa3faa83..00000000 --- a/Classes/Compatibility/ImplementationRegistrationService.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\VersionNumberUtility; -use TYPO3\CMS\Extbase\Object\Container\Container; - -/** - * Register different concrete implementations, depending on current TYPO3 version. - * This way we can provide working implementations for multiple TYPO3 versions. - */ -class ImplementationRegistrationService -{ - public static function registerImplementations() - { - $container = GeneralUtility::makeInstance(Container::class); - if (VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version) >= 8000000) { - $container->registerImplementation( - \Codappix\SearchCore\Compatibility\TypoScriptServiceInterface::class, - \Codappix\SearchCore\Compatibility\TypoScriptService::class - ); - $container->registerImplementation( - \Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableServiceInterface::class, - \Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService::class - ); - } else { - $container->registerImplementation( - \Codappix\SearchCore\Compatibility\TypoScriptServiceInterface::class, - \Codappix\SearchCore\Compatibility\TypoScriptService76::class - ); - $container->registerImplementation( - \Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableServiceInterface::class, - \Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService76::class - ); - } - } -} diff --git a/Classes/Compatibility/TypoScriptService.php b/Classes/Compatibility/TypoScriptService.php deleted file mode 100644 index e5aa7886..00000000 --- a/Classes/Compatibility/TypoScriptService.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -use TYPO3\CMS\Core\TypoScript\TypoScriptService as CoreTypoScriptService; - -/** - * Used since TYPO3 CMS 8.7. - */ -class TypoScriptService extends CoreTypoScriptService implements TypoScriptServiceInterface -{ - -} diff --git a/Classes/Compatibility/TypoScriptService76.php b/Classes/Compatibility/TypoScriptService76.php deleted file mode 100644 index 9df82ea4..00000000 --- a/Classes/Compatibility/TypoScriptService76.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -use TYPO3\CMS\Extbase\Service\TypoScriptService as CoreTypoScriptService; - -/** - * Used before TYPO3 CMS 8.7. - */ -class TypoScriptService76 extends CoreTypoScriptService implements TypoScriptServiceInterface -{ - -} diff --git a/Classes/Compatibility/TypoScriptServiceInterface.php b/Classes/Compatibility/TypoScriptServiceInterface.php deleted file mode 100644 index 8e6a9e46..00000000 --- a/Classes/Compatibility/TypoScriptServiceInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * Allows to use DI configuration to switch concrete implementation, depending - * on current TYPO3 Version. - */ -interface TypoScriptServiceInterface -{ - public function convertPlainArrayToTypoScriptArray(array $plainArray); -} diff --git a/Classes/Configuration/ConfigurationContainer.php b/Classes/Configuration/ConfigurationContainer.php index 88aa414d..e662e215 100644 --- a/Classes/Configuration/ConfigurationContainer.php +++ b/Classes/Configuration/ConfigurationContainer.php @@ -21,7 +21,7 @@ */ use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; -use TYPO3\CMS\Extbase\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\ArrayUtility; /** * Container of all configurations for extension. @@ -59,7 +59,11 @@ public function injectConfigurationManager(ConfigurationManagerInterface $config */ public function get(string $path) { - $value = ArrayUtility::getValueByPath($this->settings, $path); + try { + $value = ArrayUtility::getValueByPath($this->settings, $path, '.'); + } catch (\Exception $e) { + $value = null; + } if ($value === null) { throw new InvalidArgumentException( @@ -77,6 +81,10 @@ public function get(string $path) */ public function getIfExists(string $path) { - return ArrayUtility::getValueByPath($this->settings, $path); + try { + return ArrayUtility::getValueByPath($this->settings, $path, '.'); + } catch (\Exception $exception) { + return null; + } } } diff --git a/Classes/Connection/SearchRequestInterface.php b/Classes/Connection/SearchRequestInterface.php index a4004472..7249593b 100644 --- a/Classes/Connection/SearchRequestInterface.php +++ b/Classes/Connection/SearchRequestInterface.php @@ -23,9 +23,9 @@ use Codappix\SearchCore\Connection\ConnectionInterface; use Codappix\SearchCore\Connection\FacetRequestInterface; use Codappix\SearchCore\Domain\Search\SearchService; -use TYPO3\CMS\Extbase\Persistence\QueryInterface; +use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; -interface SearchRequestInterface extends QueryInterface +interface SearchRequestInterface extends QueryResultInterface { /** * Returns the actual string the user searched for. @@ -48,6 +48,14 @@ public function addFacet(FacetRequestInterface $facet); */ public function getFacets() : array; + public function setLimit(int $limit); + + public function setOffset(int $offset); + + public function getLimit() : int; + + public function getOffset() : int; + /** * Workaround for paginate widget support which will * use the request to build another search. diff --git a/Classes/DataProcessing/ContentObjectDataProcessorAdapterProcessor.php b/Classes/DataProcessing/ContentObjectDataProcessorAdapterProcessor.php index 2b7f5539..711f1475 100644 --- a/Classes/DataProcessing/ContentObjectDataProcessorAdapterProcessor.php +++ b/Classes/DataProcessing/ContentObjectDataProcessorAdapterProcessor.php @@ -20,7 +20,7 @@ * 02110-1301, USA. */ -use Codappix\SearchCore\Compatibility\TypoScriptServiceInterface; +use TYPO3\CMS\Core\TypoScript\TypoScriptService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -30,11 +30,11 @@ class ContentObjectDataProcessorAdapterProcessor implements ProcessorInterface { /** - * @var TypoScriptServiceInterface + * @var TypoScriptService */ protected $typoScriptService; - public function __construct(TypoScriptServiceInterface $typoScriptService) + public function __construct(TypoScriptService $typoScriptService) { $this->typoScriptService = $typoScriptService; } diff --git a/Classes/DataProcessing/GeoPointProcessor.php b/Classes/DataProcessing/GeoPointProcessor.php index 971e2c47..8eb55f4c 100644 --- a/Classes/DataProcessing/GeoPointProcessor.php +++ b/Classes/DataProcessing/GeoPointProcessor.php @@ -41,6 +41,9 @@ public function processData(array $record, array $configuration) : array protected function isApplyable(array $record, array $configuration) : bool { + if (!isset($configuration['lat']) || !isset($configuration['lon'])) { + return false; + } if (!isset($record[$configuration['lat']]) || !is_numeric($record[$configuration['lat']]) || trim($record[$configuration['lat']]) === '' diff --git a/Classes/Domain/Index/TcaIndexer/TcaTableService.php b/Classes/Domain/Index/TcaIndexer/TcaTableService.php index 1330e228..4c029a9d 100644 --- a/Classes/Domain/Index/TcaIndexer/TcaTableService.php +++ b/Classes/Domain/Index/TcaIndexer/TcaTableService.php @@ -31,6 +31,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\RootlineUtility; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; +use TYPO3\CMS\Frontend\Page\PageRepository; /** * Encapsulate logik related to TCA configuration. @@ -324,6 +325,18 @@ protected function isRecordBlacklistedByRootline(array &$record) : bool return true; } + if ($pageInRootLine['doktype'] === PageRepository::DOKTYPE_RECYCLER) { + $this->logger->info( + sprintf( + 'Record %u is black listed due to being within recycler page %u.', + $record['uid'], + $pageInRootLine['uid'] + ), + [$record, $pageInRootLine] + ); + return true; + } + if ($pageInRootLine['extendToSubpages'] && ( ($pageInRootLine['endtime'] > 0 && $pageInRootLine['endtime'] <= time()) || ($pageInRootLine['starttime'] > 0 && $pageInRootLine['starttime'] >= time()) diff --git a/Classes/Domain/Index/TcaIndexer/TcaTableService76.php b/Classes/Domain/Index/TcaIndexer/TcaTableService76.php deleted file mode 100644 index 4445d6d0..00000000 --- a/Classes/Domain/Index/TcaIndexer/TcaTableService76.php +++ /dev/null @@ -1,378 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; -use Codappix\SearchCore\Domain\Index\IndexingException; -use Codappix\SearchCore\Domain\Index\TcaIndexer\InvalidArgumentException; -use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\RootlineUtility; -use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; - -/** - * Encapsulate logik related to TCA configuration. - */ -class TcaTableService76 implements TcaTableServiceInterface -{ - /** - * TCA for current table. - * !REFERENCE! To save memory. - * @var array - */ - protected $tca; - - /** - * @var string - */ - protected $tableName; - - /** - * @var ConfigurationContainerInterface - */ - protected $configuration; - - /** - * @var \TYPO3\CMS\Core\Log\Logger - */ - protected $logger; - - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * Inject log manager to get concrete logger from it. - * - * @param \TYPO3\CMS\Core\Log\LogManager $logManager - */ - public function injectLogger(\TYPO3\CMS\Core\Log\LogManager $logManager) - { - $this->logger = $logManager->getLogger(__CLASS__); - } - - /** - * @param ObjectManagerInterface $objectManager - */ - public function injectObjectManager(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * @param string $tableName - * @param ConfigurationContainerInterface $configuration - */ - public function __construct( - $tableName, - ConfigurationContainerInterface $configuration - ) { - if (!isset($GLOBALS['TCA'][$tableName])) { - throw new IndexingException( - 'Table "' . $tableName . '" is not configured in TCA.', - IndexingException::CODE_UNKOWN_TCA_TABLE - ); - } - - $this->tableName = $tableName; - $this->tca = &$GLOBALS['TCA'][$this->tableName]; - $this->configuration = $configuration; - } - - public function getTableName() : string - { - return $this->tableName; - } - - public function getTableClause() : string - { - if ($this->tableName === 'pages') { - return $this->tableName; - } - - return $this->tableName . ' LEFT JOIN pages on ' . $this->tableName . '.pid = pages.uid'; - } - - public function getRecords(int $offset, int $limit) : array - { - $records = $this->getConnection()->exec_SELECTgetRows( - $this->getFields(), - $this->getTableClause(), - $this->getWhereClause(), - '', - '', - (int) $offset . ',' . (int) $limit - ); - - return $records ?: []; - } - - public function getRecord(int $identifier) : array - { - $record = $this->getConnection()->exec_SELECTgetSingleRow( - $this->getFields(), - $this->getTableClause(), - $this->getWhereClause() - . ' AND ' . $this->getTableName() . '.uid = ' . (int) $identifier - ); - - return $record ?: []; - } - - public function filterRecordsByRootLineBlacklist(array &$records) - { - $records = array_filter( - $records, - function ($record) { - return ! $this->isRecordBlacklistedByRootline($record); - } - ); - } - - public function prepareRecord(array &$record) - { - if (isset($record['uid']) && !isset($record['search_identifier'])) { - $record['search_identifier'] = $record['uid']; - } - if (isset($record[$this->tca['ctrl']['label']]) && !isset($record['search_title'])) { - $record['search_title'] = $record[$this->tca['ctrl']['label']]; - } - } - - public function getWhereClause() : string - { - $whereClause = '1=1' - . BackendUtility::BEenableFields($this->tableName) - . BackendUtility::deleteClause($this->tableName) - . ' AND pages.no_search = 0' - ; - - if ($this->tableName !== 'pages') { - $whereClause .= BackendUtility::BEenableFields('pages') - . BackendUtility::deleteClause('pages') - ; - } - - $userDefinedWhere = $this->configuration->getIfExists( - 'indexing.' . $this->getTableName() . '.additionalWhereClause' - ); - if (is_string($userDefinedWhere)) { - $whereClause .= ' AND ' . $userDefinedWhere; - } - if ($this->isBlacklistedRootLineConfigured()) { - $whereClause .= ' AND pages.uid NOT IN (' - . implode(',', $this->getBlacklistedRootLine()) - . ')' - . ' AND pages.pid NOT IN (' - . implode(',', $this->getBlacklistedRootLine()) - . ')'; - } - - $this->logger->debug('Generated where clause.', [$this->tableName, $whereClause]); - return $whereClause; - } - - public function getFields() : string - { - $fields = array_merge( - ['uid','pid'], - array_filter( - array_keys($this->tca['columns']), - function ($columnName) { - return !$this->isSystemField($columnName) - && !$this->isUserField($columnName) - && !$this->isPassthroughField($columnName) - ; - } - ) - ); - - foreach ($fields as $key => $field) { - $fields[$key] = $this->tableName . '.' . $field; - } - - $this->logger->debug('Generated fields.', [$this->tableName, $fields]); - return implode(',', $fields); - } - - - /** - * Generate SQL for TYPO3 as a system, to make sure only available records - * are fetched. - */ - protected function getSystemWhereClause() : string - { - $whereClause = '1=1' - . BackendUtility::BEenableFields($this->tableName) - . BackendUtility::deleteClause($this->tableName) - . ' AND pages.no_search = 0' - ; - - if ($this->tableName !== 'pages') { - $whereClause .= BackendUtility::BEenableFields('pages') - . BackendUtility::deleteClause('pages') - ; - } - - return $whereClause; - } - - protected function isSystemField(string $columnName) : bool - { - $systemFields = [ - // Versioning fields, - // https://docs.typo3.org/typo3cms/TCAReference/Reference/Ctrl/Index.html#versioningws - 't3ver_oid', 't3ver_id', 't3ver_label', 't3ver_wsid', - 't3ver_state', 't3ver_stage', 't3ver_count', 't3ver_tstamp', - 't3ver_move_id', 't3ver_swapmode', - $this->tca['ctrl']['transOrigDiffSourceField'], - $this->tca['ctrl']['cruser_id'], - $this->tca['ctrl']['fe_cruser_id'], - $this->tca['ctrl']['fe_crgroup_id'], - $this->tca['ctrl']['origUid'], - ]; - - return in_array($columnName, $systemFields); - } - - protected function isUserField(string $columnName) : bool - { - $config = $this->getColumnConfig($columnName); - return isset($config['type']) && $config['type'] === 'user'; - } - - protected function isPassthroughField(string $columnName) : bool - { - $config = $this->getColumnConfig($columnName); - return isset($config['type']) && $config['type'] === 'passthrough'; - } - - /** - * @throws InvalidArgumentException - */ - public function getColumnConfig(string $columnName) : array - { - if (!isset($this->tca['columns'][$columnName])) { - throw new InvalidArgumentException( - 'Column does not exist.', - InvalidArgumentException::COLUMN_DOES_NOT_EXIST - ); - } - - return $this->tca['columns'][$columnName]['config']; - } - - public function getLanguageUidColumn() : string - { - if (!isset($this->tca['ctrl']['languageField'])) { - return ''; - } - - return $this->tca['ctrl']['languageField']; - } - - /** - * Checks whether the given record was blacklisted by root line. - * This can be configured by typoscript as whole root lines can be black listed. - * - * Also further TYPO3 mechanics are taken into account. Does a valid root - * line exist, is page inside a recycler, is inherited start- endtime - * excluded, etc. - */ - protected function isRecordBlacklistedByRootline(array &$record) : bool - { - $pageUid = $record['pid']; - if ($this->tableName === 'pages') { - $pageUid = $record['uid']; - } - - try { - $rootline = $this->objectManager->get(RootlineUtility::class, $pageUid)->get(); - } catch (\RuntimeException $e) { - $this->logger->notice( - sprintf('Could not fetch rootline for page %u, because: %s', $pageUid, $e->getMessage()), - [$record, $e] - ); - return true; - } - - foreach ($rootline as $pageInRootLine) { - // Check configured black list if present. - if ($this->isBlackListedRootLineConfigured() - && in_array($pageInRootLine['uid'], $this->getBlackListedRootLine()) - ) { - $this->logger->info( - sprintf( - 'Record %u is black listed due to configured root line configuration of page %u.', - $record['uid'], - $pageInRootLine['uid'] - ), - [$record, $pageInRootLine] - ); - return true; - } - - if ($pageInRootLine['extendToSubpages'] && ( - ($pageInRootLine['endtime'] > 0 && $pageInRootLine['endtime'] <= time()) - || ($pageInRootLine['starttime'] > 0 && $pageInRootLine['starttime'] >= time()) - )) { - $this->logger->info( - sprintf( - 'Record %u is black listed due to configured timing of parent page %u.', - $record['uid'], - $pageInRootLine['uid'] - ), - [$record, $pageInRootLine] - ); - return true; - } - } - - return false; - } - - /** - * Checks whether any page uids are black listed. - */ - protected function isBlackListedRootLineConfigured() : bool - { - return (bool) $this->configuration->getIfExists('indexing.' . $this->getTableName() . '.rootLineBlacklist'); - } - - /** - * Get the list of black listed root line page uids. - * - * @return array - */ - protected function getBlackListedRootLine() : array - { - return GeneralUtility::intExplode( - ',', - $this->configuration->getIfExists('indexing.' . $this->getTableName() . '.rootLineBlacklist') - ); - } - - protected function getConnection() : \TYPO3\CMS\Core\Database\DatabaseConnection - { - return $GLOBALS['TYPO3_DB']; - } -} diff --git a/Classes/Domain/Model/SearchRequest.php b/Classes/Domain/Model/SearchRequest.php index 3c888712..108a7cf1 100644 --- a/Classes/Domain/Model/SearchRequest.php +++ b/Classes/Domain/Model/SearchRequest.php @@ -30,6 +30,8 @@ */ class SearchRequest implements SearchRequestInterface { + use QueryResultInterfaceStub; + /** * The search string provided by the user, the actual term to search for. * @@ -93,7 +95,10 @@ public function getSearchTerm() : string public function setFilter(array $filter) { $filter = \TYPO3\CMS\Core\Utility\ArrayUtility::removeArrayEntryByValue($filter, ''); - $this->filter = \TYPO3\CMS\Extbase\Utility\ArrayUtility::removeEmptyElementsRecursively($filter); + $this->filter = \TYPO3\CMS\Core\Utility\ArrayUtility::filterRecursive($filter, function ($value) { + return (!is_array($value) && trim($value) !== '') + || is_array($value) && count($value) !== 0; + }); } public function hasFilter() : bool @@ -170,12 +175,12 @@ public function setOffset($offset) return $this; } - public function getLimit() + public function getLimit(): int { return $this->limit; } - public function getOffset() + public function getOffset(): int { return $this->offset; } @@ -215,11 +220,6 @@ public function equals($propertyName, $operand, $caseSensitive = true) throw new \BadMethodCallException('Method is not implemented yet.', 1502196199); } - public function like($propertyName, $operand, $caseSensitive = true) - { - throw new \BadMethodCallException('Method is not implemented yet.', 1502196167); - } - public function contains($propertyName, $operand) { throw new \BadMethodCallException('Method is not implemented yet.', 1502196200); @@ -294,4 +294,29 @@ public function getStatement() { throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); } + + public function current() + { + throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); + } + + public function next() + { + throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); + } + + public function key() + { + throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); + } + + public function valid() + { + throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); + } + + public function rewind() + { + throw new \BadMethodCallException('Method is not implemented yet.', 1502196208); + } } diff --git a/Classes/Domain/Model/SearchResult.php b/Classes/Domain/Model/SearchResult.php index 516c333e..60e9c506 100644 --- a/Classes/Domain/Model/SearchResult.php +++ b/Classes/Domain/Model/SearchResult.php @@ -103,8 +103,6 @@ public function current() public function next() { ++$this->position; - - return $this->current(); } public function key() diff --git a/Classes/Domain/Search/QueryFactory.php b/Classes/Domain/Search/QueryFactory.php index 98e33247..bde8b696 100644 --- a/Classes/Domain/Search/QueryFactory.php +++ b/Classes/Domain/Search/QueryFactory.php @@ -25,7 +25,7 @@ use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Connection\SearchRequestInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\ArrayUtility; class QueryFactory { @@ -85,7 +85,7 @@ protected function createElasticaQuery(SearchRequestInterface $searchRequest) : protected function addSize(SearchRequestInterface $searchRequest, array &$query) { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ + ArrayUtility::mergeRecursiveWithOverrule($query, [ 'from' => $searchRequest->getOffset(), 'size' => $searchRequest->getLimit(), ]); @@ -108,7 +108,7 @@ protected function addSearch(SearchRequestInterface $searchRequest, array &$quer $matchExpression['minimum_should_match'] = $minimumShouldMatch; } - $query = ArrayUtility::setValueByPath($query, 'query.bool.must.0.multi_match', $matchExpression); + $query = ArrayUtility::setValueByPath($query, 'query.bool.must.0.multi_match', $matchExpression, '.'); } protected function addBoosts(SearchRequestInterface $searchRequest, array &$query) @@ -137,7 +137,7 @@ protected function addBoosts(SearchRequestInterface $searchRequest, array &$quer } if (!empty($boostQueryParts)) { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ + ArrayUtility::mergeRecursiveWithOverrule($query, [ 'query' => [ 'bool' => [ 'should' => $boostQueryParts, @@ -149,6 +149,10 @@ protected function addBoosts(SearchRequestInterface $searchRequest, array &$quer protected function addFactorBoost(array &$query) { + if (!isset($query['query'])) { + return; + } + try { $query['query'] = [ 'function_score' => [ @@ -164,7 +168,7 @@ protected function addFactorBoost(array &$query) protected function addFields(SearchRequestInterface $searchRequest, array &$query) { try { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ + ArrayUtility::mergeRecursiveWithOverrule($query, [ 'stored_fields' => GeneralUtility::trimExplode( ',', $this->configuration->get('searching.fields.stored_fields'), @@ -183,7 +187,7 @@ protected function addFields(SearchRequestInterface $searchRequest, array &$quer ); $scriptFields = $this->configurationUtility->filterByCondition($scriptFields); if ($scriptFields !== []) { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, ['script_fields' => $scriptFields]); + ArrayUtility::mergeRecursiveWithOverrule($query, ['script_fields' => $scriptFields]); } } catch (InvalidArgumentException $e) { // Nothing configured @@ -196,7 +200,7 @@ protected function addSort(SearchRequestInterface $searchRequest, array &$query) $sorting = $this->configurationUtility->replaceArrayValuesWithRequestContent($searchRequest, $sorting); $sorting = $this->configurationUtility->filterByCondition($sorting); if ($sorting !== []) { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, ['sort' => $sorting]); + ArrayUtility::mergeRecursiveWithOverrule($query, ['sort' => $sorting]); } } @@ -215,7 +219,7 @@ protected function addFilter(SearchRequestInterface $searchRequest, array &$quer ); } - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ + ArrayUtility::mergeRecursiveWithOverrule($query, [ 'query' => [ 'bool' => [ 'filter' => $filter, @@ -260,7 +264,7 @@ protected function buildFilter(string $name, $value, array $config) : array protected function addFacets(SearchRequestInterface $searchRequest, array &$query) { foreach ($searchRequest->getFacets() as $facet) { - $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ + ArrayUtility::mergeRecursiveWithOverrule($query, [ 'aggs' => [ $facet->getIdentifier() => $facet->getConfig(), ], diff --git a/Documentation/source/changelog.rst b/Documentation/source/changelog.rst index 0bde72fa..32921d29 100644 --- a/Documentation/source/changelog.rst +++ b/Documentation/source/changelog.rst @@ -1,17 +1,28 @@ Changelog ========= +v1.0.0 +------ + .. toctree:: :maxdepth: 1 :glob: - changelog/20180518-75-make-index-name-configurable - changelog/20180424-149-extract-relation-resolver-to-data-processing - changelog/20180410-148-keep-sys_language_uid - changelog/20180315-134-make-conent-fields-configurable - changelog/20180309-25-provide-sys-language-uid - changelog/20180308-131-respect-page-cache-clear - changelog/20180308-introduce-php70-type-hints - changelog/20180306-120-facet-configuration - changelog/20180926-163-allow-zero-as-typoscript-filter-value - changelog/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer + changelog/1.0.0/* + +prior v1.0.0 +------------ + +.. toctree:: + :maxdepth: 1 + + changelog/prior-1.0.0/20180518-75-make-index-name-configurable + changelog/prior-1.0.0/20180424-149-extract-relation-resolver-to-data-processing + changelog/prior-1.0.0/20180410-148-keep-sys_language_uid + changelog/prior-1.0.0/20180315-134-make-conent-fields-configurable + changelog/prior-1.0.0/20180309-25-provide-sys-language-uid + changelog/prior-1.0.0/20180308-131-respect-page-cache-clear + changelog/prior-1.0.0/20180308-introduce-php70-type-hints + changelog/prior-1.0.0/20180306-120-facet-configuration + changelog/prior-1.0.0/20180926-163-allow-zero-as-typoscript-filter-value + changelog/prior-1.0.0/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer diff --git a/Documentation/source/changelog/1.0.0/20190517-typo3-v9-update.rst b/Documentation/source/changelog/1.0.0/20190517-typo3-v9-update.rst new file mode 100644 index 00000000..b434a131 --- /dev/null +++ b/Documentation/source/changelog/1.0.0/20190517-typo3-v9-update.rst @@ -0,0 +1,23 @@ +Breaking change "TYPO3 v9 LTS Update" +===================================== + +The extension does now officially support TYPO3 CMS v9.5 LTS. +This change contains some breaking changes: + +* Support for TYPO3 versions lower then 9.5 LTS has been dropped. + +* Due to dropped TYPO3 CMS < v9 support, also all PHP Code within ``Compatibility`` + namespace was removed. + + * ``\Codappix\SearchCore\DataProcessing\ContentObjectDataProcessorAdapterProcessor`` + has changed signature for ``__construct`` due to removed ``Compatibility`` + namespace. + +* PHP Interface ``\Codappix\SearchCore\Connection\SearchRequestInterface`` has + changed, due to extending TYPO3 Interface + ``\TYPO3\CMS\Extbase\Persistence\QueryResultInterface``. + + Therefore also PHP class ``\Codappix\SearchCore\Domain\Model\SearchRequest`` has + been adjusted. + +* Recycler are respected. Pages from type recycler are ignored during indexing. diff --git a/Documentation/source/changelog/20180306-120-facet-configuration.rst b/Documentation/source/changelog/prior-1.0.0/20180306-120-facet-configuration.rst similarity index 100% rename from Documentation/source/changelog/20180306-120-facet-configuration.rst rename to Documentation/source/changelog/prior-1.0.0/20180306-120-facet-configuration.rst diff --git a/Documentation/source/changelog/20180308-131-respect-page-cache-clear.rst b/Documentation/source/changelog/prior-1.0.0/20180308-131-respect-page-cache-clear.rst similarity index 100% rename from Documentation/source/changelog/20180308-131-respect-page-cache-clear.rst rename to Documentation/source/changelog/prior-1.0.0/20180308-131-respect-page-cache-clear.rst diff --git a/Documentation/source/changelog/20180308-introduce-php70-type-hints.rst b/Documentation/source/changelog/prior-1.0.0/20180308-introduce-php70-type-hints.rst similarity index 100% rename from Documentation/source/changelog/20180308-introduce-php70-type-hints.rst rename to Documentation/source/changelog/prior-1.0.0/20180308-introduce-php70-type-hints.rst diff --git a/Documentation/source/changelog/20180309-25-provide-sys-language-uid.rst b/Documentation/source/changelog/prior-1.0.0/20180309-25-provide-sys-language-uid.rst similarity index 100% rename from Documentation/source/changelog/20180309-25-provide-sys-language-uid.rst rename to Documentation/source/changelog/prior-1.0.0/20180309-25-provide-sys-language-uid.rst diff --git a/Documentation/source/changelog/20180315-134-make-conent-fields-configurable.rst b/Documentation/source/changelog/prior-1.0.0/20180315-134-make-conent-fields-configurable.rst similarity index 100% rename from Documentation/source/changelog/20180315-134-make-conent-fields-configurable.rst rename to Documentation/source/changelog/prior-1.0.0/20180315-134-make-conent-fields-configurable.rst diff --git a/Documentation/source/changelog/20180410-148-keep-sys_language_uid.rst b/Documentation/source/changelog/prior-1.0.0/20180410-148-keep-sys_language_uid.rst similarity index 100% rename from Documentation/source/changelog/20180410-148-keep-sys_language_uid.rst rename to Documentation/source/changelog/prior-1.0.0/20180410-148-keep-sys_language_uid.rst diff --git a/Documentation/source/changelog/20180424-149-extract-relation-resolver-to-data-processing.rst b/Documentation/source/changelog/prior-1.0.0/20180424-149-extract-relation-resolver-to-data-processing.rst similarity index 100% rename from Documentation/source/changelog/20180424-149-extract-relation-resolver-to-data-processing.rst rename to Documentation/source/changelog/prior-1.0.0/20180424-149-extract-relation-resolver-to-data-processing.rst diff --git a/Documentation/source/changelog/20180518-75-make-index-name-configurable.rst b/Documentation/source/changelog/prior-1.0.0/20180518-75-make-index-name-configurable.rst similarity index 100% rename from Documentation/source/changelog/20180518-75-make-index-name-configurable.rst rename to Documentation/source/changelog/prior-1.0.0/20180518-75-make-index-name-configurable.rst diff --git a/Documentation/source/changelog/20180926-163-allow-zero-as-typoscript-filter-value.rst b/Documentation/source/changelog/prior-1.0.0/20180926-163-allow-zero-as-typoscript-filter-value.rst similarity index 100% rename from Documentation/source/changelog/20180926-163-allow-zero-as-typoscript-filter-value.rst rename to Documentation/source/changelog/prior-1.0.0/20180926-163-allow-zero-as-typoscript-filter-value.rst diff --git a/Documentation/source/changelog/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer.rst b/Documentation/source/changelog/prior-1.0.0/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer.rst similarity index 100% rename from Documentation/source/changelog/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer.rst rename to Documentation/source/changelog/prior-1.0.0/20181106-170-do-not-specify-the-pluginname-in-configurationcontainer.rst diff --git a/Makefile b/Makefile index 14306336..77f3ad9a 100644 --- a/Makefile +++ b/Makefile @@ -4,25 +4,15 @@ current_dir := $(dir $(mkfile_path)) TYPO3_WEB_DIR := $(current_dir).Build/web TYPO3_PATH_ROOT := $(current_dir).Build/web # Allow different versions on travis -TYPO3_VERSION ?= ~8.7 +TYPO3_VERSION ?= ^9.5 typo3DatabaseName ?= "searchcore_test" typo3DatabaseUsername ?= "dev" typo3DatabasePassword ?= "dev" typo3DatabaseHost ?= "127.0.0.1" -sourceOrDist=--prefer-dist -ifeq ($(TYPO3_VERSION),~7.6) - sourceOrDist=--prefer-source -endif - .PHONY: install install: clean - if [ $(TYPO3_VERSION) = ~7.6 ]; then \ - patch composer.json Tests/InstallPatches/composer.json.patch; \ - fi - - COMPOSER_PROCESS_TIMEOUT=1000 composer require --dev $(sourceOrDist) typo3/cms="$(TYPO3_VERSION)" - git checkout composer.json + composer install cgl: ./.Build/bin/phpcs @@ -33,12 +23,12 @@ functionalTests: typo3DatabasePassword=$(typo3DatabasePassword) \ typo3DatabaseHost=$(typo3DatabaseHost) \ TYPO3_PATH_WEB=$(TYPO3_WEB_DIR) \ - .Build/bin/phpunit --colors --debug -v \ + .Build/bin/phpunit --colors -v \ -c Tests/Functional/FunctionalTests.xml unitTests: TYPO3_PATH_WEB=$(TYPO3_WEB_DIR) \ - .Build/bin/phpunit --colors --debug -v \ + .Build/bin/phpunit --colors -v \ -c Tests/Unit/UnitTests.xml uploadCodeCoverage: uploadCodeCoverageToScrutinizer @@ -48,4 +38,4 @@ uploadCodeCoverageToScrutinizer: php ocular.phar code-coverage:upload --format=php-clover .Build/report/functional/clover/coverage clean: - rm -rf .Build composer.lock + rm -rf .Build/ var/ composer.lock diff --git a/Tests/Functional/AbstractFunctionalTestCase.php b/Tests/Functional/AbstractFunctionalTestCase.php index d0154576..f0b18715 100644 --- a/Tests/Functional/AbstractFunctionalTestCase.php +++ b/Tests/Functional/AbstractFunctionalTestCase.php @@ -20,7 +20,7 @@ * 02110-1301, USA. */ -use TYPO3\CMS\Core\Tests\FunctionalTestCase as CoreTestCase; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as CoreTestCase; /** * All functional tests should extend this base class. @@ -37,7 +37,7 @@ public function setUp() \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeLanguageObject(); foreach ($this->getDataSets() as $dataSet) { - $this->importDataSet($dataSet); + $this->importDataSet('EXT:search_core/' . $dataSet); } $this->setUpFrontendRootPage(1, $this->getTypoScriptFilesForFrontendRootPage()); diff --git a/Tests/Functional/Connection/Elasticsearch/IndexTcaTableTest.php b/Tests/Functional/Connection/Elasticsearch/IndexTcaTableTest.php index ae671dda..40b5fa43 100644 --- a/Tests/Functional/Connection/Elasticsearch/IndexTcaTableTest.php +++ b/Tests/Functional/Connection/Elasticsearch/IndexTcaTableTest.php @@ -124,7 +124,7 @@ public function indexingRespectsUserWhereClause() parent::getTypoScriptFilesForFrontendRootPage(), ['EXT:search_core/Tests/Functional/Fixtures/Indexing/UserWhereClause.ts'] )); - $this->importDataSet('Tests/Functional/Fixtures/Indexing/UserWhereClause.xml'); + $this->importDataSet('EXT:search_core/Tests/Functional/Fixtures/Indexing/UserWhereClause.xml'); \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) ->get(IndexerFactory::class) @@ -157,7 +157,7 @@ public function indexingRespectsUserWhereClause() */ public function resolvesRelations() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/ResolveRelations.xml'); + $this->importDataSet('EXT:search_core/Tests/Functional/Fixtures/Indexing/ResolveRelations.xml'); \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) ->get(IndexerFactory::class) diff --git a/Tests/Functional/DataProcessing/ContentObjectDataProcessorAdapterProcessorTest.php b/Tests/Functional/DataProcessing/ContentObjectDataProcessorAdapterProcessorTest.php index bb997cf5..0ebb3e55 100644 --- a/Tests/Functional/DataProcessing/ContentObjectDataProcessorAdapterProcessorTest.php +++ b/Tests/Functional/DataProcessing/ContentObjectDataProcessorAdapterProcessorTest.php @@ -20,8 +20,7 @@ * 02110-1301, USA. */ -use Codappix\SearchCore\Compatibility\TypoScriptService76; -use Codappix\SearchCore\Compatibility\TypoScriptService; +use TYPO3\CMS\Core\TypoScript\TypoScriptService; use Codappix\SearchCore\DataProcessing\ContentObjectDataProcessorAdapterProcessor; use Codappix\SearchCore\Tests\Functional\AbstractFunctionalTestCase; use TYPO3\CMS\Frontend\DataProcessing\SplitProcessor; @@ -45,13 +44,7 @@ public function contentObjectDataProcessorIsExecuted() 'new_content' => ['value1', 'value2'], ]; - if ($this->isLegacyVersion()) { - $typoScriptService = new TypoScriptService76(); - } else { - $typoScriptService = new TypoScriptService(); - } - - $subject = new ContentObjectDataProcessorAdapterProcessor($typoScriptService); + $subject = new ContentObjectDataProcessorAdapterProcessor(new TypoScriptService()); $processedData = $subject->processData($record, $configuration); $this->assertSame( $expectedData, diff --git a/Tests/Functional/DataProcessing/TcaRelationResolvingProcessorTest.php b/Tests/Functional/DataProcessing/TcaRelationResolvingProcessorTest.php index c5011df9..942795ff 100644 --- a/Tests/Functional/DataProcessing/TcaRelationResolvingProcessorTest.php +++ b/Tests/Functional/DataProcessing/TcaRelationResolvingProcessorTest.php @@ -33,7 +33,9 @@ class TcaRelationResolvingProcessorTest extends AbstractFunctionalTestCase */ public function resolveInlineRelation() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/InlineRelation.xml'); + $this->importDataSet( + 'EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/InlineRelation.xml' + ); $objectManager = GeneralUtility::makeInstance(ObjectManager::class); $table = 'sys_file'; @@ -55,7 +57,9 @@ public function resolveInlineRelation() */ public function resolveStaticSelectItems() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/StaticSelectItems.xml'); + $this->importDataSet( + 'EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/StaticSelectItems.xml' + ); $objectManager = GeneralUtility::makeInstance(ObjectManager::class); $table = 'tt_content'; @@ -74,7 +78,9 @@ public function resolveStaticSelectItems() */ public function resolveForeignDb() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/ForeignDb.xml'); + $this->importDataSet( + 'EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/ForeignDb.xml' + ); $objectManager = GeneralUtility::makeInstance(ObjectManager::class); $table = 'tt_content'; @@ -96,7 +102,9 @@ public function resolveForeignDb() */ public function resolveForeignMmSelect() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/ForeignMmSelect.xml'); + $this->importDataSet( + 'EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RelationResolver/ForeignMmSelect.xml' + ); $objectManager = GeneralUtility::makeInstance(ObjectManager::class); $table = 'tt_content'; diff --git a/Tests/Functional/Indexing/PagesIndexerTest.php b/Tests/Functional/Indexing/PagesIndexerTest.php index acc8b68d..69db4cf5 100644 --- a/Tests/Functional/Indexing/PagesIndexerTest.php +++ b/Tests/Functional/Indexing/PagesIndexerTest.php @@ -33,7 +33,7 @@ class PagesIndexerTest extends AbstractFunctionalTestCase */ public function pagesContainAllAdditionalInformation() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/IndexTcaTable.xml'); + $this->importDataSet('EXT:search_core/Tests/Functional/Fixtures/Indexing/IndexTcaTable.xml'); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class); $tableName = 'pages'; @@ -71,7 +71,7 @@ public function pagesContainAllAdditionalInformation() */ public function rootLineIsRespectedDuringIndexing($dataSetPath) { - $this->importDataSet($dataSetPath); + $this->importDataSet('EXT:search_core/' . $dataSetPath); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class); $tableName = 'pages'; diff --git a/Tests/Functional/Indexing/TcaIndexerTest.php b/Tests/Functional/Indexing/TcaIndexerTest.php index 472cc154..30059033 100644 --- a/Tests/Functional/Indexing/TcaIndexerTest.php +++ b/Tests/Functional/Indexing/TcaIndexerTest.php @@ -43,7 +43,9 @@ protected function getTypoScriptFilesForFrontendRootPage() */ public function respectRootLineBlacklist() { - $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.xml'); + $this->importDataSet( + 'EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.xml' + ); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class); $tableName = 'tt_content'; $tableService = $objectManager->get( diff --git a/Tests/InstallPatches/composer.json.patch b/Tests/InstallPatches/composer.json.patch deleted file mode 100644 index 6f11cdc7..00000000 --- a/Tests/InstallPatches/composer.json.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/composer.json b/composer.json -index 83e5f47..e9fa296 100644 ---- a/composer.json -+++ b/composer.json -@@ -21,8 +21,7 @@ - "ruflin/elastica": "~3.2" - }, - "require-dev": { -- "phpunit/phpunit": "~6.4.4", -- "typo3/testing-framework": "~1.1.5", -+ "phpunit/phpunit": "~5.7.0", - "squizlabs/php_codesniffer": "~3.1.1" - }, - "config": { diff --git a/Tests/Unit/AbstractUnitTestCase.php b/Tests/Unit/AbstractUnitTestCase.php index 384236c5..ea90bd6b 100644 --- a/Tests/Unit/AbstractUnitTestCase.php +++ b/Tests/Unit/AbstractUnitTestCase.php @@ -20,10 +20,10 @@ * 02110-1301, USA. */ -use TYPO3\CMS\Core\Tests\UnitTestCase as CoreTestCase; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Form\Service\TranslationService; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase as CoreTestCase; abstract class AbstractUnitTestCase extends CoreTestCase { diff --git a/Tests/Unit/Controller/SearchControllerTest.php b/Tests/Unit/Controller/SearchControllerTest.php index 67c6d98f..5ed5781f 100644 --- a/Tests/Unit/Controller/SearchControllerTest.php +++ b/Tests/Unit/Controller/SearchControllerTest.php @@ -29,6 +29,8 @@ class SearchControllerTest extends AbstractUnitTestCase { + protected $resetSingletonInstances = true; + /** * @var SearchController */ diff --git a/Tests/Unit/DataProcessing/TcaRelationResolvingProcessorTest.php b/Tests/Unit/DataProcessing/TcaRelationResolvingProcessorTest.php index e7abb077..6f9fd00f 100644 --- a/Tests/Unit/DataProcessing/TcaRelationResolvingProcessorTest.php +++ b/Tests/Unit/DataProcessing/TcaRelationResolvingProcessorTest.php @@ -23,6 +23,7 @@ use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\DataProcessing\TcaRelationResolvingProcessor; use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase; +use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Extbase\Object\ObjectManager; use \TYPO3\CMS\Core\Utility\GeneralUtility; @@ -51,6 +52,14 @@ public function setUp() $this->subject = GeneralUtility::makeInstance(ObjectManager::class) ->get(TcaRelationResolvingProcessor::class); + + $GLOBALS['LANG'] = $this->getMockBuilder(LanguageService::class)->getMock(); + } + + public function tearDown() + { + unset($GLOBALS['LANG']); + parent::tearDown(); } /** @@ -118,6 +127,7 @@ public function sysLanguageUidZeroIsKept() public function renderTypeInputDateTimeIsHandled() { $originalRecord = [ + 'uid' => 10, 'endtime' => 99999999999, 'starttime' => 1523010960, ]; @@ -159,6 +169,7 @@ public function renderTypeInputDateTimeIsHandled() $record = $this->subject->processData($originalRecord, $configuration); $this->assertSame( [ + 'uid' => '10', 'endtime' => '16-11-38 09:46', 'starttime' => 1523010960, ], diff --git a/Tests/Unit/Domain/Index/TcaIndexer/TcaTableServiceTest.php b/Tests/Unit/Domain/Index/TcaIndexer/TcaTableServiceTest.php index f4706138..8106f6f1 100644 --- a/Tests/Unit/Domain/Index/TcaIndexer/TcaTableServiceTest.php +++ b/Tests/Unit/Domain/Index/TcaIndexer/TcaTableServiceTest.php @@ -21,12 +21,11 @@ */ use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; -use Codappix\SearchCore\DataProcessing\CopyToProcessor; use Codappix\SearchCore\Domain\Index\TcaIndexer\RelationResolver; use Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService76; use Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService; use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase; -use TYPO3\CMS\Core\Database\DatabaseConnection; +use TYPO3\CMS\Core\Database\ConnectionPool; class TcaTableServiceTest extends AbstractUnitTestCase { @@ -41,16 +40,16 @@ class TcaTableServiceTest extends AbstractUnitTestCase protected $configuration; /** - * @var DatabaseConnection + * @var ConnectionPool */ - protected $databaseConnection; + protected $connectionPool; public function setUp() { parent::setUp(); $this->configuration = $this->getMockBuilder(ConfigurationContainerInterface::class)->getMock(); - $this->databaseConnection = $this->getMockBuilder(DatabaseConnection::class)->getMock(); + $this->connectionPool = $this->getMockBuilder(ConnectionPool::class)->getMock(); $className = TcaTableService::class; if ($this->isLegacyVersion()) { @@ -62,7 +61,7 @@ public function setUp() ->getMock(); $this->subject->expects($this->any()) ->method('getConnection') - ->willReturn($this->databaseConnection); + ->willReturn($this->connectionPool); $this->inject($this->subject, 'configuration', $this->configuration); $this->inject($this->subject, 'logger', $this->getMockedLogger()); diff --git a/Tests/Unit/Domain/Model/SearchRequestTest.php b/Tests/Unit/Domain/Model/SearchRequestTest.php index 28f90e3c..da7c3547 100644 --- a/Tests/Unit/Domain/Model/SearchRequestTest.php +++ b/Tests/Unit/Domain/Model/SearchRequestTest.php @@ -58,7 +58,8 @@ public function possibleEmptyFilter() 'Single filter with empty recursive values' => [ 'filter' => [ 'someFilter' => [ - 'someKey' => '', + 'firstEmptyKey' => '', + 'secondEmptyKey' => '', ], ], ], @@ -80,58 +81,4 @@ public function filterIsSet() 'Filter was not set.' ); } - - /** - * @test - */ - public function exceptionIsThrownIfSearchServiceWasNotSet() - { - $subject = new SearchRequest(); - $subject->setConnection($this->getMockBuilder(ConnectionInterface::class)->getMock()); - $this->expectException(\InvalidArgumentException::class); - $subject->execute(); - } - - /** - * @test - */ - public function exceptionIsThrownIfConnectionWasNotSet() - { - $subject = new SearchRequest(); - $subject->setSearchService( - $this->getMockBuilder(SearchService::class) - ->disableOriginalConstructor() - ->getMock() - ); - $this->expectException(\InvalidArgumentException::class); - $subject->execute(); - } - - /** - * @test - */ - public function executionMakesUseOfProvidedConnectionAndSearchService() - { - $searchServiceMock = $this->getMockBuilder(SearchService::class) - ->disableOriginalConstructor() - ->getMock(); - $connectionMock = $this->getMockBuilder(ConnectionInterface::class) - ->getMock(); - $searchResultMock = $this->getMockBuilder(SearchResultInterface::class) - ->getMock(); - - $subject = new SearchRequest(); - $subject->setSearchService($searchServiceMock); - $subject->setConnection($connectionMock); - - $connectionMock->expects($this->once()) - ->method('search') - ->with($subject) - ->willReturn($searchResultMock); - $searchServiceMock->expects($this->once()) - ->method('processResult') - ->with($searchResultMock); - - $subject->execute(); - } } diff --git a/Tests/Unit/Domain/Search/QueryFactoryTest.php b/Tests/Unit/Domain/Search/QueryFactoryTest.php index dc824c5f..65bad8d2 100644 --- a/Tests/Unit/Domain/Search/QueryFactoryTest.php +++ b/Tests/Unit/Domain/Search/QueryFactoryTest.php @@ -156,9 +156,8 @@ public function emptyFilterIsNotAddedToQuery() ); $query = $this->subject->create($searchRequest); - $this->assertSame( - null, - $query->toArray()['query']['bool']['filter'], + $this->assertTrue( + !isset($query->toArray()['query']['bool']['filter']), 'Filter was added to query, even if no filter exists.' ); } @@ -405,7 +404,7 @@ public function emptySearchStringWillNotAddSearchToQuery() $query = $this->subject->create($searchRequest); $this->assertInstanceOf( - stdClass, + \stdClass::class, $query->toArray()['query']['match_all'], 'Empty search request does not create expected query.' ); @@ -543,7 +542,7 @@ public function scriptFieldsAreAddedToQuery() 'config' => 'something', ], 'field2' => [ - 'config' => '{request.query}', + 'config' => '{request.searchTerm}', ], ], $this->throwException(new InvalidArgumentException) @@ -613,7 +612,7 @@ public function sortIsAddedToQuery() 'config' => 'something', ], 'field2' => [ - 'config' => '{request.query}', + 'config' => '{request.searchTerm}', ], ] )); diff --git a/Tests/Unit/Domain/Search/SearchServiceTest.php b/Tests/Unit/Domain/Search/SearchServiceTest.php index 3b880768..b7f6b88d 100644 --- a/Tests/Unit/Domain/Search/SearchServiceTest.php +++ b/Tests/Unit/Domain/Search/SearchServiceTest.php @@ -23,6 +23,7 @@ use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Connection\ConnectionInterface; +use Codappix\SearchCore\Connection\SearchRequestInterface; use Codappix\SearchCore\Connection\SearchResultInterface; use Codappix\SearchCore\DataProcessing\Service as DataProcessorService; use Codappix\SearchCore\Domain\Model\SearchRequest; @@ -182,7 +183,7 @@ public function configuredFilterWithValueZeroAreAddedToRequestWithoutAnyFilter() $this->connection->expects($this->once()) ->method('search') - ->with($this->callback(function ($searchRequest) { + ->with($this->callback(function (SearchRequestInterface $searchRequest) { return $searchRequest->getFilter() === ['property' => '0']; })) ->willReturn($this->getMockBuilder(SearchResultInterface::class)->getMock()); diff --git a/composer.json b/composer.json index 83e5f47b..6de2fadb 100644 --- a/composer.json +++ b/composer.json @@ -16,17 +16,19 @@ } }, "require": { - "php": ">=7.0.0", - "typo3/cms": ">= 7.6.0 < 9.0.0", - "ruflin/elastica": "~3.2" + "php": ">=7.2.0 <8", + "typo3/cms-core": "^9.5", + "ruflin/elastica": "^3.2" + }, + "suggests": { + "typo3/cms-form": "To update indexed records via Formframework." }, "require-dev": { - "phpunit/phpunit": "~6.4.4", - "typo3/testing-framework": "~1.1.5", - "squizlabs/php_codesniffer": "~3.1.1" + "squizlabs/php_codesniffer": "^3.4", + "typo3/testing-framework": "^4.12", + "typo3/cms-form": "^9.5" }, "config": { - "optimize-autoloader": true, "vendor-dir": ".Build/vendor", "bin-dir": ".Build/bin" }, diff --git a/ext_emconf.php b/ext_emconf.php index b0bc5ed9..069929de 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -7,8 +7,8 @@ 'clearCacheOnLoad' => 1, 'constraints' => [ 'depends' => [ - 'typo3' => '7.6.0-8.7.99', - 'php' => '7.0.0-7.2.99' + 'typo3' => '9.5.7-9.5.99', + 'php' => '7.2.0-7.3.99' ], 'conflicts' => [], ], @@ -17,8 +17,8 @@ 'Codappix\\SearchCore\\' => 'Classes', ], ], - 'state' => 'beta', - 'version' => '0.0.7', + 'state' => 'stable', + 'version' => '1.0.0', 'author' => 'Daniel Siepmann', 'author_email' => 'coding@daniel-siepmann.de', ]; diff --git a/ext_localconf.php b/ext_localconf.php index 658d6834..5a551f7d 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -5,7 +5,7 @@ function ($extensionKey) { // TODO: Add hook for Extbase -> to handle records modified through // Frontend and backend modules not using datahandler - $GLOBALS['TYPO3_CONF_VARS'] = TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule( + \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule( $GLOBALS['TYPO3_CONF_VARS'], [ 'SC_OPTIONS' => [ @@ -40,13 +40,13 @@ function ($extensionKey) { ] ); - \Codappix\SearchCore\Compatibility\ImplementationRegistrationService::registerImplementations(); + $extensionConfiguration = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + \TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class + )->get($extensionKey); - // API does make use of object manager, therefore use GLOBALS - $extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$extensionKey]); if ($extensionConfiguration === false - || !isset($extensionConfiguration['disable.']['elasticsearch']) - || $extensionConfiguration['disable.']['elasticsearch'] !== '1' + || !isset($extensionConfiguration['disable']['elasticsearch']) + || $extensionConfiguration['disable']['elasticsearch'] !== '1' ) { \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class) ->registerImplementation(