diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2a9194e0f..c035700c7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,7 +24,7 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Used versions (please complete the following information):** - - TYPO3 Version: [e.g. 11.5.26] + - TYPO3 Version: [e.g. 12.4.0] - Browser: [e.g. chrome, safari] - EXT:solr Version: [e.g. 12.0.0] - Used Apache Solr Version: [e.g. 9.3.1] diff --git a/.github/workflows/ci-matrix.json b/.github/workflows/ci-matrix.json index 54f6a73a7..e4bacd7fe 100644 --- a/.github/workflows/ci-matrix.json +++ b/.github/workflows/ci-matrix.json @@ -1,21 +1,6 @@ { - "main": { + "release-11.6.x": { "PHP": [ "7.4", "8.0", "8.1" ], "TYPO3": [ "11", "11.5.x-dev" ] - }, - - "release-11.5.x": { - "PHP": [ "7.4", "8.0", "8.1" ], - "TYPO3": [ "11", "11.5.x-dev" ] - }, - - "release-11.1.x": { - "PHP": [ "7.2", "7.3", "7.4" ], - "TYPO3": [ "10", "10.4.x-dev" ] - }, - - "release-11.0.x": { - "PHP": [ "7.2", "7.3", "7.4" ], - "TYPO3": [ "9", "10", "9.5.x-dev", "10.4.x-dev" ] } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9441da9e4..1edb058a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,11 +2,11 @@ name: build on: push: - branches: [ main, release-11.5.x, release-11.1.x, release-11.0.x ] + branches: [ main, release-11.6.x ] tags: - "**" pull_request: - branches: [ main, release-11.5.x, release-11.1.x, release-11.0.x ] + branches: [ main, release-11.6.x ] env: CI_BUILD_DIRECTORY: '/home/runner/work/ext-solr/ext-solr/.Build' @@ -23,18 +23,21 @@ jobs: outputs: matrix: ${{ steps.collect_build_matrix.outputs.matrix }} steps: - # Workaround for issue with actions/checkout@v2 wrong PR commit checkout: See https://github.com/actions/checkout/issues/299#issuecomment-677674415 + # Workaround for issue with actions/checkout "wrong PR commit checkout": + # See: + # ** https://github.com/actions/checkout/issues/299#issuecomment-677674415 + # ** https://github.com/actions/checkout/issues/1359#issuecomment-1631503791 - name: Checkout current state of Pull Request if: github.event_name == 'pull_request' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} - name: Checkout current state of Branch if: github.event_name == 'push' - uses: actions/checkout@v2 - # End: Workaround for issue with actions/checkout@v2 wrong PR commit checkout + uses: actions/checkout@v3 + # End: Workaround for issue with actions/checkout... - name: "Resolve target branch of pull request." if: github.event_name == 'pull_request' @@ -69,10 +72,10 @@ jobs: echo "matrix=$(echo $matrix)" >> $GITHUB_OUTPUT - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Build Docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v4 with: context: . file: ./Docker/SolrServer/Dockerfile @@ -88,7 +91,7 @@ jobs: ./Build/Test/cibuild_docker.sh - name: Upload artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: solrci-image path: /tmp/solrci-image.tar @@ -104,40 +107,39 @@ jobs: TYPO3_DATABASE_HOST: '127.0.0.1' TYPO3_DATABASE_USERNAME: 'root' TYPO3_DATABASE_PASSWORD: 'root' - PHP_CS_FIXER_VERSION: '^3.2.1' TYPO3_VERSION: ${{ matrix.TYPO3 }} name: TYPO3 ${{ matrix.TYPO3 }} on PHP ${{ matrix.PHP }} steps: - # Workaround for issue with actions/checkout@v2 wrong PR commit checkout: See https://github.com/actions/checkout/issues/299#issuecomment-677674415 + # Workaround for issue with actions/checkout "wrong PR commit checkout". See: ci_bootstrapping job - name: Checkout current state of Pull Request if: github.event_name == 'pull_request' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 ref: ${{ github.event.pull_request.head.sha }} - name: Checkout current state of Branch if: github.event_name == 'push' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 - # End: Workaround for issue with actions/checkout@v2 wrong PR commit checkout + # End: Workaround for issue with actions/checkout... - name: Mount RAMFS run: | mkdir -p ${{ env.CI_BUILD_DIRECTORY }} - sudo mount -t tmpfs -o size=3G none ${{ env.CI_BUILD_DIRECTORY }} + sudo mount -t tmpfs -o size=1G none ${{ env.CI_BUILD_DIRECTORY }} sudo mkdir -p ${{ env.CI_BUILD_DIRECTORY }}/data-{solr,mysql} \ && sudo chown $USER ${{ env.CI_BUILD_DIRECTORY }}/data-mysql \ && sudo chown 8983:8983 ${{ env.CI_BUILD_DIRECTORY }}/data-solr - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Download solrci-image from "ci_bootstrapping" job - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: solrci-image path: /tmp @@ -160,36 +162,9 @@ jobs: with: php-version: ${{ matrix.PHP }} coverage: pcov - tools: composer:2.1.14 - - - name: Resolve CI build cache key - # CI_CACHE_VERSION is used and can be increased to be able to invalidate caches. - # For example if some composer dependencies added or removed in composer.json or - # in Build/Test/bootstrap.sh - run: | - export CURRENT_TYPO3_VERSION_REFERNCE=$(./Build/Helpers/TYPO3_SOURCE_REFERENCE.sh "$TYPO3_VERSION" --short) - export CURRENT_SOLARIUM_VERSION=$(cat composer.json | jq --raw-output '.require."solarium/solarium"') - export CI_CACHE_VERSION="2023.01.20@00:00" - export CI_BUILD_CACHE_KEY=${{ runner.os }}-PHP:${{ matrix.PHP }}-TYPO3:$TYPO3_VERSION@$CURRENT_TYPO3_VERSION_REFERNCE-SOLARIUM:$CURRENT_SOLARIUM_VERSION-"CI_CACHE_VERSION:"$CI_CACHE_VERSION - echo "COMPOSER_GLOBAL_REQUEREMENTS=$(composer config home)" >> $GITHUB_ENV - echo "CI_BUILD_CACHE_KEY=$CI_BUILD_CACHE_KEY" >> $GITHUB_ENV - echo "The key for actions/cache@v2 is \"$CI_BUILD_CACHE_KEY\"" - - - name: Restore ci build caches - id: restore_ci_build_caches - uses: actions/cache@v2 - with: - path: | - ${{ env.CI_BUILD_DIRECTORY }}/Web - ${{ env.CI_BUILD_DIRECTORY }}/bin - ${{ env.CI_BUILD_DIRECTORY }}/vendor - ${{ env.COMPOSER_GLOBAL_REQUEREMENTS }} - composer.json - composer.lock - key: ${{ env.CI_BUILD_CACHE_KEY }} + tools: composer:2.5.5 - name: CI-Bootstrap - if: steps.restore_ci_build_caches.outputs.cache-hit != 'true' run: | ./Build/Test/bootstrap.sh --skip-solr-install echo "Current Size of EXT:Solr build Artefacts before run: " \ @@ -204,8 +179,8 @@ jobs: - name: Upload code coverage to Scrutinizer run: | - .Build/bin/ocular code-coverage:upload --format=php-clover coverage.unit.clover - .Build/bin/ocular code-coverage:upload --format=php-clover coverage.integration.clover + ocular code-coverage:upload --format=php-clover coverage.unit.clover + ocular code-coverage:upload --format=php-clover coverage.integration.clover - name: Clean up run: | @@ -225,7 +200,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} - diff --git a/Build/Helpers/GET_LACAL_PACKAGE_VERSION_CONSTRAINT.sh b/Build/Helpers/GET_LOCAL_PACKAGE_VERSION_CONSTRAINT.sh similarity index 100% rename from Build/Helpers/GET_LACAL_PACKAGE_VERSION_CONSTRAINT.sh rename to Build/Helpers/GET_LOCAL_PACKAGE_VERSION_CONSTRAINT.sh diff --git a/Build/Test/IntegrationTests.xml b/Build/Test/IntegrationTests.xml index 55d51013f..4f81a8e17 100644 --- a/Build/Test/IntegrationTests.xml +++ b/Build/Test/IntegrationTests.xml @@ -1,6 +1,7 @@ defineOriginalRootPath(); $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/tests'); $testbase->createDirectory(ORIGINAL_ROOT . 'typo3temp/var/transient'); diff --git a/Build/Test/UnitTests.xml b/Build/Test/UnitTests.xml index d5e24cf3b..79f343afc 100644 --- a/Build/Test/UnitTests.xml +++ b/Build/Test/UnitTests.xml @@ -1,6 +1,7 @@ /dev/null 2>&1 then echo "Couldn't find wget." exit 1 fi -COMPOSER_NO_INTERACTION=1 - -# Setup TYPO3 environment variables -export TYPO3_PATH_PACKAGES="${EXTENSION_ROOTPATH}.Build/vendor/" -export TYPO3_PATH_WEB="${EXTENSION_ROOTPATH}.Build/Web/" +# Use latest TYPO3 LTS stable version, if version number is compatible with get.typo3.org API +if [[ $TYPO3_VERSION =~ ^[0-9]+$ ]] ; then + TYPO3_VERSION=$("${BASH_SOURCE%/*}/../Helpers/TYPO3_GET_LATEST_VERSION.sh" "$TYPO3_VERSION") +fi -echo "Installing test environment" -echo "Using extension path $EXTENSION_ROOTPATH" -echo "Using package path $TYPO3_PATH_PACKAGES" -echo "Using web path $TYPO3_PATH_WEB" +echo "Using TYPO3 Version: $TYPO3_VERSION" +echo "Using database host: $TYPO3_DATABASE_HOST" +echo "Using database dbname: $TYPO3_DATABASE_NAME" +echo "Using database user: $TYPO3_DATABASE_USERNAME" +echo "Using database password: $TYPO3_DATABASE_PASSWORD" -# Install TYPO3 sources -if [[ $TYPO3_VERSION = *"master"* ]]; then - composer config minimum-stability dev -fi +COMPOSER_NO_INTERACTION=1 -if ! composer require --dev --update-with-dependencies --prefer-source \ - typo3/cms-core:"$TYPO3_VERSION" \ - typo3/cms-backend:"$TYPO3_VERSION" \ - typo3/cms-recordlist:"$TYPO3_VERSION" \ - typo3/cms-fluid:"$TYPO3_VERSION" \ - typo3/cms-fluid-styled-content:"$TYPO3_VERSION" \ - typo3/cms-frontend:"$TYPO3_VERSION" \ - typo3/cms-extbase:"$TYPO3_VERSION" \ - typo3/cms-reports:"$TYPO3_VERSION" \ - typo3/cms-scheduler:"$TYPO3_VERSION" \ - typo3/cms-tstemplate:"$TYPO3_VERSION" \ - typo3/cms-install:"$TYPO3_VERSION" +echo "Installing test environment" +if ! composer tests:setup then echo "The test environment could not be installed by composer as expected. Please fix this issue." exit 1 fi -mkdir -p $TYPO3_PATH_WEB/uploads $TYPO3_PATH_WEB/typo3temp +echo "Install third party tools globally:" +export PATH=$PATH:$(composer config --global home)/vendor/bin +if ! composer tests:setup:global-require +then + "The test environment could not be installed by composer as expected. Please fix this issue." + exit 1 +fi diff --git a/Build/Test/cibuild.sh b/Build/Test/cibuild.sh index 2f12bb4a7..17a40e61e 100755 --- a/Build/Test/cibuild.sh +++ b/Build/Test/cibuild.sh @@ -1,13 +1,6 @@ #!/usr/bin/env bash -TYPO3_PATH_WEB="$(pwd)/.Build/Web/" -export TYPO3_PATH_WEB -TYPO3_PATH_PACKAGES="$(pwd)/.Build/vendor/" -export TYPO3_PATH_PACKAGES - -TYPO3_BIN_DIR="$(pwd)/.Build/bin/" -export TYPO3_BIN_DIR -export PATH="$TYPO3_BIN_DIR:$PATH" +EXIT_CODE=0 COMPOSERS_BIN_DIR="$(composer config home)/vendor/bin" # Add COMPOSERS_BIN_DIR to $PATH, if not present @@ -25,54 +18,48 @@ echo "Run PHP Lint" if ! find . -name \*.php ! -path "./.Build/*" 2>/dev/null | parallel --gnu php -d display_errors=stderr -l {} > /dev/null then echo "There are syntax errors, please check and fix them." - exit 1 + EXIT_CODE=1 else echo "No syntax errors! Great job!" fi -echo "Check compliance against TYPO3 Coding Standards" -if ! .Build/bin/php-cs-fixer --version > /dev/null 2>&1 + +echo "TYPO3 Coding Standards compliance: See https://github.com/TYPO3/coding-standards" +if ! composer t3:standards:fix -- --diff --verbose --dry-run && rm .php-cs-fixer.cache then - echo "TYPO3 https://github.com/TYPO3/coding-standards is not set properly." - echo "Please fix that asap to avoid unwanted changes in the future." - exit 1 + echo "Some files are not compliant to TYPO3 Coding Standards" + echo "Please fix the files listed above." + echo "Tip for auto fix: " + echo " TYPO3_VERSION=\"${TYPO3_VERSION}\" composer tests:setup && composer t3:standards:fix" + EXIT_CODE=3 else - echo "TYPO3 Coding Standards compliance: See https://github.com/TYPO3/coding-standards" - if ! composer t3:standards:fix -- --diff --verbose --dry-run && rm .php-cs-fixer.cache - then - echo "Some files are not compliant to TYPO3 Coding Standards" - echo "Please fix the files listed above." - echo "Tip for auto fix: " - echo " composer tests:setup && composer t3:standards:fix" - exit 1 - else - echo "The code is TYPO3 Coding Standards compliant! Great job!" - fi + echo "The code is TYPO3 Coding Standards compliant! Great job!" fi echo -e "\n\n" echo "Run XML Lint" -if ! xmllint --version > /dev/null 2>&1; then - echo "XML Lint not found, skipping XML linting." -else - echo -e "\n\n" - echo "Check syntax of XML files" - if ! composer lint:xlf - then - echo "Some XML files are not valid" - echo "Please fix the files listed above" - exit 1 - fi +if ! composer tests:lint-xml +then + EXIT_CODE=4 fi +echo -e "\n\n" +echo "Run PHPStan analysis" +if ! composer tests:phpstan +then + # disable fail temporary + #EXIT_CODE=7 + echo "Error during running the PHPStan analysis, please check and fix them." + echo "Tip for working on them: " + echo " TYPO3_VERSION=\"${TYPO3_VERSION}\" composer tests:setup && composer tests:phpstan" +fi echo -e "\n\n" echo "Run unit tests" -UNIT_BOOTSTRAP="Build/Test/UnitTestsBootstrap.php" -if ! .Build/bin/phpunit --colors -c Build/Test/UnitTests.xml --bootstrap=$UNIT_BOOTSTRAP --coverage-clover=coverage.unit.clover +if ! composer tests:unit -- --coverage-clover=coverage.unit.clover then echo "Error during running the unit tests please check and fix them" - exit 1 + EXIT_CODE=5 fi # @@ -109,9 +96,10 @@ fi echo -e "\n\n" echo "Run integration tests" -INTEGRATION_BOOTSTRAP="Build/Test/IntegrationTestsBootstrap.php" -if ! .Build/bin/phpunit --colors -c Build/Test/IntegrationTests.xml --bootstrap=$INTEGRATION_BOOTSTRAP --coverage-clover=coverage.integration.clover +if ! composer tests:integration -- --coverage-clover=coverage.integration.clover then echo "Error during running the integration tests please check and fix them" - exit 1 + EXIT_CODE=6 fi + +exit $EXIT_CODE diff --git a/Build/Test/phpstan-constants.php b/Build/Test/phpstan-constants.php new file mode 100644 index 000000000..1df075f0f --- /dev/null +++ b/Build/Test/phpstan-constants.php @@ -0,0 +1,5 @@ + */ -class RootlineElementFormatException extends \InvalidArgumentException +class RootlineElementFormatException extends InvalidArgumentException { } diff --git a/Classes/ConnectionManager.php b/Classes/ConnectionManager.php index 96581aeb3..bf162e34f 100644 --- a/Classes/ConnectionManager.php +++ b/Classes/ConnectionManager.php @@ -19,13 +19,13 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository as PagesRepositoryAtExtSolr; use ApacheSolrForTypo3\Solr\System\Records\SystemLanguage\SystemLanguageRepository; use ApacheSolrForTypo3\Solr\System\Solr\Node; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; use ApacheSolrForTypo3\Solr\System\Util\SiteUtility; use Doctrine\DBAL\Driver\Exception as DBALDriverException; -use InvalidArgumentException; use function json_encode; use Throwable; use TYPO3\CMS\Core\SingletonInterface; diff --git a/Classes/ContentObject/Classification.php b/Classes/ContentObject/Classification.php index 853ba186f..a8cfa3eef 100644 --- a/Classes/ContentObject/Classification.php +++ b/Classes/ContentObject/Classification.php @@ -17,7 +17,7 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Classification\Classification as ClassificationItem; use ApacheSolrForTypo3\Solr\Domain\Index\Classification\ClassificationService; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject; diff --git a/Classes/Controller/Backend/Search/AbstractModuleController.php b/Classes/Controller/Backend/Search/AbstractModuleController.php index 3cad029d5..89d3e2830 100644 --- a/Classes/Controller/Backend/Search/AbstractModuleController.php +++ b/Classes/Controller/Backend/Search/AbstractModuleController.php @@ -18,11 +18,12 @@ use ApacheSolrForTypo3\Solr\ConnectionManager; use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface; use ApacheSolrForTypo3\Solr\System\Mvc\Backend\Service\ModuleDataStorageService; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection as SolrCoreConnection; use Doctrine\DBAL\Driver\Exception as DBALDriverException; -use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use Throwable; use TYPO3\CMS\Backend\Template\Components\Menu\Menu; @@ -61,7 +62,7 @@ abstract class AbstractModuleController extends ActionController protected int $requestedPageUID; /** - * @var ?Site + * @var Site|null */ protected ?Site $selectedSite = null; @@ -91,9 +92,9 @@ abstract class AbstractModuleController extends ActionController protected ModuleDataStorageService $moduleDataStorageService; /** - * @var Queue + * @var QueueInterface */ - protected Queue $indexQueue; + protected QueueInterface $indexQueue; /** * @var SiteFinder diff --git a/Classes/Controller/Backend/Search/IndexQueueModuleController.php b/Classes/Controller/Backend/Search/IndexQueueModuleController.php index 4462e62fc..45673e4ab 100644 --- a/Classes/Controller/Backend/Search/IndexQueueModuleController.php +++ b/Classes/Controller/Backend/Search/IndexQueueModuleController.php @@ -17,7 +17,9 @@ use ApacheSolrForTypo3\Solr\Backend\IndexingConfigurationSelectorField; use ApacheSolrForTypo3\Solr\Domain\Index\IndexService; +use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueInitializationService; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Backend\Form\Exception as BackendFormException; use TYPO3\CMS\Core\Http\RedirectResponse; @@ -29,14 +31,26 @@ /** * Index Queue Module * + * @todo: Support all index queues in actions beside "initializeIndexQueueAction" and + * "resetLogErrorsAction" + * * @author Ingo Renner */ class IndexQueueModuleController extends AbstractModuleController { /** - * @var Queue + * The default Solr Queue + + * @var QueueInterface */ - protected Queue $indexQueue; + protected QueueInterface $indexQueue; + + /** + * Enabled Solr index queues + * + * @var QueueInterface[] + */ + protected array $enabledIndexQueues; /** * Initializes the controller before invoking an action method. @@ -44,13 +58,19 @@ class IndexQueueModuleController extends AbstractModuleController protected function initializeAction() { parent::initializeAction(); - $this->indexQueue = GeneralUtility::makeInstance(Queue::class); + + $this->enabledIndexQueues = $this->getIndexQueues(); + if (!empty($this->enabledIndexQueues)) { + $this->indexQueue = $this->enabledIndexQueues[Queue::class] ?? reset($this->enabledIndexQueues); + } } /** - * @param Queue $indexQueue + * Sets the default queue to use + * + * @param QueueInterface $indexQueue */ - public function setIndexQueue(Queue $indexQueue) + public function setIndexQueue(QueueInterface $indexQueue) { $this->indexQueue = $indexQueue; } @@ -85,6 +105,11 @@ protected function canQueueSelectedSite(): bool if ($this->selectedSite === null || empty($this->solrConnectionManager->getConnectionsBySite($this->selectedSite))) { return false; } + + if (!isset($this->indexQueue)) { + return false; + } + $enabledIndexQueueConfigurationNames = $this->selectedSite->getSolrConfiguration()->getEnabledIndexQueueConfigurationNames(); if (empty($enabledIndexQueueConfigurationNames)) { return false; @@ -119,25 +144,39 @@ public function initializeIndexQueueAction(): ResponseInterface $indexingConfigurationsToInitialize = GeneralUtility::_POST('tx_solr-index-queue-initialization'); if ((!empty($indexingConfigurationsToInitialize)) && (is_array($indexingConfigurationsToInitialize))) { - // initialize selected indexing configuration - try { - $initializedIndexingConfigurations = $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfigurations($this->selectedSite, $indexingConfigurationsToInitialize); - } catch (\Throwable $e) { - $this->addFlashMessage( - sprintf( + /** @var QueueInitializationService $initializationService */ + $initializationService = GeneralUtility::makeInstance(QueueInitializationService::class); + foreach ($indexingConfigurationsToInitialize as $configurationToInitialize) { + $indexQueueClass = $this->selectedSite->getSolrConfiguration()->getIndexQueueClassByConfigurationName($configurationToInitialize); + $indexQueue = $this->enabledIndexQueues[$indexQueueClass]; + + try { + $status = $initializationService->initializeBySiteAndIndexConfigurations($this->selectedSite, [$configurationToInitialize]); + $initializedIndexingConfiguration = [ + 'status' => $status[$configurationToInitialize], + 'statistic' => 0, + ]; + if ($status[$configurationToInitialize] === true) { + $initializedIndexingConfiguration['totalCount'] = $indexQueue->getStatisticsBySite($this->selectedSite, $configurationToInitialize)->getTotalCount(); + } + $initializedIndexingConfigurations[$configurationToInitialize] = $initializedIndexingConfiguration; + } catch (\Throwable $e) { + $this->addFlashMessage( + sprintf( + LocalizationUtility::translate( + 'solr.backend.index_queue_module.flashmessage.initialize_failure', + 'Solr' + ), + $e->getMessage(), + $e->getCode() + ), LocalizationUtility::translate( - 'solr.backend.index_queue_module.flashmessage.initialize_failure', + 'solr.backend.index_queue_module.flashmessage.initialize_failure.title', 'Solr' ), - $e->getMessage(), - $e->getCode() - ), - LocalizationUtility::translate( - 'solr.backend.index_queue_module.flashmessage.initialize_failure.title', - 'Solr' - ), - FlashMessage::ERROR - ); + FlashMessage::ERROR + ); + } } } else { $messageLabel = 'solr.backend.index_queue_module.flashmessage.initialize.no_selection'; @@ -148,13 +187,31 @@ public function initializeIndexQueueAction(): ResponseInterface FlashMessage::WARNING ); } + $messagesForConfigurations = []; - foreach (array_keys($initializedIndexingConfigurations) as $indexingConfigurationName) { - $itemCount = $this->indexQueue->getStatisticsBySite($this->selectedSite, $indexingConfigurationName)->getTotalCount(); - $messagesForConfigurations[] = $indexingConfigurationName . ' (' . $itemCount . ' records)'; + foreach ($initializedIndexingConfigurations as $indexingConfigurationName => $initializationData) { + if ($initializationData['status'] === true) { + $messagesForConfigurations[] = $indexingConfigurationName . ' (' . $initializationData['totalCount'] . ' records)'; + } else { + $this->addFlashMessage( + sprintf( + LocalizationUtility::translate( + 'solr.backend.index_queue_module.flashmessage.initialize_failure', + 'Solr' + ), + $indexingConfigurationName, + 1662117020 + ), + LocalizationUtility::translate( + 'solr.backend.index_queue_module.flashmessage.initialize_failure.title', + 'Solr' + ), + FlashMessage::ERROR + ); + } } - if (!empty($initializedIndexingConfigurations)) { + if (!empty($messagesForConfigurations)) { $messageLabel = 'solr.backend.index_queue_module.flashmessage.initialize.success'; $titleLabel = 'solr.backend.index_queue_module.flashmessage.initialize.title'; $this->addFlashMessage( @@ -174,16 +231,18 @@ public function initializeIndexQueueAction(): ResponseInterface */ public function resetLogErrorsAction(): ResponseInterface { - $resetResult = $this->indexQueue->resetAllErrors(); + foreach ($this->enabledIndexQueues as $queue) { + $resetResult = $queue->resetAllErrors(); - $label = 'solr.backend.index_queue_module.flashmessage.success.reset_errors'; - $severity = FlashMessage::OK; - if (!$resetResult) { - $label = 'solr.backend.index_queue_module.flashmessage.error.reset_errors'; - $severity = FlashMessage::ERROR; - } + $label = 'solr.backend.index_queue_module.flashmessage.success.reset_errors'; + $severity = FlashMessage::OK; + if (!$resetResult) { + $label = 'solr.backend.index_queue_module.flashmessage.error.reset_errors'; + $severity = FlashMessage::ERROR; + } - $this->addIndexQueueFlashMessage($label, $severity); + $this->addIndexQueueFlashMessage($label, $severity); + } return new RedirectResponse($this->uriBuilder->uriFor('index'), 303); } @@ -269,4 +328,23 @@ protected function addIndexQueueFlashMessage(string $label, int $severity) { $this->addFlashMessage(LocalizationUtility::translate($label, 'Solr'), LocalizationUtility::translate('solr.backend.index_queue_module.flashmessage.title', 'Solr'), $severity); } + + /** + * Get index queues + * + * @return QueueInterface[] + */ + protected function getIndexQueues(): array + { + $queues = []; + $configuration = $this->selectedSite->getSolrConfiguration(); + foreach ($configuration->getEnabledIndexQueueConfigurationNames() as $indexingConfiguration) { + $indexQueueClass = $configuration->getIndexQueueClassByConfigurationName($indexingConfiguration); + if (!isset($queues[$indexQueueClass])) { + $queues[$indexQueueClass] = GeneralUtility::makeInstance($indexQueueClass); + } + } + + return $queues; + } } diff --git a/Classes/Domain/Index/IndexService.php b/Classes/Domain/Index/IndexService.php index b4fc78a34..ea8d8ecec 100644 --- a/Classes/Domain/Index/IndexService.php +++ b/Classes/Domain/Index/IndexService.php @@ -20,6 +20,7 @@ use ApacheSolrForTypo3\Solr\IndexQueue\Indexer; use ApacheSolrForTypo3\Solr\IndexQueue\Item; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\Task\IndexQueueWorkerTask; @@ -48,9 +49,9 @@ class IndexService protected ?IndexQueueWorkerTask $contextTask = null; /** - * @var Queue + * @var QueueInterface */ - protected Queue $indexQueue; + protected QueueInterface $indexQueue; /** * @var Dispatcher @@ -71,7 +72,7 @@ class IndexService */ public function __construct( Site $site, - Queue $queue = null, + QueueInterface $queue = null, Dispatcher $dispatcher = null, SolrLogManager $solrLogManager = null ) { diff --git a/Classes/Domain/Index/Queue/GarbageRemover/AbstractStrategy.php b/Classes/Domain/Index/Queue/GarbageRemover/AbstractStrategy.php index 311c2544a..d0cb6b4f4 100644 --- a/Classes/Domain/Index/Queue/GarbageRemover/AbstractStrategy.php +++ b/Classes/Domain/Index/Queue/GarbageRemover/AbstractStrategy.php @@ -16,11 +16,12 @@ namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue\GarbageRemover; use ApacheSolrForTypo3\Solr\ConnectionManager; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\GarbageCollectorPostProcessor; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -30,9 +31,9 @@ abstract class AbstractStrategy { /** - * @var Queue + * @var QueueInterface */ - protected Queue $queue; + protected QueueInterface $queue; /** * @var ConnectionManager @@ -41,11 +42,11 @@ abstract class AbstractStrategy /** * AbstractStrategy constructor. - * @param Queue|null $queue + * @param QueueInterface|null $queue * @param ConnectionManager|null $connectionManager */ public function __construct( - Queue $queue = null, + QueueInterface $queue = null, ConnectionManager $connectionManager = null ) { $this->queue = $queue ?? GeneralUtility::makeInstance(Queue::class); diff --git a/Classes/Domain/Index/Queue/QueueInitializationService.php b/Classes/Domain/Index/Queue/QueueInitializationService.php index 459c38127..afe3a8347 100644 --- a/Classes/Domain/Index/Queue/QueueInitializationService.php +++ b/Classes/Domain/Index/Queue/QueueInitializationService.php @@ -18,14 +18,15 @@ namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue; use ApacheSolrForTypo3\Solr\Domain\Site\Site; +use ApacheSolrForTypo3\Solr\Exception\Index\Queue\InvalidIndexQueueInitizalizationPostProcessorException; use ApacheSolrForTypo3\Solr\IndexQueue\InitializationPostProcessor; use ApacheSolrForTypo3\Solr\IndexQueue\Initializer\AbstractInitializer; -use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInitializationServiceAwareInterface; +use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface; use Doctrine\DBAL\ConnectionException; use Doctrine\DBAL\Exception as DBALException; use Throwable; use TYPO3\CMS\Core\Utility\GeneralUtility; -use UnexpectedValueException; /** * The queue initialization service is responsible to run the initialization of the index queue for a combination of sites @@ -36,17 +37,14 @@ */ class QueueInitializationService { - /** - * @var Queue - */ - protected Queue $queue; + protected bool $clearQueueOnInitialization = true; /** - * QueueInitializationService constructor. + * @param bool $clearQueueOnInitialization */ - public function __construct(Queue $queue) + public function setClearQueueOnInitialization(bool $clearQueueOnInitialization): void { - $this->queue = $queue; + $this->clearQueueOnInitialization = $clearQueueOnInitialization; } /** @@ -98,6 +96,7 @@ public function initializeBySitesAndConfigurations(array $sites, array $indexing * @throws ConnectionException * @throws Throwable * @throws DBALException + * @throws InvalidIndexQueueInitizalizationPostProcessorException */ public function initializeBySiteAndIndexConfigurations(Site $site, array $indexingConfigurationNames): array { @@ -118,7 +117,10 @@ public function initializeBySiteAndIndexConfigurations(Site $site, array $indexi if ($indexQueueInitializationPostProcessor instanceof InitializationPostProcessor) { $indexQueueInitializationPostProcessor->postProcessIndexQueueInitialization($site, $indexingConfigurationNames, $initializationStatus); } else { - throw new UnexpectedValueException(get_class($indexQueueInitializationPostProcessor) . ' must implement interface ' . InitializationPostProcessor::class, 1345815561); + throw new InvalidIndexQueueInitizalizationPostProcessorException( + get_class($indexQueueInitializationPostProcessor) . ' must implement interface ' . InitializationPostProcessor::class, + 1345815561 + ); } } @@ -138,10 +140,21 @@ public function initializeBySiteAndIndexConfigurations(Site $site, array $indexi */ protected function applyInitialization(Site $site, string $indexingConfigurationName): bool { + $solrConfiguration = $site->getSolrConfiguration(); + + /** @var QueueInterface $queue */ + $queue = GeneralUtility::makeInstance( + $solrConfiguration->getIndexQueueClassByConfigurationName($indexingConfigurationName) + ); + if ($queue instanceof QueueInitializationServiceAwareInterface) { + $queue->setQueueInitializationService($this); + } + // clear queue - $this->queue->deleteItemsBySite($site, $indexingConfigurationName); + if ($this->clearQueueOnInitialization) { + $queue->deleteItemsBySite($site, $indexingConfigurationName); + } - $solrConfiguration = $site->getSolrConfiguration(); $type = $solrConfiguration->getIndexQueueTypeOrFallbackToConfigurationName($indexingConfigurationName); $initializerClass = $solrConfiguration->getIndexQueueInitializerClassByConfigurationName($indexingConfigurationName); $indexConfiguration = $solrConfiguration->getIndexQueueConfigurationByName($indexingConfigurationName); diff --git a/Classes/Domain/Index/Queue/QueueItemRepository.php b/Classes/Domain/Index/Queue/QueueItemRepository.php index a0e7ff6e4..e3aa88146 100644 --- a/Classes/Domain/Index/Queue/QueueItemRepository.php +++ b/Classes/Domain/Index/Queue/QueueItemRepository.php @@ -19,6 +19,7 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\IndexQueue\Item; +use ApacheSolrForTypo3\Solr\IndexQueue\ItemInterface; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\System\Records\AbstractRepository; use Doctrine\DBAL\ConnectionException; @@ -150,12 +151,12 @@ public function flushErrorsBySite(Site $site): int /** * Flushes the error for a single item. * - * @param Item $item + * @param ItemInterface $item * @return int affected rows * * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function flushErrorByItem(Item $item): int + public function flushErrorByItem(ItemInterface $item): int { $queryBuilder = $this->getQueryBuilder(); return (int)$this->getPreparedFlushErrorQuery($queryBuilder) @@ -411,16 +412,20 @@ public function containsItem(string $itemType, int $itemUid): bool * @param string $itemType The item's type, usually a table name. * @param int $itemUid The item's uid * @param int $rootPageId + * @param string $indexingConfiguration * @return bool TRUE if the item is found in the queue, FALSE otherwise * * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function containsItemWithRootPageId(string $itemType, int $itemUid, int $rootPageId): bool + public function containsItemWithRootPageId(string $itemType, int $itemUid, int $rootPageId, string $indexingConfiguration): bool { $queryBuilder = $this->getQueryBuilderForContainsMethods($itemType, $itemUid); return (bool)$queryBuilder - ->andWhere(/** @scrutinizer ignore-type */ $queryBuilder->expr()->eq('root', $rootPageId)) + ->andWhere( + $queryBuilder->expr()->eq('root', $rootPageId), + $queryBuilder->expr()->eq('indexing_configuration', $queryBuilder->createNamedParameter($indexingConfiguration)) + ) ->execute() ->fetchOne(); } @@ -996,12 +1001,12 @@ public function markItemAsFailed($item, string $errorMessage = ''): int /** * Sets the timestamp of when an item last has been indexed. * - * @param Item $item + * @param ItemInterface $item * @return int affected rows * * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function updateIndexTimeByItem(Item $item): int + public function updateIndexTimeByItem(ItemInterface $item): int { $queryBuilder = $this->getQueryBuilder(); return (int)$queryBuilder @@ -1014,13 +1019,13 @@ public function updateIndexTimeByItem(Item $item): int /** * Sets the change timestamp of an item. * - * @param Item $item + * @param ItemInterface $item * @param int $changedTime * @return int affected rows * * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function updateChangedTimeByItem(Item $item, int $changedTime = 0): int + public function updateChangedTimeByItem(ItemInterface $item, int $changedTime = 0): int { $queryBuilder = $this->getQueryBuilder(); return (int)$queryBuilder diff --git a/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php b/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php index 0a4f60a9c..f4b460632 100644 --- a/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php +++ b/Classes/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolver.php @@ -19,11 +19,11 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache; use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration; use ApacheSolrForTypo3\Solr\System\Page\Rootline; use Doctrine\DBAL\Driver\Exception as DBALDriverException; -use InvalidArgumentException; use RuntimeException; use Throwable; use TYPO3\CMS\Backend\Utility\BackendUtility; diff --git a/Classes/Domain/Index/Queue/Statistic/QueueStatisticsRepository.php b/Classes/Domain/Index/Queue/Statistic/QueueStatisticsRepository.php index 1e1f41a11..111256331 100644 --- a/Classes/Domain/Index/Queue/Statistic/QueueStatisticsRepository.php +++ b/Classes/Domain/Index/Queue/Statistic/QueueStatisticsRepository.php @@ -29,10 +29,12 @@ */ class QueueStatisticsRepository extends AbstractRepository { - /** - * @var string - */ protected string $table = 'tx_solr_indexqueue_item'; + protected string $columnIndexed = 'indexed'; + protected string $columnIndexingConfiguration = 'indexing_configuration'; + protected string $columnChanged = 'changed'; + protected string $columnErrors = 'errors'; + protected string $columnRootpage = 'root'; /** * Extracts the number of pending, indexed and erroneous items from the @@ -53,25 +55,28 @@ public function findOneByRootPidAndOptionalIndexingConfigurationName( $queryBuilder = $this->getQueryBuilder(); $queryBuilder ->add('select', vsprintf('(%s < %s) AS %s', [ - $queryBuilder->quoteIdentifier('indexed'), - $queryBuilder->quoteIdentifier('changed'), + $queryBuilder->quoteIdentifier($this->columnIndexed), + $queryBuilder->quoteIdentifier($this->columnChanged), $queryBuilder->quoteIdentifier('pending'), ]), true) ->add('select', vsprintf('(%s) AS %s', [ - $queryBuilder->expr()->notLike('errors', $queryBuilder->createNamedParameter('')), + $queryBuilder->expr()->notLike($this->columnErrors, $queryBuilder->createNamedParameter('')), $queryBuilder->quoteIdentifier('failed'), ]), true) ->add('select', $queryBuilder->expr()->count('*', 'count'), true) ->from($this->table) ->where( /** @scrutinizer ignore-type */ - $queryBuilder->expr()->eq('root', $queryBuilder->createNamedParameter($rootPid, PDO::PARAM_INT)) + $queryBuilder->expr()->eq($this->columnRootpage, $queryBuilder->createNamedParameter($rootPid, PDO::PARAM_INT)) )->groupBy('pending', 'failed'); if (!empty($indexingConfigurationName)) { $queryBuilder->andWhere( /** @scrutinizer ignore-type */ - $queryBuilder->expr()->eq('indexing_configuration', $queryBuilder->createNamedParameter($indexingConfigurationName)) + $queryBuilder->expr()->eq( + $this->columnIndexingConfiguration, + $queryBuilder->createNamedParameter($indexingConfigurationName) + ) ); } diff --git a/Classes/Domain/Index/Queue/UpdateHandler/DataUpdateHandler.php b/Classes/Domain/Index/Queue/UpdateHandler/DataUpdateHandler.php index eb27c5b4d..1adaa06e9 100644 --- a/Classes/Domain/Index/Queue/UpdateHandler/DataUpdateHandler.php +++ b/Classes/Domain/Index/Queue/UpdateHandler/DataUpdateHandler.php @@ -22,6 +22,7 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver; use ApacheSolrForTypo3\Solr\Domain\Site\SiteInterface; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\FrontendEnvironment; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; @@ -31,7 +32,6 @@ use ApacheSolrForTypo3\Solr\Util; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use Throwable; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; diff --git a/Classes/Domain/Index/Queue/UpdateHandler/EventListener/AbstractBaseEventListener.php b/Classes/Domain/Index/Queue/UpdateHandler/EventListener/AbstractBaseEventListener.php index a0abef917..a042b8caf 100644 --- a/Classes/Domain/Index/Queue/UpdateHandler/EventListener/AbstractBaseEventListener.php +++ b/Classes/Domain/Index/Queue/UpdateHandler/EventListener/AbstractBaseEventListener.php @@ -21,8 +21,8 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\EventListener\Events\ProcessingFinishedEventInterface; use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\DataUpdateEventInterface; use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\GarbageHandler; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration; -use InvalidArgumentException; use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/Domain/Search/LastSearches/LastSearchesRepository.php b/Classes/Domain/Search/LastSearches/LastSearchesRepository.php index d6c07e8d3..dd494b2a1 100644 --- a/Classes/Domain/Search/LastSearches/LastSearchesRepository.php +++ b/Classes/Domain/Search/LastSearches/LastSearchesRepository.php @@ -15,10 +15,10 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\LastSearches; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Records\AbstractRepository; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use function json_encode; class LastSearchesRepository extends AbstractRepository diff --git a/Classes/Domain/Search/Query/ParameterBuilder/Operator.php b/Classes/Domain/Search/Query/ParameterBuilder/Operator.php index e05f84d1a..50b18b71c 100644 --- a/Classes/Domain/Search/Query/ParameterBuilder/Operator.php +++ b/Classes/Domain/Search/Query/ParameterBuilder/Operator.php @@ -15,7 +15,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; /** * The Operator ParameterProvider is responsible to build the solr query parameters diff --git a/Classes/Domain/Search/ResultSet/Facets/FacetRegistry.php b/Classes/Domain/Search/ResultSet/Facets/FacetRegistry.php index f755e4264..e1e5e7bbb 100644 --- a/Classes/Domain/Search/ResultSet/Facets/FacetRegistry.php +++ b/Classes/Domain/Search/ResultSet/Facets/FacetRegistry.php @@ -22,8 +22,8 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup\QueryGroupPackage; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\RangeBased\DateRange\DateRangePackage; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\RangeBased\NumericRange\NumericRangePackage; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Object\AbstractClassRegistry; -use InvalidArgumentException; /** * Class FacetRegistry diff --git a/Classes/Domain/Search/ResultSet/Facets/InvalidFacetPackageException.php b/Classes/Domain/Search/ResultSet/Facets/InvalidFacetPackageException.php index 0c3b80408..fa5269346 100644 --- a/Classes/Domain/Search/ResultSet/Facets/InvalidFacetPackageException.php +++ b/Classes/Domain/Search/ResultSet/Facets/InvalidFacetPackageException.php @@ -15,6 +15,8 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets; -class InvalidFacetPackageException extends \Exception +use ApacheSolrForTypo3\Solr\Exception; + +class InvalidFacetPackageException extends Exception { } diff --git a/Classes/Domain/Search/ResultSet/Facets/InvalidFacetParserException.php b/Classes/Domain/Search/ResultSet/Facets/InvalidFacetParserException.php index b0509491c..623eff19b 100644 --- a/Classes/Domain/Search/ResultSet/Facets/InvalidFacetParserException.php +++ b/Classes/Domain/Search/ResultSet/Facets/InvalidFacetParserException.php @@ -15,6 +15,8 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets; -class InvalidFacetParserException extends \Exception +use ApacheSolrForTypo3\Solr\Exception; + +class InvalidFacetParserException extends Exception { } diff --git a/Classes/Domain/Search/ResultSet/Facets/InvalidQueryBuilderException.php b/Classes/Domain/Search/ResultSet/Facets/InvalidQueryBuilderException.php index 4022e23fa..242c37263 100644 --- a/Classes/Domain/Search/ResultSet/Facets/InvalidQueryBuilderException.php +++ b/Classes/Domain/Search/ResultSet/Facets/InvalidQueryBuilderException.php @@ -15,6 +15,8 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets; -class InvalidQueryBuilderException extends \Exception +use ApacheSolrForTypo3\Solr\Exception; + +class InvalidQueryBuilderException extends Exception { } diff --git a/Classes/Domain/Search/ResultSet/Facets/InvalidUrlDecoderException.php b/Classes/Domain/Search/ResultSet/Facets/InvalidUrlDecoderException.php index 58d27d7a0..0c8992f20 100644 --- a/Classes/Domain/Search/ResultSet/Facets/InvalidUrlDecoderException.php +++ b/Classes/Domain/Search/ResultSet/Facets/InvalidUrlDecoderException.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets; -use Exception; +use ApacheSolrForTypo3\Solr\Exception; class InvalidUrlDecoderException extends Exception { diff --git a/Classes/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoder.php b/Classes/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoder.php index 79706bcfb..95381e115 100644 --- a/Classes/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoder.php +++ b/Classes/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoder.php @@ -18,7 +18,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\RangeBased\NumericRange; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\FacetUrlDecoderInterface; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; /** * Parser to build Solr range queries from tx_solr[filter] diff --git a/Classes/Domain/Search/ResultSet/Facets/RequirementsService.php b/Classes/Domain/Search/ResultSet/Facets/RequirementsService.php index fad625e94..24cb7abb4 100644 --- a/Classes/Domain/Search/ResultSet/Facets/RequirementsService.php +++ b/Classes/Domain/Search/ResultSet/Facets/RequirementsService.php @@ -15,6 +15,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -83,12 +84,13 @@ protected function getRequirementMet(AbstractFacet $facet, $requirement = []) * * @param string $facetNameToCheckRequirementsOn * @return AbstractFacetItem[] + * @throws InvalidArgumentException */ protected function getSelectedItemValues(AbstractFacet $facet, $facetNameToCheckRequirementsOn) { $facetToCheckRequirements = $facet->getResultSet()->getFacets()->getByName($facetNameToCheckRequirementsOn)->getByPosition(0); if (!$facetToCheckRequirements instanceof AbstractFacet) { - throw new \InvalidArgumentException('Requirement for unexisting facet configured'); + throw new InvalidArgumentException('Requirement for unexisting facet configured'); } if (!$facetToCheckRequirements->getIsUsed()) { diff --git a/Classes/Domain/Search/ResultSet/Result/Parser/ResultParserRegistry.php b/Classes/Domain/Search/ResultSet/Result/Parser/ResultParserRegistry.php index 3109abf8c..0c21251fd 100644 --- a/Classes/Domain/Search/ResultSet/Result/Parser/ResultParserRegistry.php +++ b/Classes/Domain/Search/ResultSet/Result/Parser/ResultParserRegistry.php @@ -18,7 +18,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\Parser; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/Domain/Search/ResultSet/Result/SearchResultBuilder.php b/Classes/Domain/Search/ResultSet/Result/SearchResultBuilder.php index e722370cc..d6f885f59 100644 --- a/Classes/Domain/Search/ResultSet/Result/SearchResultBuilder.php +++ b/Classes/Domain/Search/ResultSet/Result/SearchResultBuilder.php @@ -17,8 +17,8 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Solr\Document\Document; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** diff --git a/Classes/Domain/Search/ResultSet/Sorting/Sorting.php b/Classes/Domain/Search/ResultSet/Sorting/Sorting.php index 27e750f0d..1304b1ba0 100644 --- a/Classes/Domain/Search/ResultSet/Sorting/Sorting.php +++ b/Classes/Domain/Search/ResultSet/Sorting/Sorting.php @@ -18,7 +18,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Sorting; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; /** * Class Sorting diff --git a/Classes/Domain/Search/ResultSet/Sorting/SortingHelper.php b/Classes/Domain/Search/ResultSet/Sorting/SortingHelper.php index 64935d3e3..86d8ecb8f 100644 --- a/Classes/Domain/Search/ResultSet/Sorting/SortingHelper.php +++ b/Classes/Domain/Search/ResultSet/Sorting/SortingHelper.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Sorting; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** diff --git a/Classes/Domain/Site/Exception/InvalidSiteConfigurationCombinationException.php b/Classes/Domain/Site/Exception/InvalidSiteConfigurationCombinationException.php index 3b43b5217..cf95df0dc 100644 --- a/Classes/Domain/Site/Exception/InvalidSiteConfigurationCombinationException.php +++ b/Classes/Domain/Site/Exception/InvalidSiteConfigurationCombinationException.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\Domain\Site\Exception; -use Exception; +use ApacheSolrForTypo3\Solr\Exception; class InvalidSiteConfigurationCombinationException extends Exception { diff --git a/Classes/Domain/Site/Exception/InvalidSiteRootPageException.php b/Classes/Domain/Site/Exception/InvalidSiteRootPageException.php new file mode 100644 index 000000000..143cd468b --- /dev/null +++ b/Classes/Domain/Site/Exception/InvalidSiteRootPageException.php @@ -0,0 +1,24 @@ +eventDispatcher = $eventDispatcher; + $this->dataMapFactory = $dataMapFactory; + } + + public function entityPersisted(EntityPersistedEvent $event): void + { + $object = $event->getObject(); + $tableName = $this->getTableName($object); + if (!$this->skipMonitoringOfTable($tableName)) { + // Entity might turn inaccessible + $this->eventDispatcher->dispatch(new RecordGarbageCheckEvent($object->getUid(), $tableName)); + // Entity added/updated + $this->eventDispatcher->dispatch(new RecordUpdatedEvent($object->getUid(), $tableName)); + } + } + + public function entityRemoved(EntityRemovedFromPersistenceEvent $event): void + { + $object = $event->getObject(); + $tableName = $this->getTableName($object); + if (!$this->skipMonitoringOfTable($tableName)) { + $this->eventDispatcher->dispatch(new RecordDeletedEvent($object->getUid(), $tableName)); + } + } + + protected function getTableName(object $object): string + { + $dataMap = $this->dataMapFactory->buildDataMap(get_class($object)); + return $dataMap->getTableName(); + } +} diff --git a/Classes/Exception/Index/Queue/InvalidIndexQueueInitizalizationPostProcessorException.php b/Classes/Exception/Index/Queue/InvalidIndexQueueInitizalizationPostProcessorException.php new file mode 100644 index 000000000..4d244ed36 --- /dev/null +++ b/Classes/Exception/Index/Queue/InvalidIndexQueueInitizalizationPostProcessorException.php @@ -0,0 +1,27 @@ + */ -class Item +class Item implements ItemInterface, MountPointAwareItemInterface { - const STATE_BLOCKED = -1; - - const STATE_PENDING = 0; - - const STATE_INDEXED = 1; - /** * The item's uid in the index queue (tx_solr_indexqueue_item.uid) * @@ -115,6 +109,13 @@ class Item */ protected ?int $recordUid = null; + /** + * The indexing priority + * + * @var int + */ + protected int $indexingPriority = 0; + /** * The record itself * @@ -169,6 +170,7 @@ public function __construct( $this->indexingConfigurationName = $itemMetaData['indexing_configuration'] ?? ''; $this->hasIndexingProperties = (boolean)($itemMetaData['has_indexing_properties'] ?? false); + $this->indexingPriority = (int)($itemMetaData['indexing_priority'] ?? 0); if (!empty($fullRecord)) { $this->record = $fullRecord; @@ -181,7 +183,7 @@ public function __construct( /** * Getter for Index Queue UID * - * @return int + * @return int|null */ public function getIndexQueueUid(): ?int { @@ -201,7 +203,7 @@ public function getRootPageUid(): ?int /** * Returns mount point identifier * - * @return string + * @return string|null */ public function getMountPointIdentifier(): ?string { @@ -233,6 +235,8 @@ public function getHasErrors(): bool } /** + * Items state: pending, indexed, blocked + * * @return int */ public function getState(): int @@ -263,17 +267,17 @@ public function getSite(): ?Site /** * Returns the type/tablename of the queue record. * - * @return mixed|string + * @return string|null */ - public function getType() + public function getType(): ?string { return $this->type; } /** - * @param $type + * @param string $type */ - public function setType($type) + public function setType(string $type): void { $this->type = $type; } @@ -281,9 +285,9 @@ public function setType($type) /** * Returns the name of the index configuration that was used to create this record. * - * @return mixed|string + * @return string */ - public function getIndexingConfigurationName() + public function getIndexingConfigurationName(): string { return $this->indexingConfigurationName; } @@ -291,7 +295,7 @@ public function getIndexingConfigurationName() /** * @param string $indexingConfigurationName */ - public function setIndexingConfigurationName(string $indexingConfigurationName) + public function setIndexingConfigurationName(string $indexingConfigurationName): void { $this->indexingConfigurationName = $indexingConfigurationName; } @@ -299,9 +303,9 @@ public function setIndexingConfigurationName(string $indexingConfigurationName) /** * Returns the timestamp when this queue item was changed. * - * @return int|mixed + * @return int|null */ - public function getChanged() + public function getChanged(): ?int { return $this->changed; } @@ -309,9 +313,9 @@ public function getChanged() /** * Returns the timestamp when this queue item was indexed. * - * @return int|mixed + * @return int|null */ - public function getIndexed() + public function getIndexed(): ?int { return $this->indexed; } @@ -321,7 +325,7 @@ public function getIndexed() * * @param int $changed */ - public function setChanged(int $changed) + public function setChanged(int $changed): void { $this->changed = $changed; } @@ -329,13 +333,14 @@ public function setChanged(int $changed) /** * Returns the uid of related record (item_uid). * - * @return mixed + * @return int The uid of the item record, usually an integer uid, could be a + * different value for non-database-record types. */ public function getRecordUid() { $this->getRecord(); - return $this->record['uid']; + return (int)$this->record['uid']; } /** @@ -365,7 +370,7 @@ public function getRecord(): array * * @param array $record */ - public function setRecord(array $record) + public function setRecord(array $record): void { $this->record = $record; } @@ -386,7 +391,7 @@ public function getRecordPageId(): int * Stores the indexing properties. * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function storeIndexingProperties() + public function storeIndexingProperties(): void { $this->indexQueueIndexingPropertyRepository->removeByRootPidAndIndexQueueUid((int)($this->rootPageUid), (int)($this->indexQueueUid)); @@ -408,7 +413,7 @@ public function hasIndexingProperties(): bool /** * Writes all indexing properties. */ - protected function writeIndexingProperties() + protected function writeIndexingProperties(): void { $properties = []; foreach ($this->indexingProperties as $propertyKey => $propertyValue) { @@ -444,7 +449,7 @@ public function hasIndexingProperty(string $key): bool * @throws DBALDriverException * @throws DBALException */ - public function loadIndexingProperties() + public function loadIndexingProperties(): void { if ($this->indexingPropertiesLoaded) { return; @@ -471,7 +476,7 @@ public function loadIndexingProperties() * @throws DBALDriverException * @throws DBALException */ - public function setIndexingProperty(string $key, $value) + public function setIndexingProperty(string $key, $value): void { // make sure to not interfere with existing indexing properties $this->loadIndexingProperties(); @@ -540,4 +545,14 @@ public function getIndexingPropertyKeys(): array return array_keys($this->indexingProperties); } + + /** + * Returns the index priority. + * + * @return int + */ + public function getIndexPriority(): int + { + return $this->indexingPriority; + } } diff --git a/Classes/IndexQueue/ItemInterface.php b/Classes/IndexQueue/ItemInterface.php new file mode 100644 index 000000000..3bb37a249 --- /dev/null +++ b/Classes/IndexQueue/ItemInterface.php @@ -0,0 +1,117 @@ + */ -class NoPidException extends \Exception +class NoPidException extends Exception { } diff --git a/Classes/IndexQueue/Queue.php b/Classes/IndexQueue/Queue.php index e1abe0ee9..a4d305a33 100644 --- a/Classes/IndexQueue/Queue.php +++ b/Classes/IndexQueue/Queue.php @@ -25,13 +25,13 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Queue\Statistic\QueueStatisticsRepository; use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\FrontendEnvironment; use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use Doctrine\DBAL\ConnectionException; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use Throwable; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -42,7 +42,7 @@ * * @author Ingo Renner */ -class Queue +class Queue implements QueueInterface, QueueInitializationServiceAwareInterface { /** * @var RootPageResolver @@ -81,26 +81,26 @@ class Queue /** * Queue constructor. - * @param RootPageResolver|null $rootPageResolver - * @param ConfigurationAwareRecordService|null $recordService - * @param QueueItemRepository|null $queueItemRepository - * @param QueueStatisticsRepository|null $queueStatisticsRepository - * @param QueueInitializationService|null $queueInitializationService + * + * @param ?RootPageResolver|null $rootPageResolver + * @param ?ConfigurationAwareRecordService|null $recordService + * @param ?QueueItemRepository|null $queueItemRepository + * @param ?QueueStatisticsRepository|null $queueStatisticsRepository + * @param ?FrontendEnvironment|null $frontendEnvironment */ public function __construct( - RootPageResolver $rootPageResolver = null, - ConfigurationAwareRecordService $recordService = null, - QueueItemRepository $queueItemRepository = null, - QueueStatisticsRepository $queueStatisticsRepository = null, - QueueInitializationService $queueInitializationService = null, - FrontendEnvironment $frontendEnvironment = null + ?RootPageResolver $rootPageResolver = null, + ?ConfigurationAwareRecordService $recordService = null, + ?QueueItemRepository $queueItemRepository = null, + ?QueueStatisticsRepository $queueStatisticsRepository = null, + ?FrontendEnvironment $frontendEnvironment = null ) { $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__); + $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class); $this->recordService = $recordService ?? GeneralUtility::makeInstance(ConfigurationAwareRecordService::class); $this->queueItemRepository = $queueItemRepository ?? GeneralUtility::makeInstance(QueueItemRepository::class); $this->queueStatisticsRepository = $queueStatisticsRepository ?? GeneralUtility::makeInstance(QueueStatisticsRepository::class); - $this->queueInitializationService = $queueInitializationService ?? GeneralUtility::makeInstance(QueueInitializationService::class, /** @scrutinizer ignore-type */ $this); $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class); } @@ -150,14 +150,46 @@ public function getLastIndexedItemId(int $rootPageId): int return $lastIndexedItemId; } + /** + * @param QueueInitializationService $queueInitializationService + */ + public function setQueueInitializationService(QueueInitializationService $queueInitializationService): void + { + $this->queueInitializationService = $queueInitializationService; + } /** * @return QueueInitializationService */ - public function getInitializationService(): QueueInitializationService + public function getQueueInitializationService(): QueueInitializationService { + if (!isset($this->queueInitializationService)) { + trigger_error( + 'queueInitializationService is no longer initalized automatically, till EXT:solr supports DI' + . ' the QueueInitializationService has to be set manually, fallback will be removed in v13.', + E_USER_DEPRECATED + ); + $this->queueInitializationService = GeneralUtility::makeInstance(QueueInitializationService::class); + } + return $this->queueInitializationService; } + /** + * @return QueueInitializationService + * @deprecated Queue->getInitializationService is deprecated and will be removed in v12. + * Use Queue->getQueueInitializationService instead or create a fresh instance. + */ + public function getInitializationService(): QueueInitializationService + { + trigger_error( + 'Queue->getInitializationService is deprecated and will be removed in v13.' + . ' Use Queue->getQueueInitializationService instead or create a fresh instance.', + E_USER_DEPRECATED + ); + + return $this->getQueueInitializationService(); + } + /** * Marks an item as needing (re)indexing. * @@ -169,12 +201,13 @@ public function getInitializationService(): QueueInitializationService * @param string $itemType The item's type, usually a table name. * @param int|string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types. * @param int $forcedChangeTime The change time for the item if set, otherwise value from getItemChangedTime() is used. + * @param array|null $validLanguageUids List of valid language uids, others will be ignored. Depends on your queue implementation, may be irrelevant * @return int Number of updated/created items * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException * @throws Throwable */ - public function updateItem(string $itemType, $itemUid, int $forcedChangeTime = 0): int + public function updateItem(string $itemType, $itemUid, int $forcedChangeTime = 0, ?array $validLanguageUids = null): int { $updateCount = $this->updateOrAddItemForAllRelatedRootPages($itemType, $itemUid, $forcedChangeTime); return $this->postProcessIndexQueueUpdateItem($itemType, $itemUid, $updateCount, $forcedChangeTime); @@ -195,7 +228,7 @@ protected function updateOrAddItemForAllRelatedRootPages(string $itemType, $item { $updateCount = 0; try { - $rootPageIds = $this->rootPageResolver->getResponsibleRootPageIds($itemType, $itemUid); + $rootPageIds = $this->rootPageResolver->getResponsibleRootPageIds($itemType, (int)$itemUid); } catch (InvalidArgumentException $e) { $this->deleteItem($itemType, $itemUid); return 0; @@ -220,11 +253,11 @@ protected function updateOrAddItemForAllRelatedRootPages(string $itemType, $item continue; } $indexingPriority = $solrConfiguration->getIndexQueueIndexingPriorityByConfigurationName($indexingConfiguration); - $itemInQueueForRootPage = $this->containsItemWithRootPageId($itemType, $itemUid, $rootPageId); + $itemInQueueForRootPage = $this->containsItemWithRootPageId($itemType, $itemUid, $rootPageId, $indexingConfiguration); if ($itemInQueueForRootPage) { // update changed time if that item is in the queue already - $changedTime = ($forcedChangeTime > 0) ? $forcedChangeTime : $this->getItemChangedTime($itemType, $itemUid); - $updatedRows = $this->queueItemRepository->updateExistingItemByItemTypeAndItemUidAndRootPageId($itemType, $itemUid, $rootPageId, $changedTime, $indexingConfiguration, $indexingPriority); + $changedTime = ($forcedChangeTime > 0) ? $forcedChangeTime : $this->getItemChangedTime($itemType, (int)$itemUid); + $updatedRows = $this->queueItemRepository->updateExistingItemByItemTypeAndItemUidAndRootPageId($itemType, (int)$itemUid, $rootPageId, $changedTime, $indexingConfiguration, $indexingPriority); } else { // add the item since it's not in the queue yet $updatedRows = $this->addNewItem($itemType, $itemUid, $indexingConfiguration, $rootPageId, $indexingPriority); @@ -257,7 +290,7 @@ protected function postProcessIndexQueueUpdateItem( foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueUpdateItem'] as $classReference) { $updateHandler = $this->getHookImplementation($classReference); - $updateCount = $updateHandler->postProcessIndexQueueUpdateItem($itemType, $itemUid, $updateCount, $forcedChangeTime); + $updateCount = $updateHandler->postProcessIndexQueueUpdateItem($itemType, (int)$itemUid, $updateCount, $forcedChangeTime); } return $updateCount; @@ -288,10 +321,10 @@ public function getErrorsBySite(Site $site): array /** * Resets all the errors for all index queue items. * - * @return mixed + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function resetAllErrors() + public function resetAllErrors(): int { return $this->queueItemRepository->flushAllErrors(); } @@ -300,10 +333,10 @@ public function resetAllErrors() * Resets the errors in the index queue for a specific site * * @param Site $site - * @return mixed + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function resetErrorsBySite(Site $site) + public function resetErrorsBySite(Site $site): int { return $this->queueItemRepository->flushErrorsBySite($site); } @@ -311,11 +344,11 @@ public function resetErrorsBySite(Site $site) /** * Resets the error in the index queue for a specific item * - * @param Item $item - * @return mixed + * @param ItemInterface $item + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function resetErrorByItem(Item $item) + public function resetErrorByItem(ItemInterface $item): int { return $this->queueItemRepository->flushErrorByItem($item); } @@ -326,8 +359,7 @@ public function resetErrorByItem(Item $item) * Not meant for public use. * * @param string $itemType The item's type, usually a table name. - * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * @param int|string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types. * @param string $indexingConfiguration The item's indexing configuration to use. * Optional, overwrites existing / determined configuration. * @param int $rootPageId @@ -348,31 +380,30 @@ private function addNewItem( $additionalRecordFields = ', doktype, uid'; } - $record = $this->getRecordCached($itemType, $itemUid, $additionalRecordFields); + $record = $this->getRecordCached($itemType, (int)$itemUid, $additionalRecordFields); if (empty($record) || ($itemType === 'pages' && !$this->frontendEnvironment->isAllowedPageType($record, $indexingConfiguration))) { return 0; } - $changedTime = $this->getItemChangedTime($itemType, $itemUid); + $changedTime = $this->getItemChangedTime($itemType, (int)$itemUid); - return $this->queueItemRepository->add($itemType, $itemUid, $rootPageId, $changedTime, $indexingConfiguration, $indexingPriority); + return $this->queueItemRepository->add($itemType, (int)$itemUid, $rootPageId, $changedTime, $indexingConfiguration, $indexingPriority); } /** * Get record to be added in addNewItem * * @param string $itemType The item's type, usually a table name. - * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * @param int $itemUid The item's uid * @param string $additionalRecordFields for sql-query * * @return array|null */ - protected function getRecordCached(string $itemType, $itemUid, string $additionalRecordFields): ?array + protected function getRecordCached(string $itemType, int $itemUid, string $additionalRecordFields): ?array { $cache = GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */ 'runtime'); - $cacheId = md5('Queue' . ':' . 'getRecordCached' . ':' . $itemType . ':' . $itemUid . ':' . 'pid' . $additionalRecordFields); + $cacheId = md5('Queue' . ':' . 'getRecordCached' . ':' . $itemType . ':' . (string)$itemUid . ':' . 'pid' . $additionalRecordFields); $record = $cache->get($cacheId); if (empty($record)) { @@ -393,13 +424,12 @@ protected function getRecordCached(string $itemType, $itemUid, string $additiona * of an item. * * @param string $itemType The item's table name. - * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * @param int $itemUid The item's uid * @return int Timestamp of the item's changed time or future start time * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException */ - protected function getItemChangedTime(string $itemType, $itemUid): int + protected function getItemChangedTime(string $itemType, int $itemUid): int { $itemTypeHasStartTimeColumn = false; $changedTimeColumns = $GLOBALS['TCA'][$itemType]['ctrl']['tstamp']; @@ -430,7 +460,7 @@ protected function getItemChangedTime(string $itemType, $itemUid): int $pageChangedTime = $this->getPageItemChangedTime($record); } - $localizationsChangedTime = $this->queueItemRepository->getLocalizableItemChangedTime($itemType, (int)$itemUid); + $localizationsChangedTime = $this->queueItemRepository->getLocalizableItemChangedTime($itemType, $itemUid); // if start time exists and start time is higher than last changed timestamp // then set changed to the future start time to make the item @@ -465,7 +495,7 @@ protected function getPageItemChangedTime(array $page): int * * @param string $itemType The item's type, usually a table name. * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * different value for non-database-record types. * @return bool TRUE if the item is found in the queue, FALSE otherwise * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException @@ -480,15 +510,16 @@ public function containsItem(string $itemType, $itemUid): bool * * @param string $itemType The item's type, usually a table name. * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * different value for non-database-record types. * @param int $rootPageId + * @param string $indexingConfiguration * @return bool TRUE if the item is found in the queue, FALSE otherwise * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function containsItemWithRootPageId(string $itemType, $itemUid, int $rootPageId): bool + public function containsItemWithRootPageId(string $itemType, $itemUid, int $rootPageId, string $indexingConfiguration): bool { - return $this->queueItemRepository->containsItemWithRootPageId($itemType, (int)$itemUid, $rootPageId); + return $this->queueItemRepository->containsItemWithRootPageId($itemType, (int)$itemUid, $rootPageId, $indexingConfiguration); } /** @@ -497,9 +528,9 @@ public function containsItemWithRootPageId(string $itemType, $itemUid, int $root * * @param string $itemType The item's type, usually a table name. * @param int|string $itemUid The item's uid, usually an integer uid, could be a - * different value for non-database-record types. + * different value for non-database-record types. * @return bool TRUE if the item is found in the queue and marked as - * indexed, FALSE otherwise + * indexed, FALSE otherwise * @throws DBALDriverException * @throws DBALException|\Doctrine\DBAL\DBALException */ @@ -512,12 +543,12 @@ public function containsIndexedItem(string $itemType, $itemUid): bool * Removes an item from the Index Queue. * * @param string $itemType The type of the item to remove, usually a table name. - * @param int|string $itemUid The uid of the item to remove + * @param int|string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types. * @throws ConnectionException * @throws DBALException * @throws Throwable */ - public function deleteItem(string $itemType, $itemUid) + public function deleteItem(string $itemType, $itemUid): void { $this->queueItemRepository->deleteItem($itemType, (int)$itemUid); } @@ -530,7 +561,7 @@ public function deleteItem(string $itemType, $itemUid) * @throws DBALException * @throws Throwable */ - public function deleteItemsByType(string $itemType) + public function deleteItemsByType(string $itemType): void { $this->queueItemRepository->deleteItemsByType($itemType); } @@ -546,7 +577,7 @@ public function deleteItemsByType(string $itemType) * @throws \Doctrine\DBAL\DBALException * @throws Throwable */ - public function deleteItemsBySite(Site $site, string $indexingConfigurationName = '') + public function deleteItemsBySite(Site $site, string $indexingConfigurationName = ''): void { $this->queueItemRepository->deleteItemsBySite($site, $indexingConfigurationName); } @@ -554,7 +585,7 @@ public function deleteItemsBySite(Site $site, string $indexingConfigurationName /** * Removes all items from the Index Queue. */ - public function deleteAllItems() + public function deleteAllItems(): void { $this->queueItemRepository->deleteAllItems(); } @@ -576,7 +607,7 @@ public function getItem(int $itemId): ?Item * Gets Index Queue items by type and uid. * * @param string $itemType item type, usually the table name - * @param int|string $itemUid item uid + * @param int|string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types. * @return Item[] An array of items matching $itemType and $itemUid * @throws ConnectionException * @throws DBALDriverException @@ -654,35 +685,38 @@ public function getItemsToIndex(Site $site, int $limit = 50): array * Marks an item as failed and causes the indexer to skip the item in the * next run. * - * @param int|Item $item Either the item's Index Queue uid or the complete item + * @param int|ItemInterface $item Either the item's Index Queue uid or the complete item * @param string $errorMessage Error message + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function markItemAsFailed($item, string $errorMessage = '') + public function markItemAsFailed($item, string $errorMessage = ''): int { - $this->queueItemRepository->markItemAsFailed($item, $errorMessage); + return $this->queueItemRepository->markItemAsFailed($item, $errorMessage); } /** * Sets the timestamp of when an item last has been indexed. * - * @param Item $item + * @param ItemInterface $item + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function updateIndexTimeByItem(Item $item) + public function updateIndexTimeByItem(ItemInterface $item): int { - $this->queueItemRepository->updateIndexTimeByItem($item); + return $this->queueItemRepository->updateIndexTimeByItem($item); } /** * Sets the change timestamp of an item. * - * @param Item $item + * @param ItemInterface $item * @param int $forcedChangeTime The change time for the item + * @return int affected rows * @throws DBALException|\Doctrine\DBAL\DBALException */ - public function setForcedChangeTimeByItem(Item $item, int $forcedChangeTime = 0) + public function setForcedChangeTimeByItem(ItemInterface $item, int $forcedChangeTime = 0): int { - $this->queueItemRepository->updateChangedTimeByItem($item, $forcedChangeTime); + return $this->queueItemRepository->updateChangedTimeByItem($item, $forcedChangeTime); } } diff --git a/Classes/IndexQueue/QueueInitializationServiceAwareInterface.php b/Classes/IndexQueue/QueueInitializationServiceAwareInterface.php new file mode 100644 index 000000000..9b850e82c --- /dev/null +++ b/Classes/IndexQueue/QueueInitializationServiceAwareInterface.php @@ -0,0 +1,36 @@ +getIsUseConfigurationMonitorTables(); - } - - // No explicit configuration => all tables should be monitored - if (empty($configurationMonitorTables)) { - return false; - } - - return !in_array($table, $configurationMonitorTables); - } - /** * Check if at least one page in the record's rootline is configured to exclude sub-entries from indexing * diff --git a/Classes/LanguageFileUnavailableException.php b/Classes/LanguageFileUnavailableException.php index 18a5ce59d..96a880049 100644 --- a/Classes/LanguageFileUnavailableException.php +++ b/Classes/LanguageFileUnavailableException.php @@ -20,6 +20,6 @@ * * @author Ingo Renner */ -class LanguageFileUnavailableException extends \Exception +class LanguageFileUnavailableException extends Exception { } diff --git a/Classes/NoSolrConnectionFoundException.php b/Classes/NoSolrConnectionFoundException.php index cc71030a0..73879b22e 100644 --- a/Classes/NoSolrConnectionFoundException.php +++ b/Classes/NoSolrConnectionFoundException.php @@ -17,8 +17,6 @@ namespace ApacheSolrForTypo3\Solr; -use Exception; - /** * Exception that is thrown when no Solr connection could be found. * diff --git a/Classes/PingFailedException.php b/Classes/PingFailedException.php index 8576b798e..6e3807094 100644 --- a/Classes/PingFailedException.php +++ b/Classes/PingFailedException.php @@ -17,8 +17,6 @@ namespace ApacheSolrForTypo3\Solr; -use Exception; - /** * Exception that is thrown when a ping fails * diff --git a/Classes/Query/Modifier/Faceting.php b/Classes/Query/Modifier/Faceting.php index b80415f5a..e41241747 100644 --- a/Classes/Query/Modifier/Faceting.php +++ b/Classes/Query/Modifier/Faceting.php @@ -27,8 +27,8 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\UrlFacetContainer; use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest; use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequestAware; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; -use InvalidArgumentException; use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/Search/SearchComponentManager.php b/Classes/Search/SearchComponentManager.php index bc9735794..4de4aa791 100644 --- a/Classes/Search/SearchComponentManager.php +++ b/Classes/Search/SearchComponentManager.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\Search; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use RuntimeException; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/System/Configuration/TypoScriptConfiguration.php b/Classes/System/Configuration/TypoScriptConfiguration.php index 7c79c8ceb..26877017c 100644 --- a/Classes/System/Configuration/TypoScriptConfiguration.php +++ b/Classes/System/Configuration/TypoScriptConfiguration.php @@ -15,11 +15,12 @@ namespace ApacheSolrForTypo3\Solr\System\Configuration; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\IndexQueue\Indexer; use ApacheSolrForTypo3\Solr\IndexQueue\Initializer\Record; +use ApacheSolrForTypo3\Solr\IndexQueue\Queue; use ApacheSolrForTypo3\Solr\System\ContentObject\ContentObjectService; use ApacheSolrForTypo3\Solr\System\Util\ArrayAccessor; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -718,6 +719,20 @@ public function getIndexQueueIndexingPriorityByConfigurationName(string $configu return (int)$this->getValueByPathOrDefaultValue($path, $defaultIfEmpty); } + /** + * This method is used to retrieve the className of a queue initializer for a certain indexing configuration + * + * plugin.tx_solr.index.queue..indexQueue + * + * @param string $configurationName + * @return string + */ + public function getIndexQueueClassByConfigurationName(string $configurationName): string + { + $path = 'plugin.tx_solr.index.queue.' . $configurationName . '.indexQueue'; + return (string)$this->getValueByPathOrDefaultValue($path, Queue::class); + } + /** * Returns the _LOCAL_LANG configuration from the TypoScript. * diff --git a/Classes/System/Environment/WebRootAllReadyDefinedException.php b/Classes/System/Environment/WebRootAllReadyDefinedException.php index 727c532f1..1788c5ee0 100644 --- a/Classes/System/Environment/WebRootAllReadyDefinedException.php +++ b/Classes/System/Environment/WebRootAllReadyDefinedException.php @@ -15,11 +15,13 @@ namespace ApacheSolrForTypo3\Solr\System\Environment; +use ApacheSolrForTypo3\Solr\Exception; + /** * Exception that is thrown when a language file is needed, but not available. * * @author Timo Hund */ -class WebRootAllReadyDefinedException extends \Exception +class WebRootAllReadyDefinedException extends Exception { } diff --git a/Classes/System/Object/AbstractClassRegistry.php b/Classes/System/Object/AbstractClassRegistry.php index da6e1a877..0da477d49 100644 --- a/Classes/System/Object/AbstractClassRegistry.php +++ b/Classes/System/Object/AbstractClassRegistry.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\System\Object; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use stdClass; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; diff --git a/Classes/System/Records/AbstractRepository.php b/Classes/System/Records/AbstractRepository.php index 5d0440c30..5cbc43754 100644 --- a/Classes/System/Records/AbstractRepository.php +++ b/Classes/System/Records/AbstractRepository.php @@ -17,9 +17,9 @@ namespace ApacheSolrForTypo3\Solr\System\Records; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use RuntimeException; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; diff --git a/Classes/System/Records/Pages/PagesRepository.php b/Classes/System/Records/Pages/PagesRepository.php index d520fb7b2..9081bec03 100644 --- a/Classes/System/Records/Pages/PagesRepository.php +++ b/Classes/System/Records/Pages/PagesRepository.php @@ -17,11 +17,11 @@ namespace ApacheSolrForTypo3\Solr\System\Records\Pages; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache; use ApacheSolrForTypo3\Solr\System\Records\AbstractRepository; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use PDO; use Throwable; use TYPO3\CMS\Backend\Utility\BackendUtility; diff --git a/Classes/System/Solr/Parser/StopWordParser.php b/Classes/System/Solr/Parser/StopWordParser.php index 836dcb92e..b6f379f7a 100644 --- a/Classes/System/Solr/Parser/StopWordParser.php +++ b/Classes/System/Solr/Parser/StopWordParser.php @@ -15,7 +15,7 @@ namespace ApacheSolrForTypo3\Solr\System\Solr\Parser; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; /** * Class to parse the stopwords from a solr response. diff --git a/Classes/System/Solr/Service/SolrAdminService.php b/Classes/System/Solr/Service/SolrAdminService.php index 1354e7725..ec0d15663 100644 --- a/Classes/System/Solr/Service/SolrAdminService.php +++ b/Classes/System/Solr/Service/SolrAdminService.php @@ -17,6 +17,7 @@ namespace ApacheSolrForTypo3\Solr\System\Solr\Service; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\System\Solr\Parser\SchemaParser; @@ -24,7 +25,6 @@ use ApacheSolrForTypo3\Solr\System\Solr\Parser\SynonymParser; use ApacheSolrForTypo3\Solr\System\Solr\ResponseAdapter; use ApacheSolrForTypo3\Solr\System\Solr\Schema\Schema; -use InvalidArgumentException; use function simplexml_load_string; use Solarium\Client; use stdClass; diff --git a/Classes/System/Url/UrlHelper.php b/Classes/System/Url/UrlHelper.php index 1c090ea39..e89a9051f 100644 --- a/Classes/System/Url/UrlHelper.php +++ b/Classes/System/Url/UrlHelper.php @@ -15,7 +15,7 @@ namespace ApacheSolrForTypo3\Solr\System\Url; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\Http\Uri; /** diff --git a/Classes/Task/AbstractSolrTask.php b/Classes/Task/AbstractSolrTask.php index 1ae250227..69698860c 100644 --- a/Classes/Task/AbstractSolrTask.php +++ b/Classes/Task/AbstractSolrTask.php @@ -19,9 +19,9 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use Doctrine\DBAL\Driver\Exception as DBALDriverException; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Scheduler\Task\AbstractTask; diff --git a/Classes/Task/EventQueueWorkerTask.php b/Classes/Task/EventQueueWorkerTask.php index b5e3fed65..1edb8def8 100644 --- a/Classes/Task/EventQueueWorkerTask.php +++ b/Classes/Task/EventQueueWorkerTask.php @@ -19,11 +19,11 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\EventListener\Events\DelayedProcessingFinishedEvent; use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\DataUpdateEventInterface; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\System\Records\Queue\EventQueueItemRepository; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; -use InvalidArgumentException; use Psr\EventDispatcher\EventDispatcherInterface; use Throwable; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/Task/ReIndexTask.php b/Classes/Task/ReIndexTask.php index 51c739edd..fcec5e944 100644 --- a/Classes/Task/ReIndexTask.php +++ b/Classes/Task/ReIndexTask.php @@ -18,7 +18,7 @@ namespace ApacheSolrForTypo3\Solr\Task; use ApacheSolrForTypo3\Solr\ConnectionManager; -use ApacheSolrForTypo3\Solr\IndexQueue\Queue; +use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueInitializationService; use Doctrine\DBAL\ConnectionException as DBALConnectionException; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Doctrine\DBAL\Exception as DBALException; @@ -59,9 +59,9 @@ public function execute() $cleanUpResult = $this->cleanUpIndex(); // initialize for re-indexing - /* @var Queue $indexQueue */ - $indexQueue = GeneralUtility::makeInstance(Queue::class); - $indexQueueInitializationResults = $indexQueue->getInitializationService() + /* @var QueueInitializationService $indexQueueInitializationService */ + $indexQueueInitializationService = GeneralUtility::makeInstance(QueueInitializationService::class); + $indexQueueInitializationResults = $indexQueueInitializationService ->initializeBySiteAndIndexConfigurations($this->getSite(), $this->indexingConfigurationsToReIndex); return $cleanUpResult && !in_array(false, $indexQueueInitializationResults); diff --git a/Classes/Traits/SkipMonitoringTrait.php b/Classes/Traits/SkipMonitoringTrait.php new file mode 100644 index 000000000..16b69c634 --- /dev/null +++ b/Classes/Traits/SkipMonitoringTrait.php @@ -0,0 +1,44 @@ +getIsUseConfigurationMonitorTables(); + } + + // No explicit configuration => all tables should be monitored + if (empty($configurationMonitorTables)) { + return false; + } + + return !in_array($table, $configurationMonitorTables); + } +} diff --git a/Classes/Utility/ManagedResourcesUtility.php b/Classes/Utility/ManagedResourcesUtility.php index f83abf03d..132ed771b 100644 --- a/Classes/Utility/ManagedResourcesUtility.php +++ b/Classes/Utility/ManagedResourcesUtility.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\Utility; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3\CMS\Core\Http\Stream; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/ViewHelpers/AbstractSolrFrontendTagBasedViewHelper.php b/Classes/ViewHelpers/AbstractSolrFrontendTagBasedViewHelper.php index 0d84f7419..d7f35f227 100644 --- a/Classes/ViewHelpers/AbstractSolrFrontendTagBasedViewHelper.php +++ b/Classes/ViewHelpers/AbstractSolrFrontendTagBasedViewHelper.php @@ -18,9 +18,9 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Mvc\Controller\SolrControllerContext; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; -use InvalidArgumentException; use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext; /** diff --git a/Classes/ViewHelpers/AbstractSolrFrontendViewHelper.php b/Classes/ViewHelpers/AbstractSolrFrontendViewHelper.php index 9876a10a5..6178102e3 100644 --- a/Classes/ViewHelpers/AbstractSolrFrontendViewHelper.php +++ b/Classes/ViewHelpers/AbstractSolrFrontendViewHelper.php @@ -19,9 +19,9 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Grouping\GroupItem; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Mvc\Controller\SolrControllerContext; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; -use InvalidArgumentException; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; /** diff --git a/Classes/ViewHelpers/Backend/Security/IfHasAccessToModuleViewHelper.php b/Classes/ViewHelpers/Backend/Security/IfHasAccessToModuleViewHelper.php index 3ec80a9d0..d9f3e957b 100644 --- a/Classes/ViewHelpers/Backend/Security/IfHasAccessToModuleViewHelper.php +++ b/Classes/ViewHelpers/Backend/Security/IfHasAccessToModuleViewHelper.php @@ -17,7 +17,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Backend\Security; -use InvalidArgumentException; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use RuntimeException; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/ViewHelpers/Uri/AbstractUriViewHelper.php b/Classes/ViewHelpers/Uri/AbstractUriViewHelper.php index c26b36c13..4dfe374bd 100644 --- a/Classes/ViewHelpers/Uri/AbstractUriViewHelper.php +++ b/Classes/ViewHelpers/Uri/AbstractUriViewHelper.php @@ -20,8 +20,8 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest; use ApacheSolrForTypo3\Solr\Domain\Search\Uri\SearchUriBuilder; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\ViewHelpers\AbstractSolrFrontendViewHelper; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\Exception as ExtbaseObjectException; use TYPO3\CMS\Extbase\Object\ObjectManager; diff --git a/Classes/ViewHelpers/Uri/Facet/AbstractValueViewHelper.php b/Classes/ViewHelpers/Uri/Facet/AbstractValueViewHelper.php index 218334c51..9d3269d03 100644 --- a/Classes/ViewHelpers/Uri/Facet/AbstractValueViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/AbstractValueViewHelper.php @@ -18,6 +18,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\AbstractFacet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\AbstractFacetItem; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\ViewHelpers\Uri\AbstractUriViewHelper; /** @@ -44,7 +45,7 @@ public function initializeArguments() /** * @param $arguments * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ protected static function getValueFromArguments($arguments) { @@ -55,7 +56,7 @@ protected static function getValueFromArguments($arguments) } elseif (isset($arguments['facetItemValue'])) { $facetValue = $arguments['facetItemValue']; } else { - throw new \InvalidArgumentException('No facetItem was passed, please pass either facetItem or facetItemValue'); + throw new InvalidArgumentException('No facetItem was passed, please pass either facetItem or facetItemValue'); } return $facetValue; @@ -64,7 +65,7 @@ protected static function getValueFromArguments($arguments) /** * @param $arguments * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ protected static function getNameFromArguments($arguments) { @@ -75,7 +76,7 @@ protected static function getNameFromArguments($arguments) } elseif (isset($arguments['facetName'])) { $facetName = $arguments['facetName']; } else { - throw new \InvalidArgumentException('No facet was passed, please pass either facet or facetName'); + throw new InvalidArgumentException('No facet was passed, please pass either facet or facetName'); } return $facetName; @@ -84,7 +85,7 @@ protected static function getNameFromArguments($arguments) /** * @param $arguments * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ protected static function getResultSetFromArguments($arguments) { @@ -95,7 +96,7 @@ protected static function getResultSetFromArguments($arguments) } elseif (isset($arguments['facetName'])) { $resultSet = $arguments['resultSet']; } else { - throw new \InvalidArgumentException('No facet was passed, please pass either facet or resultSet'); + throw new InvalidArgumentException('No facet was passed, please pass either facet or resultSet'); } return $resultSet; diff --git a/Classes/ViewHelpers/Uri/Facet/AddFacetItemViewHelper.php b/Classes/ViewHelpers/Uri/Facet/AddFacetItemViewHelper.php index d53276ea1..e0b47a934 100644 --- a/Classes/ViewHelpers/Uri/Facet/AddFacetItemViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/AddFacetItemViewHelper.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Uri\Facet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; /** @@ -31,7 +32,7 @@ class AddFacetItemViewHelper extends AbstractValueViewHelper * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { diff --git a/Classes/ViewHelpers/Uri/Facet/RemoveAllFacetsViewHelper.php b/Classes/ViewHelpers/Uri/Facet/RemoveAllFacetsViewHelper.php index a6aeac858..f18dc066b 100644 --- a/Classes/ViewHelpers/Uri/Facet/RemoveAllFacetsViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/RemoveAllFacetsViewHelper.php @@ -15,6 +15,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Uri\Facet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\ViewHelpers\Uri\AbstractUriViewHelper; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; @@ -31,7 +32,7 @@ class RemoveAllFacetsViewHelper extends AbstractUriViewHelper * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { diff --git a/Classes/ViewHelpers/Uri/Facet/RemoveFacetItemViewHelper.php b/Classes/ViewHelpers/Uri/Facet/RemoveFacetItemViewHelper.php index 345e623eb..5de0367d5 100644 --- a/Classes/ViewHelpers/Uri/Facet/RemoveFacetItemViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/RemoveFacetItemViewHelper.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Uri\Facet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; /** @@ -31,7 +32,7 @@ class RemoveFacetItemViewHelper extends AbstractValueViewHelper * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { diff --git a/Classes/ViewHelpers/Uri/Facet/RemoveFacetViewHelper.php b/Classes/ViewHelpers/Uri/Facet/RemoveFacetViewHelper.php index bd2d14678..209373823 100644 --- a/Classes/ViewHelpers/Uri/Facet/RemoveFacetViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/RemoveFacetViewHelper.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Uri\Facet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\AbstractFacet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\ViewHelpers\Uri\AbstractUriViewHelper; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; @@ -41,7 +42,7 @@ public function initializeArguments() * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { diff --git a/Classes/ViewHelpers/Uri/Facet/SetFacetItemViewHelper.php b/Classes/ViewHelpers/Uri/Facet/SetFacetItemViewHelper.php index 8cad9f260..116f59415 100644 --- a/Classes/ViewHelpers/Uri/Facet/SetFacetItemViewHelper.php +++ b/Classes/ViewHelpers/Uri/Facet/SetFacetItemViewHelper.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\ViewHelpers\Uri\Facet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; /** @@ -31,7 +32,7 @@ class SetFacetItemViewHelper extends AbstractValueViewHelper * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return string - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 180c49352..972c0f15f 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -144,3 +144,13 @@ services: - name: event.listener identifier: 'solr.index.pageIndexer.FrontendUserAuthenticator' event: TYPO3\CMS\Frontend\Authentication\ModifyResolvedFrontendGroupsEvent + + ApacheSolrForTypo3\Solr\EventListener\Extbase\PersistenceEventListener: + autowire: true + tags: + - name: event.listener + identifier: 'solr.index.ExtbaseEntityPersisted' + method: 'entityPersisted' + - name: event.listener + identifier: 'solr.index.ExtbaseEntityRemoved' + method: 'entityRemoved' \ No newline at end of file diff --git a/Docker/Ci/environment.yml b/Docker/Ci/environment.yml index 937964666..a5f606f72 100644 --- a/Docker/Ci/environment.yml +++ b/Docker/Ci/environment.yml @@ -3,6 +3,5 @@ TYPO3_DATABASE_NAME=typo3 TYPO3_DATABASE_HOST=db TYPO3_DATABASE_USERNAME=typo3 TYPO3_DATABASE_PASSWORD=typo3 -PHP_CS_FIXER_VERSION=^2.11 JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 diff --git a/Documentation/Appendix/VersionMatrix.rst b/Documentation/Appendix/VersionMatrix.rst index 6f35590ae..b91965bb8 100644 --- a/Documentation/Appendix/VersionMatrix.rst +++ b/Documentation/Appendix/VersionMatrix.rst @@ -8,12 +8,8 @@ Appendix - Version Matrix You are on docs for EXT:solr |release| version, please refer to `Version Matrix on main release `_ to see all versions. -.. tip:: - There is EXT:solr v11.6 for TYPO3 11.5 LTS. - - -Requirements for EXT:solr* 11.5 stack +Requirements for EXT:solr* 11.6 stack ------------------------------------- ========= ========== ========== =========== =============== ================== ============================= =============== =============== ================= @@ -21,5 +17,5 @@ Requirements for EXT:solr* 11.5 stack ------------------------------- ---------------------------------------------- --------------------------------------------- --------------------------------- TYPO3 EXT: solr EXT:tika EXT:solrfal EXT:solrconsole EXT:solrdebugtools EXT:solrfluidgrouping EXT:solrmlt Apache Solr Configset ========= ========== ========== =========== =============== ================== ============================= =============== =============== ================= -11.5 11.5 11.0 11.0 11.0 11.0 11.0 11.0 (Ø) 8.11.1 ext_solr_11_5_0 +11.5 11.6 11.0 11.0 11.0 11.0 11.0 11.0 (Ø) 9.3 ext_solr_11_6_0 ========= ========== ========== =========== =============== ================== ============================= =============== =============== ================= diff --git a/Documentation/Configuration/Reference/TxSolrIndex.rst b/Documentation/Configuration/Reference/TxSolrIndex.rst index e6abc4928..7a0948130 100644 --- a/Documentation/Configuration/Reference/TxSolrIndex.rst +++ b/Documentation/Configuration/Reference/TxSolrIndex.rst @@ -224,6 +224,16 @@ Defines the type to index, which is usally the database table. Sometimes you may +queue.[indexConfig].indexQueue +------------------------------ + +:Type: String +:TS Path: plugin.tx_solr.index.queue.[indexConfig].indexQueue +:Since: 11.6 +:Default: + +Class name of custom index queue implementation, falls back to the default index queue (ApacheSolrForTypo3\Solr\IndexQueue\Queue). + queue.[indexConfig].initialization ---------------------------------- diff --git a/Documentation/Releases/Index.rst b/Documentation/Releases/Index.rst index 6239e84ba..e176c6d5c 100644 --- a/Documentation/Releases/Index.rst +++ b/Documentation/Releases/Index.rst @@ -14,7 +14,7 @@ Releases :glob: new-releases - solr-release-11-5 + solr-release-11-6 solr-release-11-2 solr-release-11-0 archive diff --git a/Documentation/Releases/archive.rst b/Documentation/Releases/archive.rst index 21ed6d5ff..6fc9d21f4 100644 --- a/Documentation/Releases/archive.rst +++ b/Documentation/Releases/archive.rst @@ -13,6 +13,7 @@ Archive :titlesonly: :glob: + solr-release-11-5 solr-release-11-1 solr-release-10-0 solr-release-9-0 diff --git a/Documentation/Releases/solr-release-11-5.rst b/Documentation/Releases/solr-release-11-5.rst index db392a635..e23539ab7 100644 --- a/Documentation/Releases/solr-release-11-5.rst +++ b/Documentation/Releases/solr-release-11-5.rst @@ -86,7 +86,7 @@ Release 11.5.1 We are happy to publish EXT:solr 11.5.1 maintenance release New in this release -------------------- +~~~~~~~~~~~~~~~~~~~ - [BUGFIX] Do not include removed strptime() by @dkd-kaehm in https://github.com/TYPO3-Solr/ext-solr/pull/3335 - [BUGFIX:BP:11.5] Do not handle page updates on new page with uid 0 by @rr-it in https://github.com/TYPO3-Solr/ext-solr/pull/3344 @@ -112,6 +112,10 @@ New in this release Please read the release notes: https://github.com/TYPO3-Solr/ext-solr/releases/tag/11.5.1 +Release 11.5.0 +-------------- + + Release 11.5.0 -------------- @@ -123,10 +127,10 @@ The focus of this release has been on TYPO3 11 LTS compatibility. **Important**: This version is installable with TYPO3 11 LTS on v11.5.14+ only and contains some breaking changes, see details below. New in this release -------------------- +~~~~~~~~~~~~~~~~~~~ Support of TYPO3 11 LTS -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ With EXT:solr 11.5 we provide the support of TYPO3 11 LTS. @@ -134,7 +138,7 @@ Please note that we require at least TYPO3 11.5.14, as this version contains som Bootstrap 5.1 -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ The default templates provided by EXT:solr were adapted for Bootstrap 5.1. @@ -142,7 +146,7 @@ The templates are also prepared to display some icons with Bootstrap Icons, but Custom field processors -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ fieldProcessingInstructions can be used for processing values during indexing, e.g. timestampToIsoDate or uppercase. Now you can register and use your own field processors via: $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['fieldProcessor']['yourFieldProcessor'] = ACustomFieldProcessor::class; @@ -150,7 +154,7 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['fieldProcessor']['yourFieldProce Custom processors have to implement interface ApacheSolrForTypo3\Solr\FieldProcessor\FieldProcessor. N-Gram Filter for strings -~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^ Provides a new field type and dynamic fields for strings with enabled Edge-N-Gram filter. @@ -160,7 +164,7 @@ Now the following fields can be used: - \*_stringEdgeNgramM Improve and Fix TSFE Initialization -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The initialization of TSFE within indexing and Backends modules contexts is refactored. @@ -178,7 +182,7 @@ Note: Since TYPO3 11 LTS does not allow to instantiate TSFE for sys folders and the initialization of TSFE will be done for first and closest page(not spacer or folder) within the site rootline. Get "free content mode" working -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In previous releases of EXT:solr the language handling for "free-content-mode" inconsistent. The behavior of "free-content-mode" related records varied in RecordMonitor, Initializing and Indexing contexts, @@ -188,13 +192,13 @@ This change brings the RecordMonitor, Initializing and Indexing contexts for "fr into the same line, so the "free-content-mode" records are processed the same way. Make pageRangeFirst and pageRangeLast accessible in fluid -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ With these two additional getters it is possible to access the variables in fluid templates. See: `#3254 `_ Add custom field processors -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Custom field processors can be registered with @@ -202,13 +206,15 @@ Custom field processors can be registered with $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['fieldProcessor']['yourFieldProcessor'] = ACustomFieldProcessor::class; + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['fieldProcessor']['yourFieldProcessor'] = ACustomFieldProcessor::class; + And many more -~~~~~~~~~~~~~ +^^^^^^^^^^^^^ Please see the list of changes below or `the full changelog: `_. The list of all changes: -~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^ - [TASK] Prepare schemas for EXT:solr 11.5.x `c0a3e6205 `_ - [TASK] Provide N-Gram Filter for strings `13b90a996 `_ diff --git a/Documentation/Releases/solr-release-11-6.rst b/Documentation/Releases/solr-release-11-6.rst new file mode 100644 index 000000000..a7f872b23 --- /dev/null +++ b/Documentation/Releases/solr-release-11-6.rst @@ -0,0 +1,61 @@ +.. include:: /Includes.rst.txt +.. index:: Releases +.. _releases-11-6: + +============== +Release 11.6.0 +============== + +We are happy to release EXT:solr 11.6.0. +The focus of this release has been on Apache Solr upgrade to v 9.3.0. + +**Important**: This version is installable with TYPO3 11 LTS on v11.5.14+ only and contains some breaking changes, see details below. + +New in this release +------------------- + +And many more +~~~~~~~~~~~~~ + +Please see the list of changes below or `the full changelog: `_. + +The list of all changes: +~~~~~~~~~~~~~~~~~~~~~~~~ + + +Contributors +============ + +Like always this release would not have been possible without the help from our +awesome community. Here are the contributors to this release. + +(patches, comments, bug reports, reviews, ... in alphabetical order) + +* Christoph Lehmann +* Markus Friedrich +* Rafael Kähm + +Also a big thank you to our partners who have already concluded one of our new development participation packages such as Apache Solr EB for TYPO3 11 LTS (Feature), Apache Solr EB for TYPO3 10 LTS (Maintenance) +or Apache Solr EB for TYPO3 9 ELTS (Extended): + +TBD + +How to Get Involved +=================== + +There are many ways to get involved with Apache Solr for TYPO3: + +* Submit bug reports and feature requests on [GitHub](https://github.com/TYPO3-Solr/ext-solr) +* Ask or help or answer questions in our [Slack channel](https://typo3.slack.com/messages/ext-solr/) +* Provide patches through Pull Request or review and comment on existing [Pull Requests](https://github.com/TYPO3-Solr/ext-solr/pulls) +* Go to [www.typo3-solr.com](http://www.typo3-solr.com) or call [dkd](http://www.dkd.de) to sponsor the ongoing development of Apache Solr for TYPO3 + +Support us by becoming an EB partner: + +https://shop.dkd.de/Produkte/Apache-Solr-fuer-TYPO3/ + +or call: + ++49 (0)69 - 2475218 0 + + diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg index b2d1be6cb..2f0bf1922 100644 --- a/Documentation/Settings.cfg +++ b/Documentation/Settings.cfg @@ -4,8 +4,8 @@ [general] project = Apache Solr for TYPO3 -version = 11.5 -release = 11.5.4 +version = 11.6 +release = 11.6.0 copyright = since 2009 by dkd & contributors [html_theme_options] diff --git a/README.md b/README.md index 3c6028f23..679ac167f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ [![TYPO3 11](https://img.shields.io/badge/TYPO3-11-orange.svg?style=flat-square)](https://get.typo3.org/version/11) [![Total Downloads](http://poser.pugx.org/apache-solr-for-typo3/solr/downloads)](https://packagist.org/packages/apache-solr-for-typo3/solr) [![Monthly Downloads](https://poser.pugx.org/apache-solr-for-typo3/solr/d/monthly)](https://packagist.org/packages/apache-solr-for-typo3/solr) -[![Build Status](https://github.com/TYPO3-Solr/ext-solr/actions/workflows/ci.yml/badge.svg?branch=release-11.5.x)](https://github.com/TYPO3-Solr/ext-solr/actions?query=branch:release-11.5.x) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/badges/quality-score.png?b=release-11.5.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/?branch=release-11.5.x) -[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/badges/coverage.png?b=release-11.5.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/?branch=release-11.5.x) +[![Build Status](https://github.com/TYPO3-Solr/ext-solr/actions/workflows/ci.yml/badge.svg?branch=release-11.6.x)](https://github.com/TYPO3-Solr/ext-solr/actions?query=branch:release-11.6.x) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/badges/quality-score.png?b=release-11.6.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/?branch=release-11.6.x) +[![Code Coverage](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/badges/coverage.png?b=release-11.6.x)](https://scrutinizer-ci.com/g/TYPO3-Solr/ext-solr/?branch=release-11.6.x) # Apache Solr for TYPO3 CMS @@ -28,7 +28,7 @@ Further details including a comparison chart are provided at the program homepag | | URL | |------------------|-----------------------------------------------------------------| | **Repository:** | https://github.com/TYPO3-Solr/ext-solr | -| **Read online:** | https://docs.typo3.org/p/apache-solr-for-typo3/solr/11.5/en-us/ | +| **Read online:** | https://docs.typo3.org/p/apache-solr-for-typo3/solr/11.6/en-us/ | | **TER:** | https://extensions.typo3.org/extension/solr | | **Homepage:** | https://www.typo3-solr.com/ | diff --git a/Tests/Integration/ContentObject/Fixtures/Services.yaml b/Tests/Integration/ContentObject/Fixtures/Services.yaml new file mode 100644 index 000000000..06c9cb547 --- /dev/null +++ b/Tests/Integration/ContentObject/Fixtures/Services.yaml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + ApacheSolrForTypo3\FakeExtension\: + resource: '../Classes/*' \ No newline at end of file diff --git a/Tests/Integration/Domain/Site/SiteRepositoryTest.php b/Tests/Integration/Domain/Site/SiteRepositoryTest.php index c92ebf59a..c7f7ad18f 100644 --- a/Tests/Integration/Domain/Site/SiteRepositoryTest.php +++ b/Tests/Integration/Domain/Site/SiteRepositoryTest.php @@ -17,10 +17,10 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Integration\IntegrationTest; use Doctrine\DBAL\DBALException; use Exception; -use InvalidArgumentException; use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Exception as TestingFrameworkCoreException; diff --git a/Tests/Integration/Domain/Site/SiteTest.php b/Tests/Integration/Domain/Site/SiteTest.php index 51df7ae97..8c0300eef 100644 --- a/Tests/Integration/Domain/Site/SiteTest.php +++ b/Tests/Integration/Domain/Site/SiteTest.php @@ -17,8 +17,8 @@ use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Integration\IntegrationTest; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** diff --git a/Tests/Integration/Extbase/Fixtures/delete_items.csv b/Tests/Integration/Extbase/Fixtures/delete_items.csv new file mode 100644 index 000000000..772537295 --- /dev/null +++ b/Tests/Integration/Extbase/Fixtures/delete_items.csv @@ -0,0 +1,6 @@ +"tx_fakeextension_domain_model_foo", +,"uid","pid","title","tstamp","deleted" +,3,1,"delete me",0,0 +"tx_solr_indexqueue_item", +,"uid","root","item_type","item_uid","changed","errors","indexing_configuration" +,3,1,"tx_fakeextension_domain_model_foo",3,0,0,"foo" \ No newline at end of file diff --git a/Tests/Integration/Extbase/Fixtures/hidden_items.csv b/Tests/Integration/Extbase/Fixtures/hidden_items.csv new file mode 100644 index 000000000..baa9732c2 --- /dev/null +++ b/Tests/Integration/Extbase/Fixtures/hidden_items.csv @@ -0,0 +1,6 @@ +"tx_fakeextension_domain_model_foo", +,"uid","pid","title","tstamp","deleted" +,4,1,"hide me",0,0 +"tx_solr_indexqueue_item", +,"uid","root","item_type","item_uid","changed","errors" +,4,1,"tx_fakeextension_domain_model_foo",4,0,0 \ No newline at end of file diff --git a/Tests/Integration/Extbase/Fixtures/update_items.csv b/Tests/Integration/Extbase/Fixtures/update_items.csv new file mode 100644 index 000000000..85d8ff15c --- /dev/null +++ b/Tests/Integration/Extbase/Fixtures/update_items.csv @@ -0,0 +1,3 @@ +"tx_fakeextension_domain_model_foo", +,"uid","pid","title","tstamp" +,2,1,"update me",0 diff --git a/Tests/Integration/Extbase/PersistenceEventListenerTest.php b/Tests/Integration/Extbase/PersistenceEventListenerTest.php new file mode 100644 index 000000000..b2ea68f2a --- /dev/null +++ b/Tests/Integration/Extbase/PersistenceEventListenerTest.php @@ -0,0 +1,145 @@ +writeDefaultSolrTestSiteConfiguration(); + $this->addTypoScriptToTemplateRecord(1, ' + plugin.tx_solr.index.queue.foo = 1 + plugin.tx_solr.index.queue.foo.type = tx_fakeextension_domain_model_foo + '); + $this->indexQueue = GeneralUtility::makeInstance(Queue::class); + $this->repository = GeneralUtility::makeInstance(FooRepository::class); + $this->persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class); + } + + /** + * @test + */ + public function newEntityIsAddedToIndexQueue() + { + $object = new Foo(); + $object->setTitle('Added'); + $object->setPid(1); + $repository = GeneralUtility::makeInstance(FooRepository::class); + $repository->add($object); + $this->persistenceManager->persistAll(); + self::assertTrue($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 1)); + } + + /** + * @test + */ + public function newHiddenEntityIsNotAddedToIndexQueue() + { + $object = new Foo(); + $object->setTitle('Added'); + $object->setHidden(true); + $object->setPid(1); + $repository = GeneralUtility::makeInstance(FooRepository::class); + $repository->add($object); + $this->persistenceManager->persistAll(); + self::assertFalse($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 1)); + } + + /** + * @test + */ + public function updatedEntityIsUpdatedInIndexQueue() + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/update_items.csv'); + /** @var Foo $object */ + $object = $this->repository->findByUid(2); + $object->setTitle('Updated'); + $this->repository->update($object); + $this->persistenceManager->persistAll(); + + $context = GeneralUtility::makeInstance(Context::class); + $currentTimestamp = $context->getPropertyFromAspect('date', 'timestamp'); + + self::assertTrue($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 2)); + + $item = $this->indexQueue->getItem(1); + self::assertSame(2, $item->getRecordUid()); + self::assertSame('foo', $item->getIndexingConfigurationName()); + self::assertSame($currentTimestamp, $item->getChanged()); + } + + /** + * @test + */ + public function softDeletedEntityIsRemovedFromIndexQueue() + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/delete_items.csv'); + /** @var Foo $object */ + $object = $this->repository->findByUid(3); + $this->repository->remove($object); + $this->persistenceManager->persistAll(); + + self::assertFalse($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 3)); + } + + /** + * @test + */ + public function deletedEntityIsRemovedFromIndexQueue() + { + unset($GLOBALS['TCA']['tx_fakeextension_domain_model_foo']['ctrl']['delete']); + $this->importCSVDataSet(__DIR__ . '/Fixtures/delete_items.csv'); + /** @var Foo $object */ + $object = $this->repository->findByUid(3); + $this->repository->remove($object); + $this->persistenceManager->persistAll(); + + self::assertFalse($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 3)); + } + + /** + * @test + */ + public function updatedEntityTurnedHiddenIsRemovedFromIndexQueue() + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/hidden_items.csv'); + /** @var Foo $object */ + $object = $this->repository->findByUid(4); + $object->setHidden(true); + $this->repository->update($object); + $this->persistenceManager->persistAll(); + + self::assertFalse($this->indexQueue->containsItem('tx_fakeextension_domain_model_foo', 4)); + } +} diff --git a/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Model/Foo.php b/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Model/Foo.php new file mode 100644 index 000000000..5775de6d7 --- /dev/null +++ b/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Model/Foo.php @@ -0,0 +1,31 @@ +title; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function isHidden(): bool + { + return $this->hidden; + } + + public function setHidden(bool $hidden): void + { + $this->hidden = $hidden; + } +} diff --git a/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Repository/FooRepository.php b/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Repository/FooRepository.php new file mode 100644 index 000000000..e10e34b0a --- /dev/null +++ b/Tests/Integration/Fixtures/Extensions/fake_extension/Classes/Domain/Repository/FooRepository.php @@ -0,0 +1,11 @@ +expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'][] = AdditionalIndexQueueItemIndexer::class; $document = new Document(); $metaData = ['item_type' => 'pages']; @@ -499,7 +500,7 @@ public function canGetAdditionalDocumentsNotImplementingInterface() */ public function canGetAdditionalDocumentsNonExistingClass() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'][] = 'NonExistingClass'; $document = new Document(); $metaData = ['item_type' => 'pages']; diff --git a/Tests/Integration/IndexQueue/QueueTest.php b/Tests/Integration/IndexQueue/QueueTest.php index 6a895e0ca..7c659c52d 100644 --- a/Tests/Integration/IndexQueue/QueueTest.php +++ b/Tests/Integration/IndexQueue/QueueTest.php @@ -15,6 +15,7 @@ namespace ApacheSolrForTypo3\Solr\Tests\Integration\IndexQueue; +use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueInitializationService; use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository; use ApacheSolrForTypo3\Solr\IndexQueue\Queue; @@ -43,6 +44,7 @@ protected function setUp(): void parent::setUp(); $this->writeDefaultSolrTestSiteConfiguration(); $this->indexQueue = GeneralUtility::makeInstance(Queue::class); + $this->indexQueue->setQueueInitializationService(GeneralUtility::makeInstance(QueueInitializationService::class)); $this->siteRepository = GeneralUtility::makeInstance(SiteRepository::class); } @@ -78,7 +80,7 @@ public function preFilledQueueContainsRootPageAfterInitialize() // after initialize the prefilled queue item should be lost and the root page should be added again $site = $this->siteRepository->getFirstAvailableSite(); - $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); + $this->indexQueue->getQueueInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); $this->assertItemsInQueue(1); self::assertTrue($this->indexQueue->containsItem('pages', 1)); @@ -155,10 +157,10 @@ public function mountPagesAreOnlyAddedOnceAfterInitialize() $this->assertEmptyQueue(); $site = $this->siteRepository->getFirstAvailableSite(); - $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); + $this->indexQueue->getQueueInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); $this->assertItemsInQueue(4); - $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); + $this->indexQueue->getQueueInitializationService()->initializeBySiteAndIndexConfiguration($site, 'pages'); $this->assertItemsInQueue(4); } @@ -191,7 +193,7 @@ public function canAddCustomPageTypeToTheQueue() }' ); $site = $this->siteRepository->getFirstAvailableSite(); - $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfiguration($site, 'custom_page_type'); + $this->indexQueue->getQueueInitializationService()->initializeBySiteAndIndexConfiguration($site, 'custom_page_type'); $this->assertItemsInQueue(1); @@ -247,7 +249,7 @@ public function canInitializeMultipleSites() if (is_array($availableSites)) { foreach ($availableSites as $site) { if ($site instanceof Site) { - $this->indexQueue->getInitializationService()->initializeBySiteAndIndexConfiguration($site); + $this->indexQueue->getQueueInitializationService()->initializeBySiteAndIndexConfiguration($site); } } } diff --git a/Tests/Integration/IntegrationTest.php b/Tests/Integration/IntegrationTest.php index 80e2dcbe8..d35009eab 100644 --- a/Tests/Integration/IntegrationTest.php +++ b/Tests/Integration/IntegrationTest.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\Tests\Integration; use ApacheSolrForTypo3\Solr\Access\Rootline; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\IndexQueue\Item; use ApacheSolrForTypo3\Solr\Tests\Unit\Helper\FakeObjectManager; use ApacheSolrForTypo3\Solr\Typo3PageIndexer; @@ -24,7 +25,6 @@ use Doctrine\DBAL\Exception as DoctrineDBALException; use Doctrine\DBAL\Schema\SchemaException; use function getenv; -use InvalidArgumentException; use ReflectionClass; use ReflectionException; use ReflectionObject; diff --git a/Tests/Unit/Domain/Index/Queue/QueueInitializerServiceTest.php b/Tests/Unit/Domain/Index/Queue/QueueInitializerServiceTest.php index 2fed50e2c..99b63eb54 100644 --- a/Tests/Unit/Domain/Index/Queue/QueueInitializerServiceTest.php +++ b/Tests/Unit/Domain/Index/Queue/QueueInitializerServiceTest.php @@ -21,6 +21,7 @@ use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; use PHPUnit\Framework\MockObject\MockObject; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** * @author Timo Hund @@ -33,8 +34,11 @@ class QueueInitializerServiceTest extends UnitTest public function allIndexConfigurationsAreUsedWhenWildcardIsPassed() { $queueMock = $this->getDumbMock(Queue::class); + GeneralUtility::addInstance(Queue::class, $queueMock); + GeneralUtility::addInstance(Queue::class, $queueMock); + /* @var QueueInitializationService|MockObject $service */ - $service = $this->getMockBuilder(QueueInitializationService::class)->onlyMethods(['executeInitializer'])->setConstructorArgs([$queueMock])->getMock(); + $service = $this->getMockBuilder(QueueInitializationService::class)->onlyMethods(['executeInitializer'])->getMock(); $fakeTs = [ 'plugin.' => [ diff --git a/Tests/Unit/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolverTest.php b/Tests/Unit/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolverTest.php index ae50fdba6..3ee11e2e0 100644 --- a/Tests/Unit/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolverTest.php +++ b/Tests/Unit/Domain/Index/Queue/RecordMonitor/Helper/RootPageResolverTest.php @@ -17,9 +17,9 @@ use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\ConfigurationAwareRecordService; use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; -use InvalidArgumentException; use PHPUnit\Framework\MockObject\MockObject; /** diff --git a/Tests/Unit/Domain/Search/ResultSet/Facets/FacetRegistryTest.php b/Tests/Unit/Domain/Search/ResultSet/Facets/FacetRegistryTest.php index 12a04ea32..c94e614ad 100644 --- a/Tests/Unit/Domain/Search/ResultSet/Facets/FacetRegistryTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/Facets/FacetRegistryTest.php @@ -17,9 +17,9 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\FacetRegistry; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\OptionBased\Options\OptionsPackage; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Unit\Domain\Search\ResultSet\Facets\TestPackage\TestPackage; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; -use InvalidArgumentException; use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; diff --git a/Tests/Unit/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoderTest.php b/Tests/Unit/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoderTest.php index 977042111..5eca1eda1 100644 --- a/Tests/Unit/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoderTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/Facets/RangeBased/NumericRange/NumericRangeUrlDecoderTest.php @@ -16,8 +16,8 @@ namespace ApacheSolrForTypo3\Solr\Tests\Unit\Domain\Search\ResultSet\Facets\RangeBased\NumericRange; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\RangeBased\NumericRange\NumericRangeUrlDecoder; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; -use InvalidArgumentException; use TYPO3\CMS\Core\Utility\GeneralUtility; /** diff --git a/Tests/Unit/Domain/Search/ResultSet/Facets/RequirementsServiceTest.php b/Tests/Unit/Domain/Search/ResultSet/Facets/RequirementsServiceTest.php index a623fcfd6..6f194f0a8 100644 --- a/Tests/Unit/Domain/Search/ResultSet/Facets/RequirementsServiceTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/Facets/RequirementsServiceTest.php @@ -19,6 +19,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\OptionBased\Options\OptionsFacet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\RequirementsService; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; @@ -236,7 +237,7 @@ public function getAllRequirementsMetIsReturnsFalseIfRequiredFacetValueIsNotSele */ public function exceptionIsThrownForRequirementWithNotExistingFacet() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Requirement for unexisting facet configured'); $resultSet = new SearchResultSet(); diff --git a/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingHelperTest.php b/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingHelperTest.php index 42b837ef6..a56c88538 100644 --- a/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingHelperTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingHelperTest.php @@ -16,6 +16,7 @@ namespace ApacheSolrForTypo3\Solr\Tests\Unit\Domain\Search\ResultSet\Sorting; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Sorting\SortingHelper; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; /** @@ -49,7 +50,7 @@ public function canGetSortFieldFromUrlParameter() */ public function canThrowExceptionForUnconfiguredSorting() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('No sorting configuration found for option name unconfigured'); $sorting = new SortingHelper([]); $sorting->getSortFieldFromUrlParameter('unconfigured asc'); diff --git a/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingTest.php b/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingTest.php index 114cb65e5..f72af4b32 100644 --- a/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/Sorting/SortingTest.php @@ -17,6 +17,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Sorting\Sorting; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; /** @@ -55,7 +56,7 @@ protected function setUp(): void */ public function canNotCreateWhenInvalidDirectionIsPassed() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); new Sorting($this->resultSetMock, 'Color', 'color_s', 'invalid direction', 'the color', false, false); } diff --git a/Tests/Unit/IndexQueue/IndexerTest.php b/Tests/Unit/IndexQueue/IndexerTest.php index 4e4146e4e..b30a33529 100644 --- a/Tests/Unit/IndexQueue/IndexerTest.php +++ b/Tests/Unit/IndexQueue/IndexerTest.php @@ -17,6 +17,7 @@ use ApacheSolrForTypo3\Solr\ConnectionManager; use ApacheSolrForTypo3\Solr\Domain\Search\ApacheSolrDocument\Builder; +use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException; use ApacheSolrForTypo3\Solr\FrontendEnvironment; use ApacheSolrForTypo3\Solr\IndexQueue\AdditionalIndexQueueItemIndexer; use ApacheSolrForTypo3\Solr\IndexQueue\Exception\IndexingException; @@ -30,7 +31,6 @@ use ApacheSolrForTypo3\Solr\System\Solr\Service\SolrWriteService; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; -use InvalidArgumentException; use PHPUnit\Framework\MockObject\MockBuilder; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; diff --git a/Tests/Unit/System/Configuration/TypoScriptConfigurationTest.php b/Tests/Unit/System/Configuration/TypoScriptConfigurationTest.php index 6b083891b..58c586990 100644 --- a/Tests/Unit/System/Configuration/TypoScriptConfigurationTest.php +++ b/Tests/Unit/System/Configuration/TypoScriptConfigurationTest.php @@ -15,6 +15,8 @@ namespace ApacheSolrForTypo3\Solr\Tests\Unit\System\Configuration; +use ApacheSolrForTypo3\Solr\IndexQueue\Initializer\Record; +use ApacheSolrForTypo3\Solr\IndexQueue\Queue; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; @@ -320,7 +322,6 @@ public function canGetIndexQueueConfigurationNamesByTableName() 'custom_one.' => [ 'type' => 'tx_model_bar', ], - 'custom_two' => 1, 'custom_two.' => [ 'type' => 'tx_model_news', @@ -333,6 +334,54 @@ public function canGetIndexQueueConfigurationNamesByTableName() self::assertEquals(['tx_model_news', 'custom_two'], $configuration->getIndexQueueConfigurationNamesByTableName('tx_model_news')); } + /** + * @test + */ + public function canGetIndexQueueInitializerClassByConfigurationName() + { + $fakeConfigurationArray['plugin.']['tx_solr.'] = [ + 'index.' => [ + 'queue.' => [ + 'tx_model_news' => 1, + 'tx_model_news.' => [ + ], + 'custom_one' => 1, + 'custom_one.' => [ + 'initialization' => 'CustomInitializer', + ], + ], + ], + ]; + + $configuration = new TypoScriptConfiguration($fakeConfigurationArray); + self::assertEquals(Record::class, $configuration->getIndexQueueInitializerClassByConfigurationName('tx_model_news')); + self::assertEquals('CustomInitializer', $configuration->getIndexQueueInitializerClassByConfigurationName('custom_one')); + } + + /** + * @test + */ + public function canGetIndexQueueClassByConfigurationName() + { + $fakeConfigurationArray['plugin.']['tx_solr.'] = [ + 'index.' => [ + 'queue.' => [ + 'tx_model_news' => 1, + 'tx_model_news.' => [ + ], + 'custom_one' => 1, + 'custom_one.' => [ + 'indexQueue' => 'CustomQueue', + ], + ], + ], + ]; + + $configuration = new TypoScriptConfiguration($fakeConfigurationArray); + self::assertEquals(Queue::class, $configuration->getIndexQueueClassByConfigurationName('tx_model_news')); + self::assertEquals('CustomQueue', $configuration->getIndexQueueClassByConfigurationName('custom_one')); + } + /** * @test */ diff --git a/composer.json b/composer.json index 1f0b453b5..aff804ced 100644 --- a/composer.json +++ b/composer.json @@ -41,9 +41,7 @@ "phpunit/phpunit": "^9.5", "phpspec/prophecy-phpunit":"*", "typo3/testing-framework": "^6.12", - "typo3/cms-fluid-styled-content": "*", - "scrutinizer/ocular": "*", - "sclable/xml-lint": "*" + "typo3/cms-fluid-styled-content": "*" }, "replace": { "apache-solr-for-typo3/solrfluid": "*", @@ -58,14 +56,36 @@ "autoload-dev": { "psr-4": { "ApacheSolrForTypo3\\Solr\\Tests\\": "Tests/", + "ApacheSolrForTypo3\\FakeExtension\\": "Tests/Integration/Fixtures/Extensions/fake_extension/Classes/", "TYPO3\\CMS\\Core\\Tests\\": ".Build/Web/typo3/sysext/core/Tests/" } }, + "minimum-stability": "stable", "prefer-stable": true, "config": { "allow-plugins": true, "vendor-dir": ".Build/vendor", - "bin-dir": ".Build/bin" + "bin-dir": ".Build/bin", + "sort-packages": true, + "preferred-install": { + "typo3/cms-core": "source", + "*": "dist" + } + }, + "scripts-descriptions": { + "t3:docs:build": "Renders the docs. Note: Can not run inside docker container, because uses TYPO3 dockrun_t3rd", + "t3:docs:build:prod": "Same as t3:docs:build, but places the rendered docs in Resources/Public/Documentation and symlinks them to EXT:tika/Documentation.HTML", + "t3:docs:clean": "Deletes all rendered docs created by t3:docs:build or t3:docs:build:prod.", + "t3:standards:fix": "Fixes a possible TYPO3 coding standards errors.", + + "tests:env": "Checks the requierements in environment for tests.", + "tests:integration": "Runs integration tests", + "tests:lint-xml": "Lints the XML/XLF files. Depends on global installed sclable/xml-lint. See tests:setup:global-require", + "tests:phpstan": "Runs PHPStan analys", + "tests:restore-git": "[Internal script], which is used after tests:setup to restore the composer.json.", + "tests:setup": "Installs composer dependencies, requiered for tests.", + "tests:setup:global-require": "Installs global composer dependencies. Those are moved to global, to avoid collisions and downgrades on libs.", + "tests:unit": "Runs unit tests" }, "scripts-descriptions": { "t3:docs:build": "Renders the docs. Note: Can not run inside docker container, because uses TYPO3 dockrun_t3rd", @@ -95,7 +115,7 @@ "rm -Rf Documentation-GENERATED-temp/ $(readlink -f Documentation.HTML) Documentation.HTML" ], "extension-create-libs": [ - "@composer req -d Resources/Private/Php/ComposerLibraries solarium/solarium:$(Build/Helpers/GET_LACAL_PACKAGE_VERSION_CONSTRAINT.sh solarium/solarium)" + "@composer req -d Resources/Private/Php/ComposerLibraries solarium/solarium:$(Build/Helpers/GET_LOCAL_PACKAGE_VERSION_CONSTRAINT.sh solarium/solarium)" ], "extension-build": [ "@extension-create-libs" @@ -105,31 +125,41 @@ "if [ -z ${TYPO3_VERSION+x} ]; then >&2 echo \"Can not proceed, because env var TYPO3_VERSION is not set\"; exit 1; else echo \"Setup test environment for TYPO3 ${TYPO3_VERSION}\"; fi", "if echo $TYPO3_VERSION | grep -q \"dev\"; then $COMPOSER_BINARY config minimum-stability dev; fi" ], + "tests:setup:global-require": [ + "echo \"Install global composer dependencies.\"", + "@composer global require sclable/xml-lint", + "@composer global require scrutinizer/ocular" + ], "tests:setup": [ + "# @todo: Abort if composer.json has not staged/commited changes on composer.json, to avoid losing necessery changes.", "@tests:env", - "@composer req --prefer-source --update-with-all-dependencies typo3/cms-core:${TYPO3_VERSION}", + "@composer req --update-with-all-dependencies typo3/cms-core:${TYPO3_VERSION}", "@tests:restore-git" ], "tests:unit": [ - "phpunit --colors --config=Build/Test/UnitTests.xml --bootstrap=Build/Test/UnitTestsBootstrap.php" + "phpunit --config=Build/Test/UnitTests.xml" ], "tests:integration": [ - "phpunit --colors --config=Build/Test/IntegrationTests.xml --bootstrap=.Build/Web/typo3conf/ext/solr/Build/Test/IntegrationTestsBootstrap.php" + "Composer\\Config::disableProcessTimeout", + "phpunit --config=Build/Test/IntegrationTests.xml" + ], + "tests:phpstan": [ + "phpstan analyze -c Build/Test/phpstan.neon" ], "t3:standards:fix": [ "php-cs-fixer fix" ], - "lint:xlf": [ - "xmllint Resources/Private/Language/ -p '*.xlf'" + "tests:lint-xml": [ + "echo \"Run XML Lint\"", + "if ! $($COMPOSER_BINARY config home)/vendor/bin/xmllint Resources/Private/Language/ --pattern='*.xlf' --exclude=.Build/*; then echo \"Some XML files are not valid\" && echo \"Please fix the files listed above\" && export EXIT_CODE=4; else echo \"No syntax errors! Great job!\"; fi" ] }, "extra": { "branch-alias": { - "dev-release-11.5.x": "11.5.x-dev" + "dev-release-11.6.x": "11.6.x-dev" }, "typo3/cms": { "extension-key": "solr", - "cms-package-dir": "{$vendor-dir}/typo3/cms", "web-dir": ".Build/Web" }, "TYPO3-Solr": { @@ -140,10 +170,14 @@ "ext-solrdebugtools": "^11.0", "ext-solrfluidgrouping": "^11.0", "ext-solrmlt": "^11.0", - "Apache-Solr": "8.11.1", - "configset": "ext_solr_11_5_0" + "Apache-Solr": "9.3.0", + "configset": "ext_solr_11_6_0" }, "ext-solrfal": { + }, + "stack-for-ci": { + "sclable/xml-lint": "*", + "scrutinizer/ocular": "*" } } } diff --git a/ext_emconf.php b/ext_emconf.php index e41b9bdee..1733b2619 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -3,8 +3,8 @@ $EM_CONF[$_EXTKEY] = [ 'title' => 'Apache Solr for TYPO3 - Enterprise Search', 'description' => 'Apache Solr for TYPO3 is the enterprise search server you were looking for with special features such as Faceted Search or Synonym Support and incredibly fast response times of results within milliseconds.', - 'version' => '11.5.4', - 'state' => 'stable', + 'version' => '11.6.0', + 'state' => 'beta', 'category' => 'plugin', 'author' => 'Ingo Renner, Timo Hund, Markus Friedrich', 'author_email' => 'ingo@typo3.org',