From 2194df481290db263bb8f26e6dc1a8228e487dc4 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Sat, 3 Aug 2024 09:59:14 +0200 Subject: [PATCH] [TASK] Make extension compatible to TYPO3 v12 Relates: #86 --- .github/CONTRIBUTING.md | 81 +++++ .github/FUNDING.yml | 2 + .github/ISSUE_TEMPLATE.md | 6 + .github/ISSUE_TEMPLATE/Bug_report.md | 25 ++ .github/ISSUE_TEMPLATE/Feature_request.md | 19 ++ .github/ISSUE_TEMPLATE/Support_question.md | 5 + .github/workflows/ci.yaml | 110 +++++++ .gitignore | 9 +- .gitlab-ci.yml | 196 ++++++------ Build/.php-cs-fixer.dist.php | 78 +++-- Build/FunctionalTests.xml | 26 -- Build/UnitTests.xml | 38 +-- Build/grumphp/resources/ascii/failed.txt | 7 - Build/grumphp/resources/ascii/succeeded.txt | 7 - Classes/Controller/EventController.php | 124 ++++---- Classes/Controller/EventDateController.php | 19 +- .../Finisher/Form/AddToCartFinisher.php | 37 +-- Classes/Domain/Model/AbstractEventDate.php | 47 +-- Classes/Domain/Model/CalendarEntry.php | 6 +- Classes/Domain/Model/Category.php | 12 +- Classes/Domain/Model/Dto/EventDemand.php | 57 +--- Classes/Domain/Model/Event.php | 185 +++--------- Classes/Domain/Model/EventDate.php | 152 +++------- Classes/Domain/Model/PriceCategory.php | 53 ++-- Classes/Domain/Model/SpecialPrice.php | 36 +-- .../Repository/CalendarEntryRepository.php | 6 +- .../Domain/Repository/CategoryRepository.php | 7 +- .../Domain/Repository/EventDateRepository.php | 8 +- Classes/Domain/Repository/EventRepository.php | 12 +- .../Repository/PriceCategoryRepository.php | 5 +- .../Repository/SpecialPriceRepository.php | 6 +- .../CheckProductAvailability.php | 104 +++---- .../EventListener/Order/Stock/FlushCache.php | 13 +- .../EventListener/Order/Stock/HandleStock.php | 36 +-- .../RetrieveProductsFromRequest.php | 101 +++---- Classes/Hooks/DataHandler.php | 3 +- Classes/Hooks/DatamapDataHandlerHook.php | 8 +- Classes/Hooks/KeSearchEventsIndexer.php | 86 ------ Classes/Hooks/KeSearchIndexer.php | 154 ---------- Classes/Hooks/KeSearchSingleEventIndexer.php | 78 ----- Classes/Updates/SlugUpdater.php | 24 +- .../Event/FreePlacesClassViewHelper.php | 12 +- .../Form/PriceCategorySelectViewHelper.php | 14 +- Classes/ViewHelpers/Link/EventViewHelper.php | 139 ++++++--- Classes/ViewHelpers/SchemaViewHelper.php | 4 +- Configuration/Extbase/Persistence/Classes.php | 3 +- Configuration/Icons.php | 20 ++ Configuration/TCA/Overrides/pages.php | 7 +- Configuration/TCA/Overrides/sys_category.php | 8 +- Configuration/TCA/Overrides/sys_template.php | 2 +- Configuration/TCA/Overrides/tt_content.php | 12 +- .../tx_cartevents_domain_model_event.php | 50 +-- .../tx_cartevents_domain_model_eventdate.php | 2 +- ..._cartevents_domain_model_pricecategory.php | 2 +- ...x_cartevents_domain_model_specialprice.php | 2 +- .../Overrides/tx_kesearch_indexerconfig.php | 2 +- ..._cartevents_domain_model_calendarentry.php | 35 +-- .../TCA/tx_cartevents_domain_model_event.php | 265 ++++++++-------- .../tx_cartevents_domain_model_eventdate.php | 285 ++++++++---------- ..._cartevents_domain_model_pricecategory.php | 69 ++--- ...x_cartevents_domain_model_specialprice.php | 60 ++-- Documentation/Settings.cfg | 4 +- README.md | 14 +- .../Language/Overrides/cart/fr.locallang.xlf | 15 - Resources/Private/Language/de.locallang.xlf | 43 --- .../Private/Language/de.locallang_be.xlf | 179 ----------- .../Private/Language/de.locallang_db.xlf | 247 --------------- .../Private/Language/de.locallang_tca.xlf | 56 ---- Resources/Private/Language/fr.locallang.xlf | 43 --- .../Private/Partials/Event/CartForm.html | 2 + Resources/Private/Templates/Event/Show.html | 2 +- Tests/Acceptance/Data/.gitkeep | 0 Tests/Acceptance/EventListCest.php | 50 +++ Tests/Acceptance/Support/Environment.php | 60 ++++ Tests/Acceptance/Support/Tester.php | 37 +++ .../Acceptance/Support/_generated/.gitignore | 2 + Tests/Fixtures/BackendUserDatabase.php | 16 + Tests/Fixtures/ContentDatabase.php | 24 ++ Tests/Fixtures/EventsDatabase.php | 106 +++++++ Tests/Fixtures/PagesDatabase.php | 167 ++++++++++ .../Configuration/TypoScript/setup.typoscript | 7 + Tests/Fixtures/cart_events_test/composer.json | 15 + .../Fixtures/config/sites/default/config.yaml | 34 +++ Tests/Unit/Domain/Model/EventTest.php | 14 +- codeception.dist.yml | 45 +++ composer.json | 61 ++-- ext_emconf.php | 18 +- ext_localconf.php | 84 ++---- rector.php | 142 +++------ shell.nix | 123 ++++++++ 90 files changed, 2033 insertions(+), 2558 deletions(-) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/Bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/Feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/Support_question.md create mode 100644 .github/workflows/ci.yaml delete mode 100644 Build/FunctionalTests.xml delete mode 100644 Build/grumphp/resources/ascii/failed.txt delete mode 100644 Build/grumphp/resources/ascii/succeeded.txt delete mode 100644 Classes/Hooks/KeSearchEventsIndexer.php delete mode 100644 Classes/Hooks/KeSearchIndexer.php delete mode 100644 Classes/Hooks/KeSearchSingleEventIndexer.php create mode 100644 Configuration/Icons.php delete mode 100644 Resources/Private/Language/Overrides/cart/fr.locallang.xlf delete mode 100644 Resources/Private/Language/de.locallang.xlf delete mode 100644 Resources/Private/Language/de.locallang_be.xlf delete mode 100644 Resources/Private/Language/de.locallang_db.xlf delete mode 100644 Resources/Private/Language/de.locallang_tca.xlf delete mode 100644 Resources/Private/Language/fr.locallang.xlf create mode 100644 Tests/Acceptance/Data/.gitkeep create mode 100644 Tests/Acceptance/EventListCest.php create mode 100644 Tests/Acceptance/Support/Environment.php create mode 100644 Tests/Acceptance/Support/Tester.php create mode 100644 Tests/Acceptance/Support/_generated/.gitignore create mode 100644 Tests/Fixtures/BackendUserDatabase.php create mode 100644 Tests/Fixtures/ContentDatabase.php create mode 100644 Tests/Fixtures/EventsDatabase.php create mode 100644 Tests/Fixtures/PagesDatabase.php create mode 100644 Tests/Fixtures/cart_events_test/Configuration/TypoScript/setup.typoscript create mode 100644 Tests/Fixtures/cart_events_test/composer.json create mode 100644 Tests/Fixtures/config/sites/default/config.yaml create mode 100644 codeception.dist.yml create mode 100644 shell.nix diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..91b84b7 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,81 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, +email, or any other method with the owners of this repository before making a change. + +## Getting Started + +* Make sure you have a [GitHub account](https://github.com/signup/free) +* Submit a ticket for your [issue](https://github.com/extcode/cart/issues), assuming one does not already exist. + * Clearly describe the issue including steps to reproduce when it is a bug. +* Fork the repository on GitHub + +## Making Changes + +* Create a topic branch from where you want to base your work. + * This is usually the master branch. + * Only target release branches if you are certain your fix must be on that + branch. + * To quickly create a topic branch based on master; `git checkout -b + fix/master/my_contribution master`. Please avoid working directly on the + `master` branch. +* Make commits of logical units. +* Use `./php-cs-fixer fix --config-file Build/.php_cs` to make sure the code is formatted correctly. +* Make sure your commit messages are in the proper format. Use either `[TASK]`, `[FEATURE]`, `[BUGFIX]` or `[DOC]` + +```` + [TASK] Make the example in CONTRIBUTING imperative and concrete + + The first line is a real life imperative statement. + The body describes the behavior without the patch, + why this is a problem, and how the patch fixes the problem when applied. + + Resolves: #123 +```` + +* Make sure you have added the necessary tests for your changes. +* Run _all_ the tests to assure nothing else was accidentally broken. However travis will do that for you as well. + +## Making Trivial Changes + +For changes of a trivial nature, it is not always necessary to create a new issue. + +## Additional resources + +* [Rendered documentation](https://docs.typo3.org/typo3cms/extensions/cart/) +* [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) + + +## Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and +welcoming community, we pledge to respect all people who contribute through reporting issues, +posting feature requests, updating documentation, submitting pull requests or patches, and other +activities. + +We are committed to making participation in this project a harassment-free experience for everyone, +regardless of level of experience, gender, gender identity and expression, sexual orientation, +disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, without explicit + permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, +code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By +adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently +applying these principles to every aspect of managing this project. Project maintainers who do not +follow or enforce the Code of Conduct may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), +version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ffb6d99 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: extcode +custom: ["https://paypal.me/extcart"] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..b03dc81 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,6 @@ + diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 0000000..c4be16a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug Report +about: If something isn't working as expected. + +--- + +## Bug Report + +**Current Behavior** +A clear and concise description of the behavior. + +**Expected behavior/output** +A clear and concise description of what you expected to happen. + +**Environment** +- TYPO3 version(s): [e.g. 8.7.12, 9.3.0] +- cart version: [e.g. 7.0.5] +- Is your TYPO3 installation set up with Composer (Composer Mode): [yes, no] +- OS: [e.g. OSX 10.13.4, Windows 10] + +**Possible Solution** + + +**Additional context** +Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 0000000..619ba21 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature Request +about: I have a suggestion! + +--- + +## Feature Request + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I have an issue when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. Add any considered drawbacks. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Teachability, Documentation, Adoption, Migration Strategy** +If you can, explain how users will be able to use this and possibly amend the documentation. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/Support_question.md b/.github/ISSUE_TEMPLATE/Support_question.md new file mode 100644 index 0000000..38a60c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Support_question.md @@ -0,0 +1,5 @@ +--- +name: Support Question +about: If you have a question, please check out our [Slack Channel](https://typo3.slack.com/messages/ext-cart/)! + +--- \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..7fc4df2 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,110 @@ +name: CI +on: + - pull_request +jobs: + check-composer: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Validate composer.json + run: composer validate + + php-linting: + runs-on: ubuntu-latest + strategy: + matrix: + php-version: + - 8.1 + - 8.2 + - 8.3 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php-version }}" + tools: composer:v2 + + - name: PHP lint + run: "find *.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l" + + coding-guideline: + runs-on: ubuntu-latest + needs: + - php-linting + steps: + - uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Coding Guideline + run: vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./ + + code-quality: + runs-on: ubuntu-latest + needs: + - php-linting + strategy: + matrix: + include: + - php-version: '8.1' + typo3-version: '^12.4' + - php-version: '8.2' + typo3-version: '^12.4' + - php-version: '8.3' + typo3-version: '^12.4' + steps: + - uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php-version }}" + tools: composer:v2 + + - name: Install dependencies with expected TYPO3 version + run: |- + composer require --no-interaction --prefer-dist --no-progress "typo3/cms-core:${{ matrix.typo3-version }}" "typo3/cms-extbase:${{ matrix.typo3-version }}" "typo3/cms-frontend:${{ matrix.typo3-version }}" + + - name: Code Quality (by PHPStan) + run: vendor/bin/phpstan analyse -c Build/phpstan.neon + + tests-acceptance: + runs-on: ubuntu-latest + needs: + - coding-guideline + - code-quality + steps: + - uses: actions/checkout@v3 + + - uses: cachix/install-nix-action@v17 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Run Unit Tests PHP8.1 + run: nix-shell --arg phpVersion \"php81\" --pure --run project-test-unit + + - name: Run Unit Tests PHP8.2 + run: nix-shell --arg phpVersion \"php82\" --pure --run project-test-unit + + - name: Run Unit Tests PHP8.3 + run: nix-shell --arg phpVersion \"php83\" --pure --run project-test-unit + + - name: Run Acceptance Tests PHP8.1 + run: nix-shell --arg phpVersion \"php81\" --pure --run project-test-acceptance + + - name: Run Acceptance Tests PHP8.2 + run: nix-shell --arg phpVersion \"php82\" --pure --run project-test-acceptance + + - name: Run Acceptance Tests PHP8.3 + run: nix-shell --arg phpVersion \"php83\" --pure --run project-test-acceptance diff --git a/.gitignore b/.gitignore index 228f31a..9f604ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,15 @@ .build composer.lock -.php_cs.cache -.phplint-cache -Build/.phpunit.result.cache +.php-cs-fixer.cache +.phplint.cache +Build/.phpunit.cache .DS_Store .idea +var/ +vendor/ + phpunit.coverage.xml phpunit.report.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6de4ed0..ca69da6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,23 +24,33 @@ stages: - analysis lint:cgl: - image: composer:2 + image: $CI_REGISTRY/containers/phpunit-with-php-8.1:main stage: lint before_script: - - composer config platform.php 7.4 + - sed -i -e "s#ssh://git@code.extco.de:22722#https://gitlab-ci-token:$CI_JOB_TOKEN@code.extco.de#g" composer.json + - composer config platform.php 8.1 - composer remove typo3/cms-core --no-update - composer install --no-progress --no-ansi --no-interaction script: - - .build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./ + - vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./ lint:typoscriptcgl: + image: php:8.1-alpine stage: lint - image: composer:2 - script: - - composer config platform.php 7.4 + before_script: + - apk add --no-cache bash curl git mercurial openssh openssl parallel subversion tini zlib-dev libzip-dev zip icu-dev g++ + - docker-php-ext-install mysqli && docker-php-ext-install zip && docker-php-ext-configure intl && docker-php-ext-install intl && docker-php-ext-enable intl + - wget https://composer.github.io/installer.sig -O - -q | tr -d '\n' > installer.sig + - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + - php -r "if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" + - php composer-setup.php --no-ansi --install-dir=/usr/bin --filename=composer + - php -r "unlink('composer-setup.php'); unlink('installer.sig');" + - sed -i -e "s#ssh://git@code.extco.de:22722#https://gitlab-ci-token:$CI_JOB_TOKEN@code.extco.de#g" composer.json + - composer config platform.php 8.1 - composer remove typo3/cms-core --no-update - composer install --no-progress --no-ansi --no-interaction - - .build/bin/typoscript-lint -c tslint.yaml + script: + - vendor/bin/typoscript-lint -c Build/typoscriptlint.yaml Configuration lint:yaml: stage: lint @@ -50,30 +60,6 @@ lint:yaml: script: - yamllint -c Build/yamllint.yaml Configuration/ Resources/ -lint:php72: - stage: lint - image: php:7.2-alpine - script: - - find . -name \*.php -exec php -l "{}" \; - -lint:php73: - stage: lint - image: php:7.3-alpine - script: - - find . -name \*.php -exec php -l "{}" \; - -lint:php74: - stage: lint - image: php:7.4-alpine - script: - - find . -name \*.php -exec php -l "{}" \; - -lint:php80: - stage: lint - image: php:8.0-alpine - script: - - find . -name \*.php -exec php -l "{}" \; - lint:php81: stage: lint image: php:8.1-alpine @@ -93,47 +79,34 @@ lint:php83: - find . -name \*.php -exec php -l "{}" \; phpstan:analyse: - image: composer:2 + image: $CI_REGISTRY/containers/phpunit-with-php-8.1:main stage: lint before_script: - - composer config platform.php 7.4 + - sed -i -e "s#ssh://git@code.extco.de:22722#https://gitlab-ci-token:$CI_JOB_TOKEN@code.extco.de#g" composer.json + - composer config platform.php 8.1 - composer install --no-progress --no-ansi --no-interaction - - composer req tpwd/ke_search "^4.4" script: - - .build/bin/phpstan analyse -c Build/phpstan.neon + - vendor/bin/phpstan analyse -c Build/phpstan.neon --memory-limit 256M -.test: &test_php +.test_php: &test_php stage: test services: - - mysql:5 - image: php:$DOCKER_TAG + - mysql:5 + image: $CONTAINER_IMAGE only: - branches before_script: - - apk add --no-cache bash curl git mercurial openssh openssl parallel subversion tini - - > - if [[ "$COVERAGE" == "1" ]]; then - apk add --no-cache $PHPIZE_DEPS - pecl install xdebug && docker-php-ext-enable xdebug - fi - - docker-php-ext-install mysqli - - wget https://composer.github.io/installer.sig -O - -q | tr -d '\n' > installer.sig - - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - - php -r "if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" - - php composer-setup.php --no-ansi --install-dir=/usr/bin --filename=composer - - php -r "unlink('composer-setup.php'); unlink('installer.sig');" - composer config --no-plugins allow-plugins.typo3/cms-composer-installers true - composer config --no-plugins allow-plugins.typo3/class-alias-loader true - composer require typo3/cms-core="${TYPO3_VERSION}" script: - > if [[ "$COVERAGE" == "0" ]]; then - .build/bin/phpunit -c Build/UnitTests.xml Tests/Unit + vendor/bin/phpunit -c Build/UnitTests.xml fi - > if [[ "$COVERAGE" == "1" ]]; then - composer require typo3/cms-install="${TYPO3_VERSION}" - XDEBUG_MODE=coverage .build/bin/phpunit --coverage-clover=phpunit.coverage.xml --log-junit=phpunit.report.xml -c Build/UnitTests.xml Tests/Unit + XDEBUG_MODE=coverage TYPO3_PATH_WEB=${TYPO3_PATH_WEB} vendor/bin/phpunit --coverage-clover=phpunit.coverage.xml --log-junit=phpunit.report.xml -c Build/UnitTests.xml Tests/Unit fi artifacts: paths: @@ -142,69 +115,81 @@ phpstan:analyse: expire_in: 1 day when: always -# Build in PHP 7.2 and TYPO3 10.4 -test:php72:typo3_10: - <<: *test_php - variables: - DOCKER_TAG: 7.2-alpine - TYPO3_VERSION: ^10.4 - COVERAGE: 0 - -# Build in PHP 7.3 and TYPO3 10.4 -test:php73:typo3_10: +# Build in PHP 8.1 and TYPO3 12.4 +test:php81:typo3_12: <<: *test_php variables: - DOCKER_TAG: 7.3-alpine - TYPO3_VERSION: ^10.4 + CONTAINER_IMAGE: $CI_REGISTRY/containers/phpunit-with-php-8.1:main + TYPO3_VERSION: ^12.4 COVERAGE: 0 -# Build in PHP 7.4 and TYPO3 10.4 -test:php74:typo3_10: +# Build in PHP 8.2 and TYPO3 12.4 +test:php82:typo3_12: <<: *test_php variables: - DOCKER_TAG: 7.4-alpine - TYPO3_VERSION: ^10.4 + CONTAINER_IMAGE: $CI_REGISTRY/containers/phpunit-with-php-8.2:main + TYPO3_VERSION: ^12.4 COVERAGE: 0 -# Build in PHP 7.4 and TYPO3 11.5 -test:php74:typo3_11: +# Build in PHP 8.3 and TYPO3 12.4 +test:php83:typo3_12: <<: *test_php variables: - DOCKER_TAG: 7.4-alpine - TYPO3_VERSION: ^11.5 - COVERAGE: 0 + CONTAINER_IMAGE: $CI_REGISTRY/containers/phpunit-with-php-8.3:main + TYPO3_VERSION: ^12.4 + COVERAGE: 1 -# Build in PHP 8.0 and TYPO3 11.5 -test:php80:typo3_11: - <<: *test_php - variables: - DOCKER_TAG: 8.0-alpine - TYPO3_VERSION: ^11.5 - COVERAGE: 0 +.test_codeception: &test_codeception + stage: test + image: $CONTAINER_IMAGE + only: + - branches + before_script: + - sed -i -e "s#ssh://git@code.extco.de:22722#https://gitlab-ci-token:$CI_JOB_TOKEN@code.extco.de#g" composer.json + - composer config --no-plugins allow-plugins.typo3/cms-composer-installers true + - composer config --no-plugins allow-plugins.typo3/class-alias-loader true + - composer require typo3/cms-core="${TYPO3_VERSION}" + script: + - mkdir -p .build/public/typo3temp/var/tests/acceptance-sqlite-dbs + - export typo3DatabaseDriver=pdo_sqlite + - export PROJECT_ROOT="$(pwd)" + - export INSTANCE_PATH="$(pwd)/.build/web/typo3temp/var/tests/acceptance" + - mkdir -p "$INSTANCE_PATH" + - mkdir -p "$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance-logs/" + - vendor/bin/codecept run + artifacts: + paths: + - .build + expire_in: 1 day + when: always -# Build in PHP 8.1 and TYPO3 11.5 -test:php81:typo3_11: - <<: *test_php +# Build in PHP 8.1 and TYPO3 12.4 +test:codception:php81:typo3_12: + <<: *test_codeception variables: - DOCKER_TAG: 8.1-alpine - TYPO3_VERSION: ^11.5 - COVERAGE: 0 - -# Build in PHP 8.2 and TYPO3 11.5 -test:php82:typo3_11: - <<: *test_php + CONTAINER_IMAGE: $CI_REGISTRY/containers/codeception-with-php-8.1:main + TYPO3_VERSION: ^12.4 + GECKODRIVER_VERSION: v0.34.0 + +# Build in PHP 8.2 and TYPO3 12.4 +test:codception:php82:typo3_12: + <<: *test_codeception + needs: + - test:codception:php81:typo3_12 variables: - DOCKER_TAG: 8.2-alpine - TYPO3_VERSION: ^11.5 - COVERAGE: 0 - -# Build in PHP 8.3 and TYPO3 11.5 -test:php83:typo3_11: - <<: *test_php + CONTAINER_IMAGE: $CI_REGISTRY/containers/codeception-with-php-8.2:main + TYPO3_VERSION: ^12.4 + GECKODRIVER_VERSION: v0.34.0 + +# Build in PHP 8.3 and TYPO3 12.4 +test:codception:php83:typo3_12: + <<: *test_codeception + needs: + - test:codception:php82:typo3_12 variables: - DOCKER_TAG: 8.3-alpine - TYPO3_VERSION: ^11.5 - COVERAGE: 1 + CONTAINER_IMAGE: $CI_REGISTRY/containers/codeception-with-php-8.3:main + TYPO3_VERSION: ^12.4 + GECKODRIVER_VERSION: v0.34.0 documentation: stage: documentation @@ -235,8 +220,8 @@ sonarqube: SONAR_SOURCES: "./Classes" SONAR_GITLAB_PROJECT_ID: "$CI_PROJECT_ID" script: - - echo "sonar.projectKey=cart-events-3.x" > sonar-project.properties - - gitlab-sonar-scanner -Dsonar.php.coverage.reportPath=phpunit.coverage.xml -Dsonar.php.tests.reportPath=phpunit.report.xml + - echo "sonar.projectKey=cart_events-5.x" > sonar-project.properties + - gitlab-sonar-scanner -Dsonar.php.coverage.reportPath=phpunit.coverage.xml -Dsonar.php.tests.reportPath=phpunit.report.xml allow_failure: true sonarqube-reports: @@ -249,6 +234,7 @@ sonarqube-reports: SONAR_PROJECT_VERSION: "$CI_JOB_ID" SONAR_ANALYSIS_MODE: "publish" SONAR_SOURCES: "./Classes" + SONAR_TESTS: "./Tests" script: - - echo "sonar.projectKey=cart-events-3.x" > sonar-project.properties - - gitlab-sonar-scanner -Dsonar.php.coverage.reportPath=phpunit.coverage.xml -Dsonar.php.tests.reportPath=phpunit.report.xml + - echo "sonar.projectKey=cart_events-5.x" > sonar-project.properties + - gitlab-sonar-scanner -Dsonar.php.coverage.reportPath=phpunit.coverage.xml -Dsonar.php.tests.reportPath=phpunit.report.xml diff --git a/Build/.php-cs-fixer.dist.php b/Build/.php-cs-fixer.dist.php index 121485b..58818f6 100644 --- a/Build/.php-cs-fixer.dist.php +++ b/Build/.php-cs-fixer.dist.php @@ -1,45 +1,63 @@ in(__DIR__ . '/../'); - -$config = new PhpCsFixer\Config(); -$config +return (new \PhpCsFixer\Config()) + ->setFinder( + (new PhpCsFixer\Finder()) + ->ignoreVCSIgnored(true) + ->in(__DIR__ . '/../') + ) ->setRiskyAllowed(true) ->setRules([ - '@PSR2' => true, - 'no_leading_import_slash' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_unused_imports' => true, + '@DoctrineAnnotation' => true, + '@PER-CS' => true, + 'array_syntax' => ['syntax' => 'short'], + 'cast_spaces' => ['space' => 'none'], 'concat_space' => ['spacing' => 'one'], - 'no_whitespace_in_blank_line' => true, - 'ordered_imports' => true, - 'single_quote' => true, + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_parentheses' => true, + 'dir_constant' => true, + 'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], + 'modernize_strpos' => true, + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, 'no_empty_statement' => true, 'no_extra_blank_lines' => true, - 'phpdoc_no_package' => true, - 'phpdoc_scalar' => true, - 'no_blank_lines_after_phpdoc' => true, - 'array_syntax' => ['syntax' => 'short'], - 'whitespace_after_comma_in_array' => true, - 'function_typehint_space' => true, - 'single_line_comment_style' => true, - 'no_alias_functions' => true, - 'lowercase_cast' => true, 'no_leading_namespace_whitespace' => true, - 'native_function_casing' => true, - 'self_accessor' => true, + 'no_null_property_initialization' => true, 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline' => true, 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_nullsafe_operator' => true, + 'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'], + 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], + 'php_unit_mock_short_will_return' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_no_access' => true, 'phpdoc_no_empty_return' => true, - 'phpdoc_trim' => true - ]) - ->setUsingCache(false) - ->setFinder($finder); - -return $config; + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'single_space_around_construct' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'type_declaration_spaces' => true, + 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], + 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], + ]); diff --git a/Build/FunctionalTests.xml b/Build/FunctionalTests.xml deleted file mode 100644 index 6163315..0000000 --- a/Build/FunctionalTests.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - ../Tests/Functional/ - - - - - ../Classes/ - - - diff --git a/Build/UnitTests.xml b/Build/UnitTests.xml index ed0bb6b..e4d3717 100644 --- a/Build/UnitTests.xml +++ b/Build/UnitTests.xml @@ -1,27 +1,13 @@ - - - - ../Tests/Unit/ - - - - - ../Classes/ - - - \ No newline at end of file + + + + ../Tests/Unit/ + + + + + ../Classes/ + + + diff --git a/Build/grumphp/resources/ascii/failed.txt b/Build/grumphp/resources/ascii/failed.txt deleted file mode 100644 index dbaee75..0000000 --- a/Build/grumphp/resources/ascii/failed.txt +++ /dev/null @@ -1,7 +0,0 @@ - -β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— -β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•— -β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ -β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ -β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• -β•šβ•β• β•šβ•β• β•šβ•β•β•šβ•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β• diff --git a/Build/grumphp/resources/ascii/succeeded.txt b/Build/grumphp/resources/ascii/succeeded.txt deleted file mode 100644 index 4a6479b..0000000 --- a/Build/grumphp/resources/ascii/succeeded.txt +++ /dev/null @@ -1,7 +0,0 @@ - -β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— -β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•— -β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ -β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ -β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• -β•šβ•β•β•β•β•β•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β• diff --git a/Classes/Controller/EventController.php b/Classes/Controller/EventController.php index 3988876..733c5db 100644 --- a/Classes/Controller/EventController.php +++ b/Classes/Controller/EventController.php @@ -1,5 +1,7 @@ cartUtility = $cartUtility; - } - - public function injectEventRepository(EventRepository $eventRepository): void - { - $this->eventRepository = $eventRepository; - } - - public function injectCategoryRepository(CategoryRepository $categoryRepository): void - { - $this->categoryRepository = $categoryRepository; - } + public function __construct( + private readonly SessionHandler $sessionHandler, + private readonly CartUtility $cartUtility, + private readonly EventRepository $eventRepository, + private readonly CategoryRepository $categoryRepository, + ) {} protected function initializeAction(): void { - $this->cartSettings = $this->configurationManager->getConfiguration( - ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, + $this->cartConfiguration = $this->configurationManager->getConfiguration( + ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'Cart' ); @@ -77,23 +60,24 @@ protected function initializeAction(): void } } - public function listAction(): void + public function listAction(): ResponseInterface { if (!$this->settings) { $this->settings = []; } $demand = $this->createDemandObjectFromSettings('list', $this->settings); - $demand->setActionAndClass(__METHOD__, __CLASS__); + $demand->setActionAndClass(__METHOD__, self::class); $events = $this->eventRepository->findDemanded($demand); $this->view->assign('events', $events); - $this->view->assign('cartSettings', $this->cartSettings); + $this->view->assign('cartSettings', $this->cartConfiguration); $this->addCacheTags($events); + return $this->htmlResponse(); } - public function teaserAction(): void + public function teaserAction(): ResponseInterface { $limit = (int)$this->settings['limit'] ?: (int)$this->configurationManager->getConfiguration( ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, @@ -103,36 +87,37 @@ public function teaserAction(): void $events = $this->eventRepository->findByUids($limit, $this->settings['eventUids']); $this->view->assign('events', $events); - $this->view->assign('cartSettings', $this->cartSettings); + $this->view->assign('cartSettings', $this->cartConfiguration); $this->addCacheTags($events); + return $this->htmlResponse(); } /** * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("event") */ - public function showAction(Event $event = null): void + #[IgnoreValidation(['value' => 'event'])] + public function showAction(Event $event = null): ResponseInterface { if (!$event) { $event = $this->getEvent(); } if (!$event) { - $this->forward('list'); + return new ForwardResponse('list'); } $this->view->assign('event', $event); - $this->view->assign('cartSettings', $this->cartSettings); + $this->view->assign('cartSettings', $this->cartConfiguration); $this->assignCurrencyTranslationData(); $this->addCacheTags([$event]); + return $this->htmlResponse(); } - /** - * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("eventDate") - * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("priceCategory") - */ - public function formAction(EventDate $eventDate = null, PriceCategory $priceCategory = null): void + #[IgnoreValidation(['value' => 'eventDate'])] + #[IgnoreValidation(['value' => 'priceCategory'])] + public function formAction(EventDate $eventDate = null, PriceCategory $priceCategory = null): ResponseInterface { if (!$eventDate) { $arguments = $this->request->getArguments(); @@ -208,6 +193,7 @@ public function formAction(EventDate $eventDate = null, PriceCategory $priceCate 'formDefinitionOverrides', $formDefinitionOverrides ); + return $this->htmlResponse(); } protected function getEvent(): ?Event @@ -238,9 +224,7 @@ protected function createDemandObjectFromSettings(string $type, array $settings) EventDemand::class ); - if (isset($settings['view']) && - is_array($settings['view']) && - isset($settings['view'][$type]) && + if (isset($settings['view'][$type]) && is_array($settings['view'][$type]) ) { // Use default TypoScript settings for plugin configuration @@ -256,10 +240,10 @@ protected function createDemandObjectFromSettings(string $type, array $settings) $demand->setLimit($limit); } - if (isset($settings['orderBy']) && !empty($settings['orderBy'])) { + if (!empty($settings['orderBy'])) { $orderBy = $settings['orderBy']; } - if (isset($settings['orderDirection']) && !empty($settings['orderDirection'])) { + if (!empty($settings['orderDirection'])) { $orderDirection = $settings['orderDirection']; } if (isset($orderBy) && isset($orderDirection)) { @@ -303,24 +287,15 @@ protected function addCategoriesToDemandObjectFromSettings(EventDemand &$demand) */ protected function assignCurrencyTranslationData(): void { - if (TYPO3_MODE === 'FE') { - $currencyTranslationData = []; + $this->restoreSession(); - $cartFrameworkConfig = $this->configurationManager->getConfiguration( - ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, - 'Cart' - ); - - $cart = $this->cartUtility->getCartFromSession($cartFrameworkConfig); - - if ($cart) { - $currencyTranslationData['currencyCode'] = $cart->getCurrencyCode(); - $currencyTranslationData['currencySign'] = $cart->getCurrencySign(); - $currencyTranslationData['currencyTranslation'] = $cart->getCurrencyTranslation(); - } + $currencyTranslationData = [ + 'currencyCode' => $this->cart->getCurrencyCode(), + 'currencySign' => $this->cart->getCurrencySign(), + 'currencyTranslation' => $this->cart->getCurrencyTranslation(), + ]; - $this->view->assign('currencyTranslationData', $currencyTranslationData); - } + $this->view->assign('currencyTranslationData', $currencyTranslationData); } protected function addCacheTags(iterable $events): void @@ -336,4 +311,17 @@ protected function addCacheTags(iterable $events): void } } } + + protected function restoreSession(): void + { + $cart = $this->sessionHandler->restoreCart($this->cartConfiguration['settings']['cart']['pid']); + + if ($cart instanceof Cart) { + $this->cart = $cart; + return; + } + + $this->cart = $this->cartUtility->getNewCart($this->cartConfiguration); + $this->sessionHandler->writeCart($this->cartConfiguration['settings']['cart']['pid'], $this->cart); + } } diff --git a/Classes/Controller/EventDateController.php b/Classes/Controller/EventDateController.php index d08de09..f307a56 100644 --- a/Classes/Controller/EventDateController.php +++ b/Classes/Controller/EventDateController.php @@ -1,5 +1,7 @@ eventDateRepository = $eventDateRepository; - } + public function __construct( + private readonly EventDateRepository $eventDateRepository, + ) {} protected function initializeAction(): void { @@ -37,7 +33,7 @@ protected function initializeAction(): void } } - public function listAction(): void + public function listAction(): ResponseInterface { if (!$this->settings) { $this->settings = []; @@ -57,6 +53,7 @@ public function listAction(): void $this->view->assign('eventDates', $eventDates); $this->addCacheTags($eventDates); + return $this->htmlResponse(); } protected function addCacheTags(iterable $eventDates): void diff --git a/Classes/Domain/Finisher/Form/AddToCartFinisher.php b/Classes/Domain/Finisher/Form/AddToCartFinisher.php index a13872f..2ec31e8 100644 --- a/Classes/Domain/Finisher/Form/AddToCartFinisher.php +++ b/Classes/Domain/Finisher/Form/AddToCartFinisher.php @@ -1,5 +1,7 @@ eventDateRepository = GeneralUtility::makeInstance( - EventDateRepository::class - ); $this->eventDate = $this->eventDateRepository->findByUid((int)$eventDateId); $quantity = 1; if ($priceCategoryId) { - $this->priceCategoryRepository = GeneralUtility::makeInstance( - PriceCategoryRepository::class - ); $this->priceCategory = $this->priceCategoryRepository->findByUid((int)$priceCategoryId); } diff --git a/Classes/Domain/Model/AbstractEventDate.php b/Classes/Domain/Model/AbstractEventDate.php index cd1d032..277852b 100644 --- a/Classes/Domain/Model/AbstractEventDate.php +++ b/Classes/Domain/Model/AbstractEventDate.php @@ -1,5 +1,7 @@ begin; } - /** - * @param \DateTime $begin - * @return CalendarEntry - */ - public function setBegin(\DateTime $begin): self + public function setBegin(\DateTime $begin): void { $this->begin = $begin; - return $this; } - /** - * @return \DateTime - */ public function getEnd(): ?\DateTime { return $this->end; } - /** - * @param \DateTime $end - * @return CalendarEntry - */ - public function setEnd(\DateTime $end): self + public function setEnd(\DateTime $end): void { $this->end = $end; - return $this; } - /** - * @return string - */ public function getNote(): string { return $this->note; } - /** - * @param string $note - * @return CalendarEntry - */ - public function setNote(string $note): self + public function setNote(string $note): void { $this->note = $note; - return $this; } } diff --git a/Classes/Domain/Model/CalendarEntry.php b/Classes/Domain/Model/CalendarEntry.php index 2adf476..387a9d2 100644 --- a/Classes/Domain/Model/CalendarEntry.php +++ b/Classes/Domain/Model/CalendarEntry.php @@ -1,5 +1,7 @@ sku; } - /** - * @param string $sku - */ public function setSku(string $sku): void { $this->sku = $sku; diff --git a/Classes/Domain/Model/Event.php b/Classes/Domain/Model/Event.php index aed27c5..74dd0cb 100644 --- a/Classes/Domain/Model/Event.php +++ b/Classes/Domain/Model/Event.php @@ -1,5 +1,7 @@ 'NotEmpty'])] + protected string $sku = ''; - /** - * @var string - */ - protected $teaser = ''; + #[Validate(['validator' => 'NotEmpty'])] + protected string $title = ''; - /** - * @var string - */ - protected $description = ''; + protected string $teaser = ''; - /** - * @var string - */ - protected $audience = ''; + protected string $description = ''; + + protected string $audience = ''; /** * @var ObjectStorage */ - protected $images; + protected ObjectStorage $images; /** * @var ObjectStorage */ - protected $files; + protected ObjectStorage $files; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove") * @var ObjectStorage */ - protected $eventDates; + #[Cascade(['value' => 'remove'])] + protected ObjectStorage $eventDates; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Lazy * @var ObjectStorage */ - protected $relatedEvents; + #[Lazy] + protected ObjectStorage $relatedEvents; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Lazy * @var ObjectStorage */ - protected $relatedEventsFrom; + #[Lazy] + protected ObjectStorage $relatedEventsFrom; - /** - * @var Category - */ - protected $category; + protected int $taxClassId = 1; - /** - * @var ObjectStorage - */ - protected $categories; - - /** - * @var ObjectStorage - */ - protected $tags; + protected string $metaDescription = ''; - /** - * @var int - */ - protected $taxClassId = 1; - - /** - * @var string - */ - protected $metaDescription = ''; + public function __construct() {} public function isVirtualProduct(): bool { return $this->virtualProduct; } - public function setVirtualProduct(bool $virtualProduct): self + public function setVirtualProduct(bool $virtualProduct): void { $this->virtualProduct = $virtualProduct; - return $this; } - public function getFormDefinition(): string + public function getFormDefinition(): ?string { return $this->formDefinition; } @@ -132,10 +100,9 @@ public function getSku(): string return $this->sku; } - public function setSku(string $sku): self + public function setSku(string $sku): void { $this->sku = $sku; - return $this; } public function getTitle(): string @@ -143,10 +110,9 @@ public function getTitle(): string return $this->title; } - public function setTitle(string $title): self + public function setTitle(string $title): void { $this->title = $title; - return $this; } public function getTeaser(): string @@ -154,10 +120,9 @@ public function getTeaser(): string return $this->teaser; } - public function setTeaser(string $teaser): self + public function setTeaser(string $teaser): void { $this->teaser = $teaser; - return $this; } public function getDescription(): string @@ -165,10 +130,9 @@ public function getDescription(): string return $this->description; } - public function setDescription(string $description): self + public function setDescription(string $description): void { $this->description = $description; - return $this; } public function getAudience(): string @@ -176,10 +140,9 @@ public function getAudience(): string return $this->audience; } - public function setAudience(string $audience): self + public function setAudience(string $audience): void { $this->audience = $audience; - return $this; } public function getImages(): ?ObjectStorage @@ -196,10 +159,9 @@ public function getFirstImage(): ?FileReference return array_shift($images); } - public function setImages(ObjectStorage $images): self + public function setImages(ObjectStorage $images): void { $this->images = $images; - return $this; } public function getFiles(): ?ObjectStorage @@ -207,14 +169,13 @@ public function getFiles(): ?ObjectStorage return $this->files; } - public function setFiles(ObjectStorage $files): self + public function setFiles(ObjectStorage $files): void { $this->files = $files; - return $this; } /** - * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Extcode\CartEvents\Domain\Model\EventDate> + * @return ObjectStorage */ public function getEventDates(): ?ObjectStorage { @@ -229,22 +190,19 @@ public function getFirstEventDate(): ?EventDate return $this->getEventDates()->current(); } - public function setEventDates(ObjectStorage $eventDates): self + public function setEventDates(ObjectStorage $eventDates): void { $this->eventDates = $eventDates; - return $this; } - public function addRelatedEvent(self $relatedEvent): self + public function addRelatedEvent(self $relatedEvent): void { $this->relatedEvents->attach($relatedEvent); - return $this; } - public function removeRelatedEvent(self $relatedEvent): self + public function removeRelatedEvent(self $relatedEvent): void { $this->relatedEvents->detach($relatedEvent); - return $this; } /** @@ -255,22 +213,19 @@ public function getRelatedEvents(): ?ObjectStorage return $this->relatedEvents; } - public function setRelatedEvents(ObjectStorage $relatedEvents): self + public function setRelatedEvents(ObjectStorage $relatedEvents): void { $this->relatedEvents = $relatedEvents; - return $this; } - public function addRelatedEventFrom(self $relatedEventFrom): self + public function addRelatedEventFrom(self $relatedEventFrom): void { $this->relatedEventsFrom->attach($relatedEventFrom); - return $this; } - public function removeRelatedEventFrom(self $relatedEventFrom): self + public function removeRelatedEventFrom(self $relatedEventFrom): void { $this->relatedEventsFrom->detach($relatedEventFrom); - return $this; } /** @@ -281,49 +236,9 @@ public function getRelatedEventsFrom(): ?ObjectStorage return $this->relatedEventsFrom; } - public function setRelatedEventsFrom(ObjectStorage $relatedEventsFrom): self + public function setRelatedEventsFrom(ObjectStorage $relatedEventsFrom): void { $this->relatedEventsFrom = $relatedEventsFrom; - return $this; - } - - public function getCategory(): ?Category - { - return $this->category; - } - - public function setCategory(Category $category): self - { - $this->category = $category; - return $this; - } - - /** - * @return ObjectStorage - */ - public function getCategories(): ObjectStorage - { - return $this->categories; - } - - public function setCategories(ObjectStorage $categories): self - { - $this->categories = $categories; - return $this; - } - - /** - * @return ObjectStorage - */ - public function getTags(): ObjectStorage - { - return $this->tags; - } - - public function setTags(ObjectStorage $tags): self - { - $this->tags = $tags; - return $this; } public function getTaxClassId(): int @@ -331,10 +246,9 @@ public function getTaxClassId(): int return $this->taxClassId; } - public function setTaxClassId(int $taxClassId): self + public function setTaxClassId(int $taxClassId): void { $this->taxClassId = $taxClassId; - return $this; } public function getMetaDescription(): string @@ -342,9 +256,8 @@ public function getMetaDescription(): string return $this->metaDescription; } - public function setMetaDescription(string $metaDescription): self + public function setMetaDescription(string $metaDescription): void { $this->metaDescription = $metaDescription; - return $this; } } diff --git a/Classes/Domain/Model/EventDate.php b/Classes/Domain/Model/EventDate.php index 2e4a170..31fe359 100644 --- a/Classes/Domain/Model/EventDate.php +++ b/Classes/Domain/Model/EventDate.php @@ -1,5 +1,7 @@ 'NotEmpty'])] + protected string $sku; - /** - * @var string - * @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty") - */ - protected $title = ''; + #[Validate(['validator' => 'NotEmpty'])] + protected string $title = ''; - /** - * @var string - */ - protected $location = ''; + protected string $location = ''; - /** - * @var string - */ - protected $lecturer = ''; + protected string $lecturer = ''; /** * @var ObjectStorage */ - protected $images; + protected ObjectStorage $images; /** * @var ObjectStorage */ - protected $files; + protected ObjectStorage $files; - /** - * @var bool - */ - protected $bookable = false; + protected bool $bookable = false; - /** - * @var float - */ - protected $price = 0.0; + protected float $price = 0.0; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove") * @var ObjectStorage */ - protected $specialPrices; + #[Cascade(['value' => 'remove'])] + protected ObjectStorage $specialPrices; - /** - * @var bool - */ - protected $priceCategorized = false; + protected bool $priceCategorized = false; - /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove") - * @var ObjectStorage - */ - protected $priceCategories; + #[Cascade(['value' => 'remove'])] + protected ObjectStorage $priceCategories; - /** - * @var bool - */ - protected $handleSeats = false; + protected bool $handleSeats = false; - /** - * @var bool - */ - protected $handleSeatsInPriceCategory = false; + protected bool $handleSeatsInPriceCategory = false; - /** - * @var int - */ - protected $seatsNumber = 0; + protected int $seatsNumber = 0; - /** - * @var int - */ - protected $seatsTaken = 0; + protected int $seatsTaken = 0; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove") * @var ObjectStorage */ - protected $calendarEntries; + #[Cascade(['value' => 'remove'])] + protected ObjectStorage $calendarEntries; - /** - * @return string - */ public function getSku(): string { return $this->sku; } - public function setSku(string $sku): self + public function setSku(string $sku): void { $this->sku = $sku; - return $this; } public function getTitle(): string @@ -123,10 +83,9 @@ public function getTitle(): string return $this->title; } - public function setTitle(string $title): self + public function setTitle(string $title): void { $this->title = $title; - return $this; } public function getLocation(): string @@ -134,10 +93,9 @@ public function getLocation(): string return $this->location; } - public function setLocation(string $location): self + public function setLocation(string $location): void { $this->location = $location; - return $this; } public function getLecturer(): string @@ -145,10 +103,9 @@ public function getLecturer(): string return $this->lecturer; } - public function setLecturer(string $lecturer): self + public function setLecturer(string $lecturer): void { $this->lecturer = $lecturer; - return $this; } /** @@ -168,10 +125,9 @@ public function getFirstImage(): ?FileReference return array_shift($images); } - public function setImages(ObjectStorage $images): self + public function setImages(ObjectStorage $images): void { $this->images = $images; - return $this; } /** @@ -182,10 +138,9 @@ public function getFiles(): ?ObjectStorage return $this->files; } - public function setFiles(ObjectStorage $files): self + public function setFiles(ObjectStorage $files): void { $this->files = $files; - return $this; } public function isBookable(): bool @@ -193,10 +148,9 @@ public function isBookable(): bool return $this->bookable; } - public function setBookable(bool $bookable): self + public function setBookable(bool $bookable): void { $this->bookable = $bookable; - return $this; } public function getPrice(): float @@ -204,10 +158,9 @@ public function getPrice(): float return $this->price; } - public function setPrice(float $price): self + public function setPrice(float $price): void { $this->price = $price; - return $this; } /** @@ -218,22 +171,19 @@ public function getSpecialPrices(): ?ObjectStorage return $this->specialPrices; } - public function addSpecialPrice(SpecialPrice $specialPrice): self + public function addSpecialPrice(SpecialPrice $specialPrice): void { $this->specialPrices->attach($specialPrice); - return $this; } - public function removeSpecialPrice(SpecialPrice $specialPrice): self + public function removeSpecialPrice(SpecialPrice $specialPrice): void { $this->specialPrices->detach($specialPrice); - return $this; } - public function setSpecialPrices(ObjectStorage $specialPrices): self + public function setSpecialPrices(ObjectStorage $specialPrices): void { $this->specialPrices = $specialPrices; - return $this; } public function isPriceCategorized(): bool @@ -262,16 +212,14 @@ public function getFirstAvailablePriceCategory(): ?PriceCategory return null; } - public function addPriceCategory(PriceCategory $priceCategory): self + public function addPriceCategory(PriceCategory $priceCategory): void { $this->priceCategories->attach($priceCategory); - return $this; } - public function removePriceCategory(PriceCategory $priceCategory): self + public function removePriceCategory(PriceCategory $priceCategory): void { $this->priceCategories->detach($priceCategory); - return $this; } public function setPriceCategories(ObjectStorage $priceCategories): void @@ -319,12 +267,7 @@ public function getCalendarEntries(): ?ObjectStorage usort($calendarEntryArr, function ($calendarEntry1, $calendarEntry2) { $begin1 = $calendarEntry1->getBegin(); $begin2 = $calendarEntry2->getBegin(); - - if ($begin1 === $begin2) { - return 0; - } - - return $begin1 < $begin2 ? -1 : 1; + return $begin1 <=> $begin2; }); foreach ($calendarEntryArr as $calendarEntry) { @@ -342,10 +285,9 @@ public function getFirstCalendarEntry(): ?CalendarEntry return $this->getCalendarEntries()->current(); } - public function setCalendarEntries(ObjectStorage $calendarEntries): self + public function setCalendarEntries(ObjectStorage $calendarEntries): void { $this->calendarEntries = $calendarEntries; - return $this; } public function getEvent(): ?Event @@ -353,10 +295,9 @@ public function getEvent(): ?Event return $this->event; } - public function setEvent(Event $event): self + public function setEvent(Event $event): void { $this->event = $event; - return $this; } public function isHandleSeats(): bool @@ -364,10 +305,9 @@ public function isHandleSeats(): bool return $this->handleSeats; } - public function setHandleSeats(bool $handleSeats): self + public function setHandleSeats(bool $handleSeats): void { $this->handleSeats = $handleSeats; - return $this; } public function isHandleSeatsInPriceCategory(): bool @@ -401,10 +341,9 @@ public function getSeatsNumber(): int return $this->seatsNumber; } - public function setSeatsNumber(int $seatsNumber): self + public function setSeatsNumber(int $seatsNumber): void { $this->seatsNumber = $seatsNumber; - return $this; } /** @@ -430,10 +369,9 @@ public function getSeatsTaken(): int return $this->seatsTaken; } - public function setSeatsTaken(int $seatsTaken): self + public function setSeatsTaken(int $seatsTaken): void { $this->seatsTaken = $seatsTaken; - return $this; } /** diff --git a/Classes/Domain/Model/PriceCategory.php b/Classes/Domain/Model/PriceCategory.php index 7578c3b..3417a9e 100644 --- a/Classes/Domain/Model/PriceCategory.php +++ b/Classes/Domain/Model/PriceCategory.php @@ -1,5 +1,7 @@ 'NotEmpty'])] + protected string $sku; - /** - * @var string - * @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty") - */ - protected $title = ''; + #[Validate(['validator' => 'NotEmpty'])] + protected string $title = ''; - /** - * @var float - */ - protected $price = 0.0; + protected float $price = 0.0; /** - * @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove") * @var ObjectStorage */ - protected $specialPrices; + #[Cascade(['value' => 'remove'])] + protected ObjectStorage $specialPrices; - /** - * @var int - */ - protected $seatsNumber = 0; + protected int $seatsNumber = 0; - /** - * @var int - */ - protected $seatsTaken = 0; + protected int $seatsTaken = 0; public function getSku(): string { @@ -101,22 +85,19 @@ public function getSpecialPrices(): ?ObjectStorage return $this->specialPrices; } - public function addSpecialPrice(SpecialPrice $specialPrice): self + public function addSpecialPrice(SpecialPrice $specialPrice): void { $this->specialPrices->attach($specialPrice); - return $this; } - public function removeSpecialPrice(SpecialPrice $specialPrice): self + public function removeSpecialPrice(SpecialPrice $specialPrice): void { $this->specialPrices->detach($specialPrice); - return $this; } - public function setSpecialPrices(ObjectStorage $specialPrices): self + public function setSpecialPrices(ObjectStorage $specialPrices): void { $this->specialPrices = $specialPrices; - return $this; } public function getSeatsNumber(): int diff --git a/Classes/Domain/Model/SpecialPrice.php b/Classes/Domain/Model/SpecialPrice.php index 0a10ade..f0f16fd 100644 --- a/Classes/Domain/Model/SpecialPrice.php +++ b/Classes/Domain/Model/SpecialPrice.php @@ -1,5 +1,7 @@ 'NotEmpty'])] + protected string $title = ''; - /** - * @var float - * @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty") - */ - protected $price = 0.0; + #[Validate(['validator' => 'NotEmpty'])] + protected float $price = 0.0; - /** - * @var FrontendUserGroup - */ - protected $frontendUserGroup; + protected FrontendUserGroup $frontendUserGroup; - /** - * @return string - */ public function getTitle(): string { return $this->title; } - public function setTitle(string $title): self + public function setTitle(string $title): void { $this->title = $title; - return $this; } public function getPrice(): float @@ -50,10 +40,9 @@ public function getPrice(): float return $this->price; } - public function setPrice(float $price): self + public function setPrice(float $price): void { $this->price = $price; - return $this; } public function getFrontendUserGroup(): ?FrontendUserGroup @@ -61,9 +50,8 @@ public function getFrontendUserGroup(): ?FrontendUserGroup return $this->frontendUserGroup; } - public function setFrontendUserGroup(FrontendUserGroup $frontendUserGroup): self + public function setFrontendUserGroup(FrontendUserGroup $frontendUserGroup): void { $this->frontendUserGroup = $frontendUserGroup; - return $this; } } diff --git a/Classes/Domain/Repository/CalendarEntryRepository.php b/Classes/Domain/Repository/CalendarEntryRepository.php index b06c65c..b31063b 100644 --- a/Classes/Domain/Repository/CalendarEntryRepository.php +++ b/Classes/Domain/Repository/CalendarEntryRepository.php @@ -1,5 +1,7 @@ $localCategory->getTitle(), 'parent' => $localCategory->getParent() ? $localCategory->getParent()->getUid() : null, 'subcategories' => null, - 'isSelected' => $selectedCategory == $localCategory + 'isSelected' => $selectedCategory == $localCategory, ]; $categories[] = $newCategory; } diff --git a/Classes/Domain/Repository/EventDateRepository.php b/Classes/Domain/Repository/EventDateRepository.php index 8de32e1..098f789 100644 --- a/Classes/Domain/Repository/EventDateRepository.php +++ b/Classes/Domain/Repository/EventDateRepository.php @@ -1,5 +1,7 @@ getCategories())) { $categoryConstraints = []; foreach ($demand->getCategories() as $category) { - $categoryConstraints[] = $query->contains('category', $category); + $categoryConstraints[] = $query->equals('category', $category); $categoryConstraints[] = $query->contains('categories', $category); } - $constraints = $query->logicalOr($categoryConstraints); + $constraints = $query->logicalOr(...array_values($categoryConstraints)); } if (!empty($constraints)) { $query->matching( - $query->logicalAnd($constraints) + $query->logicalAnd(...array_values($constraints)) ); } @@ -76,7 +78,7 @@ public function findByUids(int $limit, string $uids): array return $this->orderByField($query->execute(), $uids); } - protected function createOrderingsFromDemand(EventDemand $demand) : array + protected function createOrderingsFromDemand(EventDemand $demand): array { $orderings = []; @@ -84,7 +86,7 @@ protected function createOrderingsFromDemand(EventDemand $demand) : array if (!empty($orderList)) { foreach ($orderList as $orderItem) { - list($orderField, $ascDesc) = + [$orderField, $ascDesc] = GeneralUtility::trimExplode(' ', $orderItem, true); if ($ascDesc) { $orderings[$orderField] = ((strtolower($ascDesc) === 'desc') ? diff --git a/Classes/Domain/Repository/PriceCategoryRepository.php b/Classes/Domain/Repository/PriceCategoryRepository.php index 4b0caba..65cc277 100644 --- a/Classes/Domain/Repository/PriceCategoryRepository.php +++ b/Classes/Domain/Repository/PriceCategoryRepository.php @@ -1,4 +1,5 @@ eventDateRepository = $eventDateRepository; - $this->priceCategory = $priceCategoryRepository; - } + private readonly EventDateRepository $eventDateRepository, + ) {} public function __invoke(CheckProductAvailabilityEvent $listenerEvent): void { @@ -86,10 +64,7 @@ public function __invoke(CheckProductAvailabilityEvent $listenerEvent): void } } - /** - * @param Product $cartProduct - */ - protected function retrieveEventDateFromDatabase(Product $cartProduct) + protected function retrieveEventDateFromDatabase(Product $cartProduct): void { $querySettings = $this->eventDateRepository->createQuery()->getQuerySettings(); $querySettings->setRespectStoragePage(false); @@ -98,12 +73,7 @@ protected function retrieveEventDateFromDatabase(Product $cartProduct) $this->eventDate = $this->eventDateRepository->findByIdentifier($cartProduct->getProductId()); } - /** - * @param Request $request - * @param Product $cartProduct - * @return mixed - */ - protected function getQuantitiesFromRequest(Request $request, Product $cartProduct) + protected function getQuantitiesFromRequest(Request $request, Product $cartProduct): mixed { if ($request->hasArgument('quantities')) { $quantities = $request->getArgument('quantities'); @@ -124,17 +94,15 @@ protected function getQuantitiesFromRequest(Request $request, Product $cartProdu return 0; } - /** - * @param Product $cartProduct - * @param Cart $cart - * @param string $mode - * @param int $quantity - * @param CheckProductAvailabilityEvent $listenerEvent - */ - protected function hasEventDateEnoughSeats(Product $cartProduct, Cart $cart, string $mode, int $quantity, CheckProductAvailabilityEvent $listenerEvent): void - { - if (($mode === 'add') && $cart->getProduct($cartProduct->getId())) { - $quantity += $cart->getProduct($cartProduct->getId())->getQuantity(); + protected function hasEventDateEnoughSeats( + Product $cartProduct, + Cart $cart, + string $mode, + int $quantity, + CheckProductAvailabilityEvent $listenerEvent + ): void { + if (($mode === 'add') && $cart->getProductById($cartProduct->getId())) { + $quantity += $cart->getProductById($cartProduct->getId())->getQuantity(); } if ($quantity > $this->eventDate->getSeatsAvailable()) { @@ -147,26 +115,24 @@ protected function hasEventDateEnoughSeats(Product $cartProduct, Cart $cart, str 'cart' ), '', - AbstractMessage::ERROR + ContextualFeedbackSeverity::ERROR ) ); } } - /** - * @param Product $cartProduct - * @param Cart $cart - * @param string $mode - * @param string $beVariantId - * @param int $quantity - * @param $priceCategory - * @param CheckProductAvailabilityEvent $listenerEvent - */ - protected function hasPriceCategoryEnoughSeats(Product $cartProduct, Cart $cart, string $mode, string $beVariantId, int $quantity, $priceCategory, CheckProductAvailabilityEvent $listenerEvent): void - { - if (($mode === 'add') && $cart->getProduct($cartProduct->getId())) { - if ($cart->getProduct($cartProduct->getId())->getBeVariant($beVariantId)) { - $quantity += (int)$cart->getProduct($cartProduct->getId())->getBeVariant($beVariantId)->getQuantity(); + protected function hasPriceCategoryEnoughSeats( + Product $cartProduct, + Cart $cart, + string $mode, + string $beVariantId, + int $quantity, + $priceCategory, + CheckProductAvailabilityEvent $listenerEvent + ): void { + if (($mode === 'add') && $cart->getProductById($cartProduct->getId())) { + if ($cart->getProductById($cartProduct->getId())->getBeVariantById($beVariantId)) { + $quantity += (int)$cart->getProductById($cartProduct->getId())->getBeVariantById($beVariantId)->getQuantity(); } } if ($quantity > $priceCategory->getSeatsAvailable()) { @@ -179,7 +145,7 @@ protected function hasPriceCategoryEnoughSeats(Product $cartProduct, Cart $cart, 'cart' ), '', - AbstractMessage::ERROR + ContextualFeedbackSeverity::ERROR ) ); } diff --git a/Classes/EventListener/Order/Stock/FlushCache.php b/Classes/EventListener/Order/Stock/FlushCache.php index 2de4862..30caf3c 100644 --- a/Classes/EventListener/Order/Stock/FlushCache.php +++ b/Classes/EventListener/Order/Stock/FlushCache.php @@ -1,5 +1,7 @@ eventDateRepository = $eventDateRepository; - } + private readonly EventDateRepository $eventDateRepository + ) {} public function __invoke(EventInterface $event): void { diff --git a/Classes/EventListener/Order/Stock/HandleStock.php b/Classes/EventListener/Order/Stock/HandleStock.php index dde6f4e..1234871 100644 --- a/Classes/EventListener/Order/Stock/HandleStock.php +++ b/Classes/EventListener/Order/Stock/HandleStock.php @@ -1,5 +1,7 @@ persistenceManager = $persistenceManager; - $this->eventDateRepository = $eventDateRepository; - $this->priceCategoryRepository = $priceCategoryRepository; - } + private readonly PersistenceManager $persistenceManager, + private readonly EventDateRepository $eventDateRepository, + private readonly PriceCategoryRepository $priceCategoryRepository, + ) {} public function __invoke(EventInterface $event): void { @@ -53,17 +36,14 @@ public function __invoke(EventInterface $event): void } } - /** - * @param Product $cartProduct - */ - protected function handleStockForEventDate(Product $cartProduct) + protected function handleStockForEventDate(Product $cartProduct): void { $eventDate = $this->eventDateRepository->findByUid($cartProduct->getProductId()); if ($eventDate && $eventDate->isHandleSeats()) { if ($eventDate->isHandleSeatsInPriceCategory()) { foreach ($cartProduct->getBeVariants() as $cartBeVariant) { - $explodedId = explode('-', $cartBeVariant->getId()); + $explodedId = explode('-', (string)$cartBeVariant->getId()); $id = (int)end($explodedId); $priceCategory = $this->priceCategoryRepository->findByUid($id); $priceCategory->setSeatsTaken($priceCategory->getSeatsTaken() + $cartBeVariant->getQuantity()); diff --git a/Classes/EventListener/RetrieveProductsFromRequest.php b/Classes/EventListener/RetrieveProductsFromRequest.php index 1b1a350..9f2ae7d 100644 --- a/Classes/EventListener/RetrieveProductsFromRequest.php +++ b/Classes/EventListener/RetrieveProductsFromRequest.php @@ -1,5 +1,7 @@ eventDateRepository = $eventDateRepository; - $this->priceCategoryRepository = $priceCategoryRepository; - } + private readonly EventDateRepository $eventDateRepository, + private readonly PriceCategoryRepository $priceCategoryRepository + ) {} public function __invoke(RetrieveProductsFromRequestEvent $event): void { @@ -81,26 +62,30 @@ public function __invoke(RetrieveProductsFromRequestEvent $event): void if (!$this->eventDate) { $event->addError( - [ - 'messageBody' => LocalizationUtility::translate( + GeneralUtility::makeInstance( + FlashMessage::class, + LocalizationUtility::translate( 'tx_cartevents.error.event_date_not_found', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::WARNING - ] + '', + ContextualFeedbackSeverity::WARNING + ) ); return; } if (!$this->eventDate->isBookable()) { $event->addError( - [ - 'messageBody' => LocalizationUtility::translate( + GeneralUtility::makeInstance( + FlashMessage::class, + LocalizationUtility::translate( 'tx_cartevents.error.event_is_not_bookable', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::WARNING - ] + '', + ContextualFeedbackSeverity::WARNING + ) ); return; } @@ -108,13 +93,15 @@ public function __invoke(RetrieveProductsFromRequestEvent $event): void if (isset($requestArguments['priceCategory'])) { if (!(int)$requestArguments['priceCategory']) { $event->addError( - [ - 'messageBody' => LocalizationUtility::translate( + GeneralUtility::makeInstance( + FlashMessage::class, + LocalizationUtility::translate( 'tx_cartevents.plugin.form.submit.error.invalid_event_date_category_price', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::ERROR - ] + '', + ContextualFeedbackSeverity::ERROR + ) ); return; } @@ -123,13 +110,15 @@ public function __invoke(RetrieveProductsFromRequestEvent $event): void if (!$this->priceCategory->isBookable()) { $event->addError( - [ - 'messageBody' => LocalizationUtility::translate( + GeneralUtility::makeInstance( + FlashMessage::class, + LocalizationUtility::translate( 'tx_cartevents.plugin.form.submit.error.event_date.price_category.is_not_bookable', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::WARNING - ] + '', + ContextualFeedbackSeverity::WARNING + ) ); return; } @@ -155,7 +144,7 @@ protected function getProductFromEventDate( $sku = implode(' - ', [$event->getSku(), $this->eventDate->getSku()]); $price = $this->eventDate->getBestPrice(); - if ($this->priceCategory) { + if ($this->priceCategory instanceof PriceCategory) { $price = $this->priceCategory->getBestPrice(); } @@ -174,11 +163,11 @@ protected function getProductFromEventDate( ); $product->setIsVirtualProduct($event->isVirtualProduct()); - if ($this->priceCategory) { + if ($this->priceCategory instanceof PriceCategory) { $product->addBeVariant($this->getProductBackendVariant($product, $quantity)); } - if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart_events']['getProductFromEventDate']) { + if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart_events']['getProductFromEventDate'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart_events']['getProductFromEventDate'] ?? [] as $className) { $params = [ 'cart' => $this->cart, @@ -231,9 +220,9 @@ protected function checkRequestArguments(array $requestArguments): array return [ 'messageBody' => LocalizationUtility::translate( 'tx_cartevents.plugin.form.submit.error.invalid_event_date', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::ERROR + 'severity' => ContextualFeedbackSeverity::ERROR, ]; } @@ -241,9 +230,9 @@ protected function checkRequestArguments(array $requestArguments): array return [ 'messageBody' => LocalizationUtility::translate( 'tx_cart.error.invalid_quantity', - 'cart_events' + 'CartEvents' ), - 'severity' => AbstractMessage::WARNING + 'severity' => ContextualFeedbackSeverity::WARNING, ]; } diff --git a/Classes/Hooks/DataHandler.php b/Classes/Hooks/DataHandler.php index 981de34..88c1be9 100644 --- a/Classes/Hooks/DataHandler.php +++ b/Classes/Hooks/DataHandler.php @@ -17,14 +17,13 @@ */ class DataHandler { - /** * Flushes the cache if a news record was edited. * This happens on two levels: by UID and by PID. * * @param array $params */ - public function clearCachePostProc(array $params) + public function clearCachePostProc(array $params): void { if (isset($params['table']) && ($params['table'] === 'tx_cartevents_domain_model_event')) { $cacheTagsToFlush = []; diff --git a/Classes/Hooks/DatamapDataHandlerHook.php b/Classes/Hooks/DatamapDataHandlerHook.php index efd0034..cb0ab7f 100644 --- a/Classes/Hooks/DatamapDataHandlerHook.php +++ b/Classes/Hooks/DatamapDataHandlerHook.php @@ -1,5 +1,7 @@ datamap; if (empty($datamap['tt_content']) || $dataHandler->bypassAccessCheckForRecords) { @@ -63,7 +65,7 @@ public function processDatamap_beforeStart(DataHandler $dataHandler) } } - public function processDatamap_afterAllOperations(DataHandler $dataHandler) + public function processDatamap_afterAllOperations(DataHandler $dataHandler): void { $newIdUidArray = $dataHandler->substNEWwithIDs; @@ -84,7 +86,7 @@ public function processDatamap_afterAllOperations(DataHandler $dataHandler) protected function isAllowedTargetPage($listType, $doktype) { - if (empty($listType) || substr($listType, 0, 11) !== 'cartevents_') { + if (empty($listType) || !str_starts_with((string)$listType, 'cartevents_')) { return true; } if (($doktype == 186) && ($listType === 'cartevents_singleevent')) { diff --git a/Classes/Hooks/KeSearchEventsIndexer.php b/Classes/Hooks/KeSearchEventsIndexer.php deleted file mode 100644 index ed062d1..0000000 --- a/Classes/Hooks/KeSearchEventsIndexer.php +++ /dev/null @@ -1,86 +0,0 @@ -getPidList($indexerConfig); - - if ($indexPids === '') { - $eventIndexerMessage = 'ERROR: No Storage Pids configured!'; - } else { - $events = $this->getEventsToIndex($indexPids); - - if ($events) { - foreach ($events as $event) { - $targetPid = $this->getTargetPidFormPage($event['uid']); - - if ($targetPid) { - continue; - } - - // compile the information which should go into the index - // the field names depend on the table you want to index! - $sku = strip_tags($event['sku']); - $title = strip_tags($event['title']); - $teaser = strip_tags($event['teaser']); - $description = strip_tags($event['description']); - - $fullContent = $sku . "\n" . $title . "\n" . $teaser . "\n" . $description; - $tags = '#event#'; - $additionalFields = [ - 'sortdate' => $event['crdate'], - 'orig_uid' => $event['uid'], - 'orig_pid' => $event['pid'], - ]; - - $params = '&tx_cartevents_events[event]=' . $event['uid']; - - $targetPid = $this->getTargetPidFormCategory($event['category']); - - if ($targetPid == 0) { - $targetPid = $indexerConfig['targetpid']; - } - - $indexerObject->storeInIndex( - $indexerConfig['storagepid'], // storage PID - $title, // record title - 'cartevent', // content type - $targetPid, // target PID: where is the single view? - $fullContent, // indexed content, includes the title (linebreak after title) - $tags, // tags for faceted search - $params, // typolink params for singleview - $teaser, // abstract; shown in result list if not empty - $event['sys_language_uid'], // language uid - $event['starttime'], // starttime - $event['endtime'], // endtime - $event['fe_group'], // fe_group - false, // debug only? - $additionalFields // additionalFields - ); - } - $eventIndexerMessage = 'Success: ' . count($event) . ' event has been indexed.'; - } else { - $eventIndexerMessage = 'Warning: No event found in configured Storage Pids.'; - } - } - - return '

' . $eventIndexerName . '
' . $eventIndexerMessage . '

'; - } -} diff --git a/Classes/Hooks/KeSearchIndexer.php b/Classes/Hooks/KeSearchIndexer.php deleted file mode 100644 index dba3b6c..0000000 --- a/Classes/Hooks/KeSearchIndexer.php +++ /dev/null @@ -1,154 +0,0 @@ -indexerKey) && !empty($this->indexerName)) { - $newArray = [ - $this->indexerName, - $this->indexerKey, - ExtensionManagementUtility::extPath('cart_events') . 'ext_icon.svg' - ]; - $params['items'][] = $newArray; - } - } - - public function customIndexer(array &$indexerConfig, IndexerRunner &$indexerObject): string - { - if ($indexerConfig['type'] === $this->indexerKey) { - return $this->cartEventIndexer($indexerConfig, $indexerObject); - } - - return ''; - } - - abstract public function cartEventIndexer(array &$indexerConfig, IndexerRunner &$indexerObject): string; - - /** - * Returns all Storage Pids for indexing - */ - protected function getPidList(array $config): string - { - $recursivePids = $this->extendPidListByChildren($config['startingpoints_recursive'], 99); - if ($config['sysfolder']) { - return $recursivePids . ',' . $config['sysfolder']; - } - - return $recursivePids; - } - - /** - * Find all ids from given ids and level - */ - protected function extendPidListByChildren(string $pidList = '', $recursive = 0): string - { - $recursive = (int)$recursive; - - if ($recursive <= 0) { - return $pidList; - } - - $queryGenerator = GeneralUtility::makeInstance( - QueryGenerator::class - ); - $recursiveStoragePids = $pidList; - $storagePids = GeneralUtility::intExplode(',', $pidList); - foreach ($storagePids as $startPid) { - $pids = $queryGenerator->getTreeList($startPid, $recursive, 0, 1); - if (strlen($pids) > 0) { - $recursiveStoragePids .= ',' . $pids; - } - } - return $recursiveStoragePids; - } - - /** - * Returns all events for a given PidList - */ - protected function getEventsToIndex(string $indexPids): array - { - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('tx_cartevents_domain_model_event'); - - $queryBuilder - ->select('*') - ->from('tx_cartevents_domain_model_event') - ->where( - $queryBuilder->expr()->in('tx_cartevents_domain_model_event.pid', $indexPids) - ); - - return $queryBuilder->execute()->fetchAll(); - } - - protected function getTargetPidFormPage(int $eventUid): ?int - { - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('pages'); - - $constraints = [ - $queryBuilder->expr()->eq('pages.doktype', $queryBuilder->createNamedParameter('186', \PDO::PARAM_INT)), - $queryBuilder->expr()->eq('pages.cart_events_event', $queryBuilder->createNamedParameter($eventUid, \PDO::PARAM_INT)), - ]; - - $queryBuilder - ->select('pages.uid') - ->from('pages') - ->where(...$constraints); - - $page = $queryBuilder->execute()->fetch(); - - return $page['uid']; - } - - /** - * - */ - protected function getTargetPidFormCategory(int $categoryUid): ?int - { - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_category'); - - $constraints = [ - $queryBuilder->expr()->eq('sys_category_mm.tablenames', $queryBuilder->createNamedParameter('tx_cartevents_domain_model_event', \PDO::PARAM_STR)), - $queryBuilder->expr()->eq('sys_category_mm.fieldname', $queryBuilder->createNamedParameter('category', \PDO::PARAM_STR)), - $queryBuilder->expr()->eq('sys_category_mm.uid_foreign', $queryBuilder->createNamedParameter($categoryUid, \PDO::PARAM_INT)), - ]; - - $queryBuilder - ->select('sys_category.cart_event_show_pid') - ->from('sys_category') - ->leftJoin( - 'sys_category', - 'sys_category_record_mm', - 'sys_category_mm', - $queryBuilder->expr()->eq( - 'sys_category_mm.uid_local', - $queryBuilder->quoteIdentifier('sys_category.uid') - ) - ) - ->where(...$constraints); - - $sysCategory = $queryBuilder->execute()->fetch(); - - return $sysCategory['cart_event_show_pid']; - } -} diff --git a/Classes/Hooks/KeSearchSingleEventIndexer.php b/Classes/Hooks/KeSearchSingleEventIndexer.php deleted file mode 100644 index fa71a31..0000000 --- a/Classes/Hooks/KeSearchSingleEventIndexer.php +++ /dev/null @@ -1,78 +0,0 @@ -getPidList($indexerConfig); - - if ($indexPids === '') { - $eventIndexerMessage = 'ERROR: No Storage Pids configured!'; - } else { - $events = $this->getEventsToIndex($indexPids); - - if ($events) { - foreach ($events as $event) { - $targetPid = $this->getTargetPidFormPage($event['uid']); - - if (!$targetPid) { - continue; - } - - // compile the information which should go into the index - // the field names depend on the table you want to index! - $sku = strip_tags($event['sku']); - $title = strip_tags($event['title']); - $teaser = strip_tags($event['teaser']); - $description = strip_tags($event['description']); - - $fullContent = $sku . "\n" . $title . "\n" . $teaser . "\n" . $description; - $tags = '#event#'; - $additionalFields = [ - 'sortdate' => $event['crdate'], - 'orig_uid' => $event['uid'], - 'orig_pid' => $event['pid'], - ]; - - $indexerObject->storeInIndex( - $indexerConfig['storagepid'], // storage PID - $title, // record title - 'page', // content type - $targetPid, // target PID: where is the single view? - $fullContent, // indexed content, includes the title (linebreak after title) - $tags, // tags for faceted search - '', // typolink params for singleview - $teaser, // abstract; shown in result list if not empty - $event['sys_language_uid'], // language uid - $event['starttime'], // starttime - $event['endtime'], // endtime - $event['fe_group'], // fe_group - false, // debug only? - $additionalFields // additionalFields - ); - } - $eventIndexerMessage = 'Success: ' . count($event) . ' event has been indexed.'; - } else { - $eventIndexerMessage = 'Warning: No event found in configured Storage Pids.'; - } - } - - return '

' . $eventIndexerName . '
' . $eventIndexerMessage . '

'; - } -} diff --git a/Classes/Updates/SlugUpdater.php b/Classes/Updates/SlugUpdater.php index f2554c7..5d93db0 100644 --- a/Classes/Updates/SlugUpdater.php +++ b/Classes/Updates/SlugUpdater.php @@ -1,5 +1,7 @@ getQueryBuilderForTable(self::TABLE_NAME); $queryBuilder->getRestrictions()->removeAll(); $elementCount = $queryBuilder->count('uid') - ->from(self::TABLE_NAME) - ->where( - $queryBuilder->expr()->orX( - $queryBuilder->expr()->eq('path_segment', $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)), - $queryBuilder->expr()->isNull('path_segment') - ) - ) - ->execute()->fetchColumn(0); + ->from(self::TABLE_NAME)->where($queryBuilder->expr()->or($queryBuilder->expr()->eq('path_segment', $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)), $queryBuilder->expr()->isNull('path_segment')))->executeQuery()->fetchOne(); return (bool)$elementCount; } @@ -84,14 +79,7 @@ public function executeUpdate(): bool $queryBuilder = $connection->createQueryBuilder(); $queryBuilder->getRestrictions()->removeAll(); $statement = $queryBuilder->select('uid', 'title') - ->from(self::TABLE_NAME) - ->where( - $queryBuilder->expr()->orX( - $queryBuilder->expr()->eq('path_segment', $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)), - $queryBuilder->expr()->isNull('path_segment') - ) - ) - ->execute(); + ->from(self::TABLE_NAME)->where($queryBuilder->expr()->or($queryBuilder->expr()->eq('path_segment', $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)), $queryBuilder->expr()->isNull('path_segment')))->executeQuery(); while ($record = $statement->fetch()) { $queryBuilder = $connection->createQueryBuilder(); $queryBuilder->update(self::TABLE_NAME) diff --git a/Classes/ViewHelpers/Event/FreePlacesClassViewHelper.php b/Classes/ViewHelpers/Event/FreePlacesClassViewHelper.php index 9adf64b..b665c86 100644 --- a/Classes/ViewHelpers/Event/FreePlacesClassViewHelper.php +++ b/Classes/ViewHelpers/Event/FreePlacesClassViewHelper.php @@ -14,7 +14,7 @@ class FreePlacesClassViewHelper extends AbstractViewHelper { - public function initializeArguments() + public function initializeArguments(): void { parent::initializeArguments(); @@ -61,9 +61,9 @@ public function render(): string $returnColorPrefix = $this->arguments['returnColorPrefix'] ?? ''; if ($eventDate->isHandleSeats()) { - $greenLowerBound = $this->arguments['greenLowerBound'] ?? ($eventDate->getSeatsNumber() * 2/3); + $greenLowerBound = $this->arguments['greenLowerBound'] ?? ($eventDate->getSeatsNumber() * 2 / 3); $yellowLowerBound = $this->arguments['yellowLowerBound']; - $orangeLowerBound = $this->arguments['orangeLowerBound'] ?? ($eventDate->getSeatsNumber() * 1/3); + $orangeLowerBound = $this->arguments['orangeLowerBound'] ?? ($eventDate->getSeatsNumber() * 1 / 3); $orangeLowerBound = $orangeLowerBound <= 5 ? $orangeLowerBound : 5; if (($yellowLowerBound > $greenLowerBound) || ($yellowLowerBound < $orangeLowerBound)) { @@ -72,9 +72,11 @@ public function render(): string if ($eventDate->getSeatsAvailable() > $greenLowerBound) { return $returnColorPrefix . 'green'; - } elseif (isset($yellowLowerBound) && $eventDate->getSeatsAvailable() > $yellowLowerBound) { + } + if (isset($yellowLowerBound) && $eventDate->getSeatsAvailable() > $yellowLowerBound) { return $returnColorPrefix . 'yellow'; - } elseif ($eventDate->getSeatsAvailable() > $orangeLowerBound) { + } + if ($eventDate->getSeatsAvailable() > $orangeLowerBound) { return $returnColorPrefix . 'orange'; } } diff --git a/Classes/ViewHelpers/Form/PriceCategorySelectViewHelper.php b/Classes/ViewHelpers/Form/PriceCategorySelectViewHelper.php index 6fd29b4..d8e9900 100644 --- a/Classes/ViewHelpers/Form/PriceCategorySelectViewHelper.php +++ b/Classes/ViewHelpers/Form/PriceCategorySelectViewHelper.php @@ -8,9 +8,9 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ - use Extcode\Cart\ViewHelpers\Format\CurrencyViewHelper; use Extcode\CartEvents\Domain\Model\EventDate; +use Extcode\CartEvents\Domain\Model\PriceCategory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; @@ -23,7 +23,7 @@ class PriceCategorySelectViewHelper extends AbstractViewHelper */ protected $eventDate; - public function initializeArguments() + public function initializeArguments(): void { parent::initializeArguments(); @@ -88,12 +88,10 @@ protected function getOptions(): array foreach ($this->eventDate->getPriceCategories() as $priceCategory) { /** - * @var \Extcode\CartEvents\Domain\Model\PriceCategory $priceCategory + * @var PriceCategory $priceCategory */ $currencyViewHelper->setRenderChildrenClosure( - function () use ($priceCategory) { - return $priceCategory->getPrice(); - } + fn() => $priceCategory->getPrice() ); $regularPrice = $currencyViewHelper->render(); @@ -103,9 +101,7 @@ function () use ($priceCategory) { $specialPrice = $priceCategory->getBestSpecialPrice(); if ($specialPrice) { $currencyViewHelper->setRenderChildrenClosure( - function () use ($priceCategory) { - return $priceCategory->getBestPrice(); - } + fn() => $priceCategory->getBestPrice() ); $specialPricePrice = $currencyViewHelper->render(); diff --git a/Classes/ViewHelpers/Link/EventViewHelper.php b/Classes/ViewHelpers/Link/EventViewHelper.php index 9f3f4ab..1fe14d9 100644 --- a/Classes/ViewHelpers/Link/EventViewHelper.php +++ b/Classes/ViewHelpers/Link/EventViewHelper.php @@ -8,19 +8,45 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ - use Extcode\CartEvents\Domain\Model\Event; -use TYPO3\CMS\Core\Context\Context; -use TYPO3\CMS\Core\Context\LanguageAspect; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\ViewHelpers\Link\ActionViewHelper; +use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Extbase\Mvc\RequestInterface; +use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; +use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext; +use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; -class EventViewHelper extends ActionViewHelper +class EventViewHelper extends AbstractTagBasedViewHelper { - public function initializeArguments() + /** + * @var string + */ + protected $tagName = 'a'; + + public function initializeArguments(): void { parent::initializeArguments(); + $this->registerUniversalTagAttributes(); + $this->registerTagAttribute('name', 'string', 'Specifies the name of an anchor'); + $this->registerTagAttribute('rel', 'string', 'Specifies the relationship between the current document and the linked document'); + $this->registerTagAttribute('rev', 'string', 'Specifies the relationship between the linked document and the current document'); + $this->registerTagAttribute('target', 'string', 'Specifies where to open the linked document'); + $this->registerArgument('action', 'string', 'Target action'); + $this->registerArgument('controller', 'string', 'Target controller. If NULL current controllerName is used'); + $this->registerArgument('extensionName', 'string', 'Target Extension Name (without `tx_` prefix and no underscores). If NULL the current extension name is used'); + $this->registerArgument('pluginName', 'string', 'Target plugin. If empty, the current plugin name is used'); + $this->registerArgument('pageUid', 'int', 'Target page. See TypoLink destination'); + $this->registerArgument('pageType', 'int', 'Type of the target page. See typolink.parameter'); + $this->registerArgument('noCache', 'bool', 'Set this to disable caching for the target page. You should not need this.'); + $this->registerArgument('section', 'string', 'The anchor to be added to the URI'); + $this->registerArgument('format', 'string', 'The requested format, e.g. ".html'); + $this->registerArgument('linkAccessRestrictedPages', 'bool', 'If set, links pointing to access restricted pages will still link to the page even though the page cannot be accessed.'); + $this->registerArgument('additionalParams', 'array', 'Additional query parameters that won\'t be prefixed like $arguments (overrule $arguments)'); + $this->registerArgument('absolute', 'bool', 'If set, the URI of the rendered link is absolute'); + $this->registerArgument('addQueryString', 'bool', 'If set, the current query parameters will be kept in the URI'); + $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'Arguments to be removed from the URI. Only active if $addQueryString = TRUE'); + $this->registerArgument('arguments', 'array', 'Arguments for the controller action, associative array'); $this->registerArgument( 'event', @@ -36,46 +62,81 @@ public function initializeArguments() ); } - /** - * returns the gendered link - */ public function render(): string { + /** @var RenderingContext $renderingContext */ + $renderingContext = $this->renderingContext; + $request = $renderingContext->getRequest(); + if (!$request instanceof RequestInterface) { + throw new \RuntimeException( + 'ViewHelper f:link.action can be used only in extbase context and needs a request implementing extbase RequestInterface.', + 1639818540 + ); + } + + $action = $this->arguments['action']; + $controller = $this->arguments['controller']; + $extensionName = $this->arguments['extensionName']; + $pluginName = $this->arguments['pluginName']; + $pageUid = (int)$this->arguments['pageUid'] ?: null; + $pageType = (int)$this->arguments['pageType']; + $noCache = (bool)$this->arguments['noCache']; + $section = (string)$this->arguments['section']; + $format = (string)$this->arguments['format']; + $linkAccessRestrictedPages = (bool)$this->arguments['linkAccessRestrictedPages']; + $additionalParams = (array)$this->arguments['additionalParams']; + $absolute = (bool)$this->arguments['absolute']; + $addQueryString = (bool)$this->arguments['addQueryString']; + $argumentsToBeExcludedFromQueryString = (array)$this->arguments['argumentsToBeExcludedFromQueryString']; + $event = $this->arguments['event']; $page = $this->getEventPage($event); if ($page) { - $languageId = $this->getCurrentLanguageAspect()->getId(); - - if ( - !( - GeneralUtility::hideIfDefaultLanguage($page['l18n_cfg']) - && (!$languageId || ($languageId && !$page['_PAGES_OVERLAY'])) - ) - && - !( - $languageId - && GeneralUtility::hideIfNotTranslated($page['l18n_cfg']) - && !$page['_PAGES_OVERLAY'] - ) - ) { - $this->arguments['pageUid'] = $page['uid']; - } else { - return ''; - } + $this->arguments['pageUid'] = $page['uid']; } else { - if ($event->getCategory() && $event->getCategory()->getCartEventShowPid()) { - $this->arguments['pageUid'] = $event->getCategory()->getCartEventShowPid(); + $pluginName = 'Events'; + + if ($event->getCategory() && $event->getCategory()->getCartProductShowPid()) { + $pageUid = $event->getCategory()->getCartProductShowPid(); } elseif ($this->arguments['settings']['showPageUids']) { - $this->arguments['pageUid'] = $this->arguments['settings']['showPageUids']; + $pageUid = $this->arguments['settings']['showPageUids']; } - $this->arguments['action'] = 'show'; + $action = 'show'; $this->arguments['arguments']['event'] = $event; } - return parent::render(); + $parameters = $this->arguments['arguments']; + + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + $uriBuilder + ->reset() + ->setRequest($request) + ->setTargetPageType($pageType) + ->setNoCache($noCache) + ->setSection($section) + ->setFormat($format) + ->setLinkAccessRestrictedPages($linkAccessRestrictedPages) + ->setArguments($additionalParams) + ->setCreateAbsoluteUri($absolute) + ->setAddQueryString($addQueryString) + ->setArgumentsToBeExcludedFromQueryString($argumentsToBeExcludedFromQueryString) + ; + + if (MathUtility::canBeInterpretedAsInteger($pageUid)) { + $uriBuilder->setTargetPageUid((int)$pageUid); + } + + $uri = $uriBuilder->uriFor($action, $parameters, $controller, $extensionName, $pluginName); + if ($uri === '') { + return $this->renderChildren(); + } + $this->tag->addAttribute('href', $uri); + $this->tag->setContent($this->renderChildren()); + $this->tag->forceClosingTag(true); + return $this->tag->render(); } /** @@ -90,18 +151,6 @@ protected function getEventPage(Event $event) ->where( $queryBuilder->expr()->eq('cart_events_event', $event->getUid()) ) - ->orderBy('sorting') - ->setMaxResults(1) - ->execute() - ->fetch(); - } - - /** - * @return LanguageAspect - * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException - */ - protected function getCurrentLanguageAspect(): LanguageAspect - { - return GeneralUtility::makeInstance(Context::class)->getAspect('language'); + ->orderBy('sorting')->setMaxResults(1)->executeQuery()->fetchAssociative(); } } diff --git a/Classes/ViewHelpers/SchemaViewHelper.php b/Classes/ViewHelpers/SchemaViewHelper.php index 6cb0045..43f2111 100644 --- a/Classes/ViewHelpers/SchemaViewHelper.php +++ b/Classes/ViewHelpers/SchemaViewHelper.php @@ -21,7 +21,7 @@ class SchemaViewHelper extends AbstractViewHelper */ protected $escapeOutput = false; - public function initializeArguments() + public function initializeArguments(): void { parent::initializeArguments(); @@ -58,7 +58,7 @@ public function render(): string '@type' => 'Offer', 'price' => $eventDate->getPrice(), 'priceCurrency' => 'EUR', - ] + ], ]; } } diff --git a/Configuration/Extbase/Persistence/Classes.php b/Configuration/Extbase/Persistence/Classes.php index acd1e81..35b11e7 100644 --- a/Configuration/Extbase/Persistence/Classes.php +++ b/Configuration/Extbase/Persistence/Classes.php @@ -1,4 +1,5 @@ [ 'tableName' => 'sys_category', - ] + ], ]; diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 0000000..b9a7a88 --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,20 @@ + [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:cart_events/Resources/Public/Icons/apps_pagetree_folder_cartevents_events.svg', + ], + 'apps-pagetree-page-cartevents-events' => [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:cart_events/Resources/Public/Icons/apps_pagetree_page_cartevents_events.svg', + ], + 'ext-cartevents-wizard-icon' => [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:cart_events/Resources/Public/Icons/cartevents_plugin_wizard.svg', + ], +]; diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php index 359c24a..a147b73 100644 --- a/Configuration/TCA/Overrides/pages.php +++ b/Configuration/TCA/Overrides/pages.php @@ -1,6 +1,6 @@ $_LLL_be . ':pages.singleview_cart_events_event', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'allowed' => 'tx_cartevents_domain_model_event', 'foreign_table' => 'tx_cartevents_domain_model_event', 'minitems' => 0, diff --git a/Configuration/TCA/Overrides/sys_category.php b/Configuration/TCA/Overrides/sys_category.php index 88d4467..cf8c032 100644 --- a/Configuration/TCA/Overrides/sys_category.php +++ b/Configuration/TCA/Overrides/sys_category.php @@ -1,6 +1,6 @@ $_LLL_db . 'tx_cartevents_domain_model_category.cart_event_list_pid', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'allowed' => 'pages', 'size' => 1, 'maxitems' => 1, @@ -23,14 +22,13 @@ 'searchWholePhrase' => true, ], ], - ] + ], ], 'cart_event_show_pid' => [ 'exclude' => 1, 'label' => $_LLL_db . 'tx_cartevents_domain_model_category.cart_event_show_pid', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'allowed' => 'pages', 'size' => 1, 'maxitems' => 1, @@ -41,7 +39,7 @@ 'searchWholePhrase' => true, ], ], - ] + ], ], ]; diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php index a848aad..55bb93b 100644 --- a/Configuration/TCA/Overrides/sys_template.php +++ b/Configuration/TCA/Overrides/sys_template.php @@ -1,6 +1,6 @@ [ - 'subtypes_excludelist' => 'select_key' + 'subtypes_excludelist' => 'select_key', ], 'TeaserEvents' => [ - 'subtypes_excludelist' => 'select_key, pages, recursive' + 'subtypes_excludelist' => 'select_key, pages, recursive', ], 'SingleEvent' => [ - 'subtypes_excludelist' => 'select_key, pages, recursive' + 'subtypes_excludelist' => 'select_key, pages, recursive', ], 'EventDates' => [ - 'subtypes_excludelist' => 'select_key, recursive' + 'subtypes_excludelist' => 'select_key, recursive', ], ]; foreach ($pluginNames as $pluginName => $pluginConf) { $pluginSignature = 'cartevents_' . strtolower($pluginName); - $pluginNameSC = strtolower(preg_replace('/[A-Z]/', '_$0', lcfirst($pluginName))); + $pluginNameSC = strtolower((string)preg_replace('/[A-Z]/', '_$0', lcfirst($pluginName))); ExtensionUtility::registerPlugin( 'CartEvents', $pluginName, diff --git a/Configuration/TCA/Overrides/tx_cartevents_domain_model_event.php b/Configuration/TCA/Overrides/tx_cartevents_domain_model_event.php index 966f2eb..8b5a5a3 100644 --- a/Configuration/TCA/Overrides/tx_cartevents_domain_model_event.php +++ b/Configuration/TCA/Overrides/tx_cartevents_domain_model_event.php @@ -1,6 +1,6 @@ 'select', 'renderType' => 'selectSingle', 'items' => [ - ['LLL:EXT:form/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.formframework.selectPersistenceIdentifier', ''], + ['label' => 'LLL:EXT:form/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.formframework.selectPersistenceIdentifier', 'value' => ''], ], 'itemsProcFunc' => 'Extcode\\Cart\\Hooks\\ItemsProcFunc->user_formDefinition', 'itemsProcFuncConfig' => [ - 'prototypeName' => 'cart-events' + 'prototypeName' => 'cart-events', ], 'size' => 1, 'minitems' => 0, @@ -45,49 +45,17 @@ ); } -ExtensionManagementUtility::makeCategorizable( - 'cart_events', - 'tx_cartevents_domain_model_event', - 'category', - [ - 'label' => $_LLL_db . 'tx_cartevents_domain_model_event.category', - 'fieldConfiguration' => [ - 'minitems' => 0, - 'maxitems' => 1, - 'multiple' => false, - ] - ] -); - -$GLOBALS['TCA']['tx_cartevents_domain_model_event']['category']['config']['maxitems'] = 1; - -ExtensionManagementUtility::makeCategorizable( - 'cart_events', - 'tx_cartevents_domain_model_event', - 'categories', - [ - 'label' => $_LLL_db . 'tx_cartevents_domain_model_event.categories' - ] -); - // category restriction based on settings in extension manager $categoryRestrictionSetting = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('cart_events', 'categoryRestriction'); if ($categoryRestrictionSetting) { $categoryRestriction = ''; - switch ($categoryRestrictionSetting) { - case 'current_pid': - $categoryRestriction = ' AND sys_category.pid=###CURRENT_PID### '; - break; - case 'siteroot': - $categoryRestriction = ' AND sys_category.pid IN (###SITEROOT###) '; - break; - case 'page_tsconfig': - $categoryRestriction = ' AND sys_category.pid IN (###PAGE_TSCONFIG_IDLIST###) '; - break; - default: - $categoryRestriction = ''; - } + $categoryRestriction = match ($categoryRestrictionSetting) { + 'current_pid' => ' AND sys_category.pid=###CURRENT_PID### ', + 'siteroot' => ' AND sys_category.pid IN (###SITEROOT###) ', + 'page_tsconfig' => ' AND sys_category.pid IN (###PAGE_TSCONFIG_IDLIST###) ', + default => '', + }; // prepend category restriction at the beginning of foreign_table_where if (!empty($categoryRestriction)) { diff --git a/Configuration/TCA/Overrides/tx_cartevents_domain_model_eventdate.php b/Configuration/TCA/Overrides/tx_cartevents_domain_model_eventdate.php index fb3a520..a5eb676 100644 --- a/Configuration/TCA/Overrides/tx_cartevents_domain_model_eventdate.php +++ b/Configuration/TCA/Overrides/tx_cartevents_domain_model_eventdate.php @@ -1,6 +1,6 @@ 1, 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', 'hideTable' => true, 'delete' => 'deleted', @@ -24,7 +23,7 @@ 'endtime' => 'endtime', ], 'searchFields' => 'title', - 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_calendarentry.svg' + 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_calendarentry.svg', ], 'types' => [ '1' => [ @@ -32,12 +31,12 @@ begin, end, note, --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access, --palette--;' . $_LLL_tca . ':palettes.visibility;hiddenonly - ' + ', ], ], 'palettes' => [ '1' => [ - 'showitem' => '' + 'showitem' => '', ], 'hiddenonly' => [ 'showitem' => 'hidden;' . $_LLL_db . ':tx_cartevents_domain_model_calendarentry', @@ -50,11 +49,6 @@ 'config' => [ 'type' => 'check', 'renderType' => 'checkboxToggle', - 'items' => [ - '1' => [ - '0' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:hidden.I.0' - ] - ] ], ], @@ -62,14 +56,12 @@ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.starttime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -77,14 +69,12 @@ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.endtime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -92,21 +82,18 @@ 'begin' => [ 'label' => $_LLL_db . ':tx_cartevents_domain_model_calendarentry.begin', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'required,datetime', 'checkbox' => 0, 'default' => 0, + 'required' => true, ], ], 'end' => [ 'label' => $_LLL_db . ':tx_cartevents_domain_model_calendarentry.end', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], diff --git a/Configuration/TCA/tx_cartevents_domain_model_event.php b/Configuration/TCA/tx_cartevents_domain_model_event.php index 1b51093..827fc22 100644 --- a/Configuration/TCA/tx_cartevents_domain_model_event.php +++ b/Configuration/TCA/tx_cartevents_domain_model_event.php @@ -1,9 +1,8 @@ 1, 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', 'sortby' => 'sorting', @@ -37,7 +35,7 @@ 'endtime' => 'endtime', ], 'searchFields' => 'sku,title,teaser,description,audience', - 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_event.svg' + 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_event.svg', ], 'types' => [ '1' => [ @@ -58,12 +56,12 @@ --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access, --palette--;' . $_LLL_tca . ':palettes.visibility;hiddenonly, --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access, - ' + ', ], ], 'palettes' => [ '1' => [ - 'showitem' => '' + 'showitem' => '', ], 'hiddenonly' => [ 'showitem' => 'hidden;' . $_LLL_db . ':tx_cartevents_domain_model_event', @@ -77,19 +75,7 @@ 'sys_language_uid' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.language', - 'config' => [ - 'type' => 'select', - 'renderType' => 'selectSingle', - 'special' => 'languages', - 'items' => [ - [ - $_LLL_general . ':LGL.allLanguages', - -1, - 'flags-multiple' - ], - ], - 'default' => 0, - ], + 'config' => ['type' => 'language'], ], 'l10n_parent' => [ 'displayCond' => 'FIELD:sys_language_uid:>:0', @@ -98,7 +84,7 @@ 'type' => 'select', 'renderType' => 'selectSingle', 'items' => [ - ['', 0], + ['label' => '', 'value' => 0], ], 'foreign_table' => 'tx_cartevents_domain_model_event', 'foreign_table_where' => 'AND tx_cartevents_domain_model_event.pid=###CURRENT_PID### AND tx_cartevents_domain_model_event.sys_language_uid IN (-1,0)', @@ -121,7 +107,7 @@ 'type' => 'input', 'size' => 30, 'max' => 255, - ] + ], ], 'hidden' => [ 'exclude' => 1, @@ -129,25 +115,18 @@ 'config' => [ 'type' => 'check', 'renderType' => 'checkboxToggle', - 'items' => [ - '1' => [ - '0' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:hidden.I.0' - ] - ] ], ], 'starttime' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.starttime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -155,14 +134,12 @@ 'exclude' => 1, 'label' => 'LLL' . ':EXT:lang/locallang_general.xlf:LGL.endtime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -173,7 +150,8 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'required,trim' + 'eval' => 'trim', + 'required' => true, ], ], 'title' => [ @@ -182,7 +160,8 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'required,trim' + 'eval' => 'trim', + 'required' => true, ], ], 'path_segment' => [ @@ -226,7 +205,7 @@ 'type' => 'text', 'cols' => 40, 'rows' => 5, - 'eval' => 'trim' + 'eval' => 'trim', ], ], 'audience' => [ @@ -243,7 +222,6 @@ 'label' => $_LLL_db . ':tx_cartevents_domain_model_event.related_events', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'allowed' => 'tx_cartevents_domain_model_event', 'foreign_table' => 'tx_cartevents_domain_model_event', 'MM_opposite_field' => 'related_events_from', @@ -256,7 +234,7 @@ 'searchWholePhrase' => true, ], ], - ] + ], ], 'related_events_from' => [ @@ -264,136 +242,131 @@ 'label' => $_LLL_db . ':tx_cartevents_domain_model_event.related_events_from', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'foreign_table' => 'tx_cartevents_domain_model_event', 'allowed' => 'tx_cartevents_domain_model_event', 'size' => 5, 'maxitems' => 100, 'MM' => 'tx_cartevents_domain_model_event_event_related_mm', 'readOnly' => 1, - ] + ], ], 'images' => [ 'exclude' => 1, 'label' => $_LLL_db . ':tx_cartevents_domain_model_event.images', - 'config' => ExtensionManagementUtility::getFileFieldTCAConfig( - 'images', - [ - 'appearance' => [ - 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', - 'showPossibleLocalizationRecords' => true, - 'showRemovedLocalizationRecords' => true, - 'showAllLocalizationLink' => true, - 'showSynchronizationLink' => true, - ], - 'foreign_match_fields' => [ - 'fieldname' => 'image', - 'tablenames' => 'tx_cartevents_domain_model_event', - 'table_local' => 'sys_file', - ], - // custom configuration for displaying fields in the overlay/reference table - // to use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' + 'config' => [ + //## !!! Watch out for fieldName different from columnName + 'type' => 'file', + 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], + 'appearance' => [ + 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', + 'showPossibleLocalizationRecords' => true, + 'showRemovedLocalizationRecords' => true, + 'showAllLocalizationLink' => true, + 'showSynchronizationLink' => true, + ], + 'foreign_match_fields' => [ + 'fieldname' => 'image', + 'tablenames' => 'tx_cartevents_domain_model_event', + ], + // custom configuration for displaying fields in the overlay/reference table + // to use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_TEXT => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_TEXT => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_IMAGE => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_IMAGE => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_AUDIO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_AUDIO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_VIDEO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_VIDEO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_APPLICATION => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_APPLICATION => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], + --palette--;;filePalette', ], ], - 'minitems' => 0, - 'maxitems' => 99, ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'minitems' => 0, + 'maxitems' => 99, + ], ], 'files' => [ 'exclude' => 1, 'label' => $_LLL_db . ':tx_cartevents_domain_model_event.files', - 'config' => ExtensionManagementUtility::getFileFieldTCAConfig( - 'files', - [ - 'appearance' => [ - 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', - 'showPossibleLocalizationRecords' => true, - 'showRemovedLocalizationRecords' => true, - 'showAllLocalizationLink' => true, - 'showSynchronizationLink' => true, - ], - 'foreign_match_fields' => [ - 'fieldname' => 'files', - 'tablenames' => 'tx_cartevents_domain_model_event', - 'table_local' => 'sys_file', - ], - // custom configuration for displaying fields in the overlay/reference table - // to use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' + 'config' => [ + //## !!! Watch out for fieldName different from columnName + 'type' => 'file', + 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] . ', pdf', + 'appearance' => [ + 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', + 'showPossibleLocalizationRecords' => true, + 'showRemovedLocalizationRecords' => true, + 'showAllLocalizationLink' => true, + 'showSynchronizationLink' => true, + ], + 'foreign_match_fields' => [ + 'fieldname' => 'files', + 'tablenames' => 'tx_cartevents_domain_model_event', + ], + // custom configuration for displaying fields in the overlay/reference table + // to use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_TEXT => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_TEXT => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_IMAGE => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_IMAGE => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_AUDIO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_AUDIO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_VIDEO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_VIDEO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_APPLICATION => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_APPLICATION => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], + --palette--;;filePalette', ], ], - 'minitems' => 0, - 'maxitems' => 99, ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] . ', pdf' - ), + 'minitems' => 0, + 'maxitems' => 99, + ], ], 'tax_class_id' => [ @@ -403,9 +376,9 @@ 'type' => 'select', 'renderType' => 'selectSingle', 'items' => [ - [$_LLL_cart . ':tx_cart.tax_class_id.1', 1], - [$_LLL_cart . ':tx_cart.tax_class_id.2', 2], - [$_LLL_cart . ':tx_cart.tax_class_id.3', 3], + ['label' => $_LLL_cart . ':tx_cart.tax_class_id.1', 'value' => 1], + ['label' => $_LLL_cart . ':tx_cart.tax_class_id.2', 'value' => 2], + ['label' => $_LLL_cart . ':tx_cart.tax_class_id.3', 'value' => 3], ], 'size' => 1, 'minitems' => 1, @@ -437,7 +410,7 @@ 'hide' => true, 'delete' => true, 'localize' => true, - ] + ], ], ], ], @@ -447,7 +420,6 @@ 'label' => $_LLL_cart . ':tx_cart_domain_model_tags', 'config' => [ 'type' => 'group', - 'internal_type' => 'db', 'allowed' => 'tx_cart_domain_model_tag', 'foreign_table' => 'tx_cart_domain_model_tag', 'size' => 5, @@ -461,5 +433,18 @@ ], ], ], + + 'category' => [ + 'config' => [ + 'type' => 'category', + 'relationship' => 'oneToOne', + ], + ], + + 'categories' => [ + 'config' => [ + 'type' => 'category', + ], + ], ], ]; diff --git a/Configuration/TCA/tx_cartevents_domain_model_eventdate.php b/Configuration/TCA/tx_cartevents_domain_model_eventdate.php index 055d6ac..c58bccb 100644 --- a/Configuration/TCA/tx_cartevents_domain_model_eventdate.php +++ b/Configuration/TCA/tx_cartevents_domain_model_eventdate.php @@ -1,9 +1,8 @@ 1, 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', 'sortby' => 'sorting', @@ -37,7 +35,7 @@ 'endtime' => 'endtime', ], 'searchFields' => 'sku,title,', - 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_eventdate.svg' + 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_eventdate.svg', ], 'types' => [ '1' => [ @@ -53,12 +51,12 @@ --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access, --palette--;' . $_LLL_tca . ':palettes.visibility;hiddenonly, --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access, - ' + ', ], ], 'palettes' => [ 'begin_and_end' => [ - 'showitem' => 'begin, end, --linebreak--, note' + 'showitem' => 'begin, end, --linebreak--, note', ], 'hiddenonly' => [ 'showitem' => 'hidden;' . $_LLL_db . ':tx_cartevents_domain_model_eventdate', @@ -72,19 +70,7 @@ 'sys_language_uid' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.language', - 'config' => [ - 'type' => 'select', - 'renderType' => 'selectSingle', - 'special' => 'languages', - 'items' => [ - [ - $_LLL_general . ':LGL.allLanguages', - -1, - 'flags-multiple' - ], - ], - 'default' => 0, - ], + 'config' => ['type' => 'language'], ], 'l10n_parent' => [ 'displayCond' => 'FIELD:sys_language_uid:>:0', @@ -93,7 +79,7 @@ 'type' => 'select', 'renderType' => 'selectSingle', 'items' => [ - ['', 0], + ['label' => '', 'value' => 0], ], 'foreign_table' => 'tx_cartevents_domain_model_eventdate', 'foreign_table_where' => 'AND tx_cartevents_domain_model_eventdate.pid=###CURRENT_PID### AND tx_cartevents_domain_model_eventdate.sys_language_uid IN (-1,0)', @@ -116,7 +102,7 @@ 'type' => 'input', 'size' => 30, 'max' => 255, - ] + ], ], 'hidden' => [ 'exclude' => 1, @@ -124,25 +110,18 @@ 'config' => [ 'type' => 'check', 'renderType' => 'checkboxToggle', - 'items' => [ - '1' => [ - '0' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:hidden.I.0' - ] - ] ], ], 'starttime' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.starttime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -150,14 +129,12 @@ 'exclude' => 1, 'label' => 'LLL' . ':EXT:lang/locallang_general.xlf:LGL.endtime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => [ - 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) + 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), ], ], ], @@ -168,7 +145,8 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'required,trim' + 'eval' => 'trim', + 'required' => true, ], ], @@ -178,28 +156,26 @@ 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'required,trim' + 'eval' => 'trim', + 'required' => true, ], ], 'begin' => [ 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.begin', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'required,datetime', 'checkbox' => 0, 'default' => 0, + 'required' => true, ], ], 'end' => [ 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.end', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -216,123 +192,119 @@ 'images' => [ 'exclude' => 1, 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.images', - 'config' => ExtensionManagementUtility::getFileFieldTCAConfig( - 'images', - [ - 'appearance' => [ - 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', - 'showPossibleLocalizationRecords' => true, - 'showRemovedLocalizationRecords' => true, - 'showAllLocalizationLink' => true, - 'showSynchronizationLink' => true, - ], - 'foreign_match_fields' => [ - 'fieldname' => 'image', - 'tablenames' => 'tx_cartevents_domain_model_eventdate', - 'table_local' => 'sys_file', - ], - // custom configuration for displaying fields in the overlay/reference table - // to use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' + 'config' => [ + //## !!! Watch out for fieldName different from columnName + 'type' => 'file', + 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], + 'appearance' => [ + 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', + 'showPossibleLocalizationRecords' => true, + 'showRemovedLocalizationRecords' => true, + 'showAllLocalizationLink' => true, + 'showSynchronizationLink' => true, + ], + 'foreign_match_fields' => [ + 'fieldname' => 'image', + 'tablenames' => 'tx_cartevents_domain_model_eventdate', + ], + // custom configuration for displaying fields in the overlay/reference table + // to use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_TEXT => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_TEXT => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_IMAGE => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_IMAGE => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_AUDIO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_AUDIO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_VIDEO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_VIDEO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_APPLICATION => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_APPLICATION => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], + --palette--;;filePalette', ], ], - 'minitems' => 0, - 'maxitems' => 99, ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'minitems' => 0, + 'maxitems' => 99, + ], ], 'files' => [ 'exclude' => 1, 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.files', - 'config' => ExtensionManagementUtility::getFileFieldTCAConfig( - 'files', - [ - 'appearance' => [ - 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', - 'showPossibleLocalizationRecords' => true, - 'showRemovedLocalizationRecords' => true, - 'showAllLocalizationLink' => true, - 'showSynchronizationLink' => true, - ], - 'foreign_match_fields' => [ - 'fieldname' => 'files', - 'tablenames' => 'tx_cartevents_domain_model_eventdate', - 'table_local' => 'sys_file', - ], - // custom configuration for displaying fields in the overlay/reference table - // to use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' + 'config' => [ + //## !!! Watch out for fieldName different from columnName + 'type' => 'file', + 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] . ', pdf', + 'appearance' => [ + 'createNewRelationLinkTitle' => $_LLL_ttc . ':images.addFileReference', + 'showPossibleLocalizationRecords' => true, + 'showRemovedLocalizationRecords' => true, + 'showAllLocalizationLink' => true, + 'showSynchronizationLink' => true, + ], + 'foreign_match_fields' => [ + 'fieldname' => 'files', + 'tablenames' => 'tx_cartevents_domain_model_eventdate', + ], + // custom configuration for displaying fields in the overlay/reference table + // to use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_TEXT => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_TEXT => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_IMAGE => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_IMAGE => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_AUDIO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_AUDIO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_VIDEO => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_VIDEO => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], - File::FILETYPE_APPLICATION => [ - 'showitem' => ' + --palette--;;filePalette', + ], + File::FILETYPE_APPLICATION => [ + 'showitem' => ' --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, - --palette--;;filePalette' - ], + --palette--;;filePalette', ], ], - 'minitems' => 0, - 'maxitems' => 99, ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] . ', pdf' - ), + 'minitems' => 0, + 'maxitems' => 99, + ], ], 'event' => [ @@ -393,10 +365,8 @@ 'displayCond' => 'FIELD:bookable:REQ:TRUE', 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.bookable_until', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -409,14 +379,6 @@ 'config' => [ 'type' => 'check', 'renderType' => 'checkboxToggle', - 'items' => [ - [ - 0 => '', - 1 => '', - 'labelChecked' => 'Enabled', - 'labelUnchecked' => 'Disabled', - ] - ], ], 'onChange' => 'reload', ], @@ -427,7 +389,7 @@ 'AND' => [ 'FIELD:bookable:REQ:TRUE', 'FIELD:price_categorized:REQ:TRUE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.price_categories', 'config' => [ @@ -453,15 +415,16 @@ 'AND' => [ 'FIELD:bookable:REQ:TRUE', 'FIELD:price_categorized:REQ:FALSE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.price.gross', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'required,double2', 'default' => '0.00', - ] + 'format' => 'decimal', + 'required' => true, + ], ], 'special_prices' => [ @@ -470,7 +433,7 @@ 'AND' => [ 'FIELD:bookable:REQ:TRUE', 'FIELD:price_categorized:REQ:FALSE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.special_prices', 'config' => [ @@ -512,7 +475,7 @@ 'FIELD:bookable:REQ:TRUE', 'FIELD:price_categorized:REQ:TRUE', 'FIELD:handle_seats:REQ:TRUE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.handle_seats_in_price_category', 'config' => [ @@ -531,14 +494,13 @@ 'FIELD:bookable:REQ:TRUE', 'FIELD:handle_seats:REQ:TRUE', 'FIELD:handle_seats_in_price_category:REQ:FALSE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.seats_number', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'int' - ] + ], ], 'seats_taken' => [ @@ -550,14 +512,13 @@ 'FIELD:bookable:REQ:TRUE', 'FIELD:handle_seats:REQ:TRUE', 'FIELD:handle_seats_in_price_category:REQ:FALSE', - ] + ], ], 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.seats_taken', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'int' - ] + ], ], ], ]; diff --git a/Configuration/TCA/tx_cartevents_domain_model_pricecategory.php b/Configuration/TCA/tx_cartevents_domain_model_pricecategory.php index 2671ce4..4264924 100644 --- a/Configuration/TCA/tx_cartevents_domain_model_pricecategory.php +++ b/Configuration/TCA/tx_cartevents_domain_model_pricecategory.php @@ -1,19 +1,18 @@ [ - 'title' => $_LLL . ':tx_cartevents_domain_model_pricecategory', + 'title' => $_LLL_db . ':tx_cartevents_domain_model_pricecategory', 'label' => 'sku', 'label_alt' => 'title, price', 'label_alt_force' => 1, 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', 'versioningWS' => true, @@ -31,22 +30,22 @@ 'fe_group' => 'frontend_user_group', ], 'searchFields' => 'price', - 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_pricecategory.svg' + 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_pricecategory.svg', ], 'types' => [ '1' => [ - 'showitem' => 'sku,title,price,special_prices,seats_number,seats_taken,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access' + 'showitem' => 'sku,title,price,special_prices,seats_number,seats_taken,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access', ], '2' => [ - 'showitem' => 'sku,title,price,seats_number,seats_taken,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access' + 'showitem' => 'sku,title,price,seats_number,seats_taken,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access', ], ], 'palettes' => [ '1' => [ - 'showitem' => '' + 'showitem' => '', ], 'hiddenonly' => [ - 'showitem' => 'hidden;' . $_LLL . ':tx_cartevents_domain_model_pricecategory', + 'showitem' => 'hidden;' . $_LLL_db . ':tx_cartevents_domain_model_pricecategory', ], 'access' => [ 'showitem' => 'starttime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:starttime_formlabel, endtime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:endtime_formlabel', @@ -56,18 +55,7 @@ 'sys_language_uid' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.language', - 'config' => [ - 'type' => 'select', - 'renderType' => 'selectSingle', - 'foreign_table' => 'sys_language', - 'foreign_table_where' => 'ORDER BY sys_language.title', - 'items' => [ - [$_LLL_general . ':LGL.allLanguages', -1], - [$_LLL_general . ':LGL.default_value', 0] - ], - 'eval' => 'int', - 'default' => 0, - ], + 'config' => ['type' => 'language'], ], 'l10n_parent' => [ 'displayCond' => 'FIELD:sys_language_uid:>:0', @@ -76,7 +64,7 @@ 'type' => 'select', 'renderType' => 'selectSingle', 'items' => [ - ['', 0], + ['label' => '', 'value' => 0], ], 'foreign_table' => 'tx_cartevents_domain_model_pricecategory', 'foreign_table_where' => 'AND tx_cartevents_domain_model_pricecategory.pid=###CURRENT_PID### AND tx_cartevents_domain_model_pricecategory.sys_language_uid IN (-1,0)', @@ -100,7 +88,7 @@ 'type' => 'input', 'size' => 30, 'max' => 255, - ] + ], ], 'hidden' => [ @@ -117,10 +105,8 @@ 'l10n_display' => 'defaultAsReadonly', 'label' => $_LLL_general . ':LGL.starttime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -131,10 +117,8 @@ 'l10n_display' => 'defaultAsReadonly', 'label' => $_LLL_general . ':LGL.endtime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -142,31 +126,32 @@ 'sku' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_pricecategory.sku', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_pricecategory.sku', 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim' + 'eval' => 'trim', ], ], 'title' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_pricecategory.title', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_pricecategory.title', 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim' + 'eval' => 'trim', ], ], 'price' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_pricecategory.price.gross', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_pricecategory.price.gross', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'required,double2', 'default' => '0.00', - ] + 'format' => 'decimal', + 'required' => true, + ], ], 'special_prices' => [ @@ -195,10 +180,9 @@ 'l10n_display' => 'defaultAsReadonly', 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.seats_number', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'int' - ] + ], ], 'seats_taken' => [ @@ -207,10 +191,9 @@ 'l10n_display' => 'defaultAsReadonly', 'label' => $_LLL_db . ':tx_cartevents_domain_model_eventdate.seats_taken', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'int' - ] + ], ], 'event_date' => [ diff --git a/Configuration/TCA/tx_cartevents_domain_model_specialprice.php b/Configuration/TCA/tx_cartevents_domain_model_specialprice.php index b25dd5e..64caac8 100644 --- a/Configuration/TCA/tx_cartevents_domain_model_specialprice.php +++ b/Configuration/TCA/tx_cartevents_domain_model_specialprice.php @@ -1,19 +1,18 @@ [ - 'title' => $_LLL . ':tx_cartevents_domain_model_specialprice', + 'title' => $_LLL_db . ':tx_cartevents_domain_model_specialprice', 'label' => 'price', 'label_alt' => 'starttime, endtime', 'label_alt_force' => 1, 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', 'versioningWS' => true, @@ -31,19 +30,19 @@ 'fe_group' => 'frontend_user_group', ], 'searchFields' => 'price', - 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_specialprice.svg' + 'iconfile' => 'EXT:cart_events/Resources/Public/Icons/tx_cartevents_domain_model_specialprice.svg', ], 'types' => [ '1' => [ - 'showitem' => 'frontend_user_group,title,price,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access' + 'showitem' => 'frontend_user_group,title,price,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.tabs.access,--palette--;LLL:EXT:cart_events/Resources/Private/Language/locallang_tca.xlf:palettes.visibility;hiddenonly,--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.palettes.access;access', ], ], 'palettes' => [ '1' => [ - 'showitem' => '' + 'showitem' => '', ], 'hiddenonly' => [ - 'showitem' => 'hidden;' . $_LLL . ':tx_cartevents_domain_model_specialprice', + 'showitem' => 'hidden;' . $_LLL_db . ':tx_cartevents_domain_model_specialprice', ], 'access' => [ 'showitem' => 'starttime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:starttime_formlabel, endtime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:endtime_formlabel', @@ -53,19 +52,7 @@ 'sys_language_uid' => [ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.language', - 'config' => [ - 'type' => 'select', - 'renderType' => 'selectSingle', - 'special' => 'languages', - 'items' => [ - [ - $_LLL_general . ':LGL.allLanguages', - -1, - 'flags-multiple' - ], - ], - 'default' => 0, - ], + 'config' => ['type' => 'language'], ], 'l10n_parent' => [ 'displayCond' => 'FIELD:sys_language_uid:>:0', @@ -74,7 +61,7 @@ 'type' => 'select', 'renderType' => 'selectSingle', 'items' => [ - ['', 0], + ['label' => '', 'value' => 0], ], 'foreign_table' => 'tx_cartevents_domain_model_specialprice', 'foreign_table_where' => 'AND tx_cartevents_domain_model_specialprice.pid=###CURRENT_PID### AND tx_cartevents_domain_model_specialprice.sys_language_uid IN (-1,0)', @@ -98,7 +85,7 @@ 'type' => 'input', 'size' => 30, 'max' => 255, - ] + ], ], 'hidden' => [ @@ -113,10 +100,8 @@ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.starttime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -125,10 +110,8 @@ 'exclude' => 1, 'label' => $_LLL_general . ':LGL.endtime', 'config' => [ - 'type' => 'input', - 'renderType' => 'inputDateTime', + 'type' => 'datetime', 'size' => 13, - 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, ], @@ -136,27 +119,28 @@ 'title' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_specialprice.title', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_specialprice.title', 'config' => [ 'type' => 'input', 'size' => 30, - 'eval' => 'trim' + 'eval' => 'trim', ], ], 'price' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_specialprice.price.gross', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_specialprice.price.gross', 'config' => [ - 'type' => 'input', + 'type' => 'number', 'size' => 30, - 'eval' => 'required,double2', 'default' => '0.00', - ] + 'format' => 'decimal', + 'required' => true, + ], ], 'frontend_user_group' => [ 'exclude' => 1, - 'label' => $_LLL . ':tx_cartevents_domain_model_specialprice.frontend_user_group', + 'label' => $_LLL_db . ':tx_cartevents_domain_model_specialprice.frontend_user_group', 'config' => [ 'type' => 'select', 'renderType' => 'selectSingle', @@ -164,13 +148,13 @@ 'foreign_table' => 'fe_groups', 'size' => 1, 'items' => [ - ['', 0], + ['label' => '', 'value' => 0], ], 'minitems' => 0, 'maxitems' => 1, 'eval' => 'int', 'default' => 0, - ] + ], ], 'event_date' => [ diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg index 073bc1a..94e27c0 100644 --- a/Documentation/Settings.cfg +++ b/Documentation/Settings.cfg @@ -1,8 +1,8 @@ [general] project = Cart Events -version = 4.0 -release = 4.0.0 +version = 5.0 +release = 5.0.0 t3author = Daniel Gohlke copyright = 2021-2024 diff --git a/README.md b/README.md index 97196cc..a90e4cc 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,13 @@ Sometimes minor versions also result in minor adjustments to own templates or co ## 3.1 Compatibility and supported Versions -| Cart Events | TYPO3 | PHP | Support/Development | -| ------------- | ---------- | ----------|-----------------------------------------| -| 4.x.x | 10.4, 11.5 | 7.2 - 8.0 | Features, Bugfixes, Security Updates | -| 3.x.x | 10.4 | 7.2 - 7.4 | Bugfixes, Security Updates | -| 2.x.x | 9.5 | 7.2 - 7.4 | Security Updates | -| 1.x.x | 8.7 | 7.0 - 7.4 | | +| Cart Events | TYPO3 | PHP | Support/Development | +|-------------|------------|-----------|--------------------------------------| +| 5.x.x | 12.4 | 8.1+ | Features, Bugfixes, Security Updates | +| 4.x.x | 10.4, 11.5 | 7.2+ | Bugfixes, Security Updates | +| 3.x.x | 10.4 | 7.2 - 7.4 | Security Updates | +| 2.x.x | 9.5 | 7.2 - 7.4 | | +| 1.x.x | 8.7 | 7.0 - 7.4 | | If you need extended support for features and bug fixes outside of the currently supported versions, we are happy to offer paid services. @@ -59,7 +60,6 @@ News uses **semantic versioning** which basically means for you, that * Ask for an invoice. * [GitHub Sponsors](https://github.com/sponsors/extcode) * [PayPal.Me](https://paypal.me/extcart) -* [Patreon](https://patreon.com/ext_cart) [1]: https://docs.typo3.org/typo3cms/extensions/cart_events/ [2]: https://getcomposer.org/ \ No newline at end of file diff --git a/Resources/Private/Language/Overrides/cart/fr.locallang.xlf b/Resources/Private/Language/Overrides/cart/fr.locallang.xlf deleted file mode 100644 index 7542e52..0000000 --- a/Resources/Private/Language/Overrides/cart/fr.locallang.xlf +++ /dev/null @@ -1,15 +0,0 @@ - - - -
- - - - The event has been added to your shopping cart. - La manifestation a Γ©tΓ© ajoutΓ©e au panier. - - - - - - diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf deleted file mode 100644 index 5c50347..0000000 --- a/Resources/Private/Language/de.locallang.xlf +++ /dev/null @@ -1,43 +0,0 @@ - - - -
- - - - more - mehr - - - Add to cart - in den Warenkorb - - - The event has been added to your shopping cart. - Die Veranstaltung wurde in den Warenkorb gelegt. - - - The event could not be added to the shopping cart! - Die Veranstaltung konnte nicht in den Warenkorb gelegt werden! - - - Event is not bookable. - Die Veranstaltung ist nicht buchbar. - - - Not enough Seats available. - Nicht ausreichend freie PlΓ€tze verfΓΌgbar. - - - - Seats - PlΓ€tze - - - This event date can not be booked. - Dieser Veranstaltungstermin kann nicht gebucht werden. - - - - - diff --git a/Resources/Private/Language/de.locallang_be.xlf b/Resources/Private/Language/de.locallang_be.xlf deleted file mode 100644 index e3334e5..0000000 --- a/Resources/Private/Language/de.locallang_be.xlf +++ /dev/null @@ -1,179 +0,0 @@ - - - -
- - - - - Category restriction: Restrict the available categories in event records. - PageTsConfig: - TCEFORM.tx_cartevents_domain_model_event.category.PAGE_TSCONFIG_ID=120. - TCEFORM.tx_cartevents_domain_model_event.categories.PAGE_TSCONFIG_ID=120. - - - - Categories from current page - - - Categories from site root - - - Page TsConfig - - - No restriction - - - Prices are entered as net prices. - Preiseingabe erfolgt als Nettopreise. - - - - Cart: Events - Cart: Veranstaltungen - - - - Template Layout - - - Table - Tabelle - - - Grid - - - Table - Tabelle - - - Grid - - - Default - Standard - - - - Cart: Events - Cart: Veranstaltungen - - - list and show events - Listen- und Detailansicht fΓΌr Veranstaltungen - - - Display Type - Darstellungsart - - - List (and Show) View - Listenansicht (und Detailansicht) - - - Show View - Detailansicht - - - Teaser View - Teaseransicht - - - Event Detail Page - Veranstaltungsdetailseite - - - Sort by - Sortieren nach - - - Uid - Uid - - - Last edited - Zuletzt geΓ€ndert - - - Backend Sorting - Backend Sortierung - - - Created - Erstellt - - - Title - Titel - - - Sort direction - Sortierreihenfolge - - - Ascending - Aufsteigend - - - Descending - Absteigend - - - Number of records to display - Anzahl der anzuzeigenden DatensΓ€tze - - - Categories - Kategorie - - - with Subcategories - mit Unterkategorien - - - Choose teaser product - Teaserprodukt auswΓ€hlen - - - - Cart: selected Events - Cart: ausgewΓ€hlte Veranstaltungen - - - list or tease selected events - Listen- oder Teaseransicht fΓΌr ausgewΓ€hlte Veranstaltungen - - - - Cart: Single Event - Cart: Einzelveranstaltung - - - - Cart: Event Dates (upcoming) - Cart: Veranstaltungstermine (kommende) - - - Event Detail Page - Veranstaltungsdetailseite - - - Number of records to display - Anzahl der anzuzeigenden DatensΓ€tze - - - - Cart: Events - Cart: Veranstaltungen - - - - Cart: Event - Cart: Veranstaltung - - - - - diff --git a/Resources/Private/Language/de.locallang_db.xlf b/Resources/Private/Language/de.locallang_db.xlf deleted file mode 100644 index 50c9bd4..0000000 --- a/Resources/Private/Language/de.locallang_db.xlf +++ /dev/null @@ -1,247 +0,0 @@ - - - -
- - - - Event - Veranstaltung - - - Event number - Veranstaltungsnummer - - - Title - Titel - - - URL segment - URL Segment - - - Form Definition - Formulardefinition - - - Teaser - Kurzbeschreibung - - - Description - Beschreibung - - - Meta description - Metabeschreibung - - - Audience - Publikum - - - Files - Dateien - - - Event Dates - Veranstaltungstermine - - - Related Events - Verwandte Veranstaltungen - - - Related Events (from) - Verwandte Veranstaltungen (von) - - - Main Category - Hauptkategorie - - - Associated Categories - Assoziierte Kategorien - - - Tags - Tags - - - - Event Date - Veranstaltungstermin - - - SKU - Artikelnummer - - - Title - Titel - - - Begin - Beginn - - - End - Ende - - - Note - Notiz - - - Calendar Entries - KalendereintrΓ€ge - - - Location - Veranstaltungsort - - - Lecturer - Dozent - - - Files - Dateien - - - Dates - Termine - - - bookable? - buchbar? - - - bookable until - buchbar bis - - - use Price Categories? - Preiskategorien benutzen - - - Price categories - Preiskategorien - - - Price (gross) - Preis (brutto) - - - Price (net) - Preis (netto) - - - Special Prices - Spezialpreise - - - Handle number of seats - Anzahl der PlΓ€tze verwalten - - - Handle number of seats in price categories - Anzahl der PlΓ€tze in Preiskategorien verwalten - - - Price Categories - Preiskategorien - - - Number of Seats - Anzahl der PlΓ€tze - - - Number of Seats (taken) - Anzahl der PlΓ€tze (gebucht) - - - - Price Category - Preiskategorie - - - SKU - Artikelnummer - - - Title - Titel - - - Price (gross) - Preis (brutto) - - - Price (net) - Preis (netto) - - - Special Prices - Spezialpreise - - - Number of Seats - Anzahl der PlΓ€tze - - - Number of Seats (taken) - Anzahl der PlΓ€tze (gebucht) - - - - Special Price - Spezialpreis - - - Title - Titel - - - Website Usergroup - Website-Benutzergruppe - - - Price (gross) - Preis (brutto) - - - Price (net) - Preis (netto) - - - - Calendar Entry - Kalendereintrag - - - Begin - Beginn - - - End - Ende - - - Note - Notiz - - - - Cart: Page where Events of this category are listed. - Cart: Seite auf der Veranstaltungen dieser Kategorie aufgelistet werden. - - - Cart: Page where Events of this category are shown. - Cart: Seite auf der Veranstaltungen dieser Kategorie angezeigt werden. - - - - - diff --git a/Resources/Private/Language/de.locallang_tca.xlf b/Resources/Private/Language/de.locallang_tca.xlf deleted file mode 100644 index 151ec84..0000000 --- a/Resources/Private/Language/de.locallang_tca.xlf +++ /dev/null @@ -1,56 +0,0 @@ - - - -
- - - - Categorization - Kategorisierung - - - Description - Beschreibung - - - Images / Files - Bilder / Dateien - - - Event Dates - Veranstaltungstermine - - - Relations - Relationen - - - Informations - Informationen - - - Dates - Termine - - - Order - Buchung - - - Images / Files - Bilder / Dateien - - - - Visibility - Sichtbarkeit - - - - The form is displayed when the event is to be added to the shopping cart. Only forms of the prototype "cart-events" will be displayed. - Das Formular wird angezeigt, wenn die Veranstaltung in den Warenkorb gelegt werden soll. Es werden nur Formulare des Prototyps "cart-events" angezeigt. - - - - - diff --git a/Resources/Private/Language/fr.locallang.xlf b/Resources/Private/Language/fr.locallang.xlf deleted file mode 100644 index 0aa9b9e..0000000 --- a/Resources/Private/Language/fr.locallang.xlf +++ /dev/null @@ -1,43 +0,0 @@ - - - -
- - - - more - plus - - - Add to cart - Ajouter au panier - - - The event has been added to your shopping cart. - La manifestation a Γ©tΓ© ajoutΓ©e au panier. - - - The event could not be added to the shopping cart! - La manifestation n'a pas pu Γͺtre ajoutΓ©e au panier! - - - Event is not bookable. - La manifestation ne peut pas Γͺtre rΓ©servΓ©e. - - - Not enough Seats available. - Pas assez de places libres disponibles. - - - - Seats - Places - - - This event date can not be booked. - Cette date de manifestation ne peut pas Γͺtre rΓ©servΓ©e. - - - - - diff --git a/Resources/Private/Partials/Event/CartForm.html b/Resources/Private/Partials/Event/CartForm.html index b2752e5..02a9f6e 100644 --- a/Resources/Private/Partials/Event/CartForm.html +++ b/Resources/Private/Partials/Event/CartForm.html @@ -75,4 +75,6 @@ + + diff --git a/Resources/Private/Templates/Event/Show.html b/Resources/Private/Templates/Event/Show.html index fbff9c0..dc73225 100644 --- a/Resources/Private/Templates/Event/Show.html +++ b/Resources/Private/Templates/Event/Show.html @@ -67,7 +67,7 @@

{event.title} - {eventDate.title}

- + diff --git a/Tests/Acceptance/Data/.gitkeep b/Tests/Acceptance/Data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Tests/Acceptance/EventListCest.php b/Tests/Acceptance/EventListCest.php new file mode 100644 index 0000000..5c53fcf --- /dev/null +++ b/Tests/Acceptance/EventListCest.php @@ -0,0 +1,50 @@ +amOnUrl('http://127.0.0.1:8080/events/'); + + $I->see('Event 1'); + $I->see('Teaser 1'); + + $I->dontSee('Event 4'); + + $I->click('Event 1'); + $I->see('Event 1', 'h1'); + $I->see('31.07.2024 10:00'); + $I->see('This event date can not be booked.'); + } + + public function testListAndDetailViewForBookableEventWithoutPriceCategories(Tester $I): void + { + $I->amOnUrl('http://127.0.0.1:8080/events/'); + + $I->see('Event 2'); + $I->see('Teaser 2'); + + $I->dontSee('Event 4'); + + $I->click('Event 2'); + $I->see('Event 2', 'h1'); + $I->see('31.07.2024 10:00'); + + $I->dontSee('This event date can not be booked.'); + $I->seeElement("input[name='tx_cart_cart[quantity]']"); + $I->seeElement('input[type="submit"]'); + } +} diff --git a/Tests/Acceptance/Support/Environment.php b/Tests/Acceptance/Support/Environment.php new file mode 100644 index 0000000..3641f93 --- /dev/null +++ b/Tests/Acceptance/Support/Environment.php @@ -0,0 +1,60 @@ + [ + 'typo3/cms-core', + 'typo3/cms-backend', + 'typo3/cms-extbase', + 'typo3/cms-frontend', + 'typo3/cms-fluid', + 'typo3/cms-fluid-styled-content', + 'typo3/cms-install', + ], + 'testExtensionsToLoad' => [ + 'extcode/cart', + 'extcode/cart-events', + __DIR__ . '/../../Fixtures/cart_events_test', + ], + 'phpDatabaseFixtures' => [ + 'typo3conf/ext/cart_events/Tests/Fixtures/BackendUserDatabase.php', + 'typo3conf/ext/cart_events/Tests/Fixtures/PagesDatabase.php', + 'typo3conf/ext/cart_events/Tests/Fixtures/ContentDatabase.php', + 'typo3conf/ext/cart_events/Tests/Fixtures/EventsDatabase.php', + ], + 'pathsToLinkInTestInstance' => [ + 'typo3conf/ext/cart_events/Tests/Fixtures/config/sites' => 'typo3conf/sites', + ], + 'configurationToUseInTestInstance' => [ + 'SYS' => [ + 'trustedHostsPattern' => '.*', + ], + ], + ]; + + public function bootstrapTypo3Environment(SuiteEvent $suiteEvent): void + { + parent::bootstrapTypo3Environment($suiteEvent); + + assert(is_array($this->config['phpDatabaseFixtures'])); + foreach ($this->config['phpDatabaseFixtures'] as $dataSetFile) { + (new PhpDataSet())->import(include $dataSetFile); + } + } +} diff --git a/Tests/Acceptance/Support/Tester.php b/Tests/Acceptance/Support/Tester.php new file mode 100644 index 0000000..d0f5dd6 --- /dev/null +++ b/Tests/Acceptance/Support/Tester.php @@ -0,0 +1,37 @@ + [ + [ + 'uid' => '1', + 'pid' => '0', + 'username' => 'test-admin', + 'password' => '$2y$12$ksKbFwhPyf9EWWM52R2e4ubG09tPTK9W6139nxpsgwyUHW17W1nye', + 'lang' => 'default', + 'admin' => '1', + ], + ], +]; diff --git a/Tests/Fixtures/ContentDatabase.php b/Tests/Fixtures/ContentDatabase.php new file mode 100644 index 0000000..a4950e2 --- /dev/null +++ b/Tests/Fixtures/ContentDatabase.php @@ -0,0 +1,24 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '3', + 'CType' => 'list', + 'list_type' => 'cartevents_events', + 'pages' => '7', + 'pi_flexform' => ' Event->show;Event->list table 0 ', + ], + 1 => [ + 'uid' => '2', + 'pid' => '11', + 'CType' => 'list', + 'list_type' => 'cart_cart', + 'pages' => '', + 'pi_flexform' => '', + ], + ], +]; diff --git a/Tests/Fixtures/EventsDatabase.php b/Tests/Fixtures/EventsDatabase.php new file mode 100644 index 0000000..cc91766 --- /dev/null +++ b/Tests/Fixtures/EventsDatabase.php @@ -0,0 +1,106 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '7', + 'sku' => 'event-1', + 'title' => 'Event 1', + 'teaser' => 'Teaser 1', + 'description' => '', + 'meta_description' => '', + 'audience' => '', + 'path_segment' => 'event-1', + ], + 1 => [ + 'uid' => '2', + 'pid' => '7', + 'sku' => 'event-2', + 'title' => 'Event 2', + 'teaser' => 'Teaser 2', + 'description' => '', + 'meta_description' => '', + 'audience' => '', + 'path_segment' => 'event-2', + ], + 2 => [ + 'uid' => '3', + 'pid' => '7', + 'sku' => 'event-3', + 'title' => 'Event 3', + 'teaser' => 'Teaser 3', + 'description' => '', + 'meta_description' => '', + 'audience' => '', + 'path_segment' => 'event-3', + ], + 3 => [ + 'uid' => '4', + 'pid' => '9', + 'sku' => 'event-4', + 'title' => 'Event 4', + 'teaser' => '', + 'description' => '', + 'meta_description' => '', + 'audience' => '', + 'path_segment' => 'event-4', + ], + ], + 'tx_cartevents_domain_model_eventdate' => [ + 0 => [ + 'uid' => '1', + 'pid' => '7', + 'event' => '1', + 'sku' => 'eventdate-1', + 'title' => 'Eventdate 1', + 'begin' => '1722420000', + 'location' => '', + 'lecturer' => '', + 'note' => '', + 'price' => 9.99, + 'bookable' => false, + ], + 1 => [ + 'uid' => '2', + 'pid' => '7', + 'event' => '2', + 'sku' => 'eventdate-2', + 'title' => 'Eventdate 2', + 'begin' => '1722420000', + 'location' => '', + 'lecturer' => '', + 'note' => '', + 'price' => 19.99, + 'bookable' => true, + ], + 2 => [ + 'uid' => '3', + 'pid' => '7', + 'event' => '3', + 'sku' => 'eventdate-3', + 'title' => 'Eventdate 3', + 'begin' => '1722420000', + 'location' => '', + 'lecturer' => '', + 'note' => '', + 'price' => 29.99, + 'bookable' => true, + ], + 3 => [ + 'uid' => '4', + 'pid' => '9', + 'event' => '4', + 'sku' => 'eventdate-4', + 'title' => 'Eventdate 4', + 'begin' => '1722420000', + 'location' => '', + 'lecturer' => '', + 'note' => '', + 'price' => 9.99, + 'bookable' => true, + ], + ], +]; diff --git a/Tests/Fixtures/PagesDatabase.php b/Tests/Fixtures/PagesDatabase.php new file mode 100644 index 0000000..416f1a8 --- /dev/null +++ b/Tests/Fixtures/PagesDatabase.php @@ -0,0 +1,167 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '0', + 'title' => 'Home', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/', + 'sorting' => '128', + 'deleted' => '0', + 'is_siteroot' => '1', + ], + 1 => [ + 'uid' => '2', + 'pid' => '0', + 'title' => 'Startseite', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/', + 'sorting' => '128', + 'deleted' => '0', + 'is_siteroot' => '1', + 'sys_language_uid' => 2, + 'l10n_parent' => 1, + 'l10n_source' => 1, + ], + 2 => [ + 'uid' => '3', + 'pid' => '1', + 'title' => 'Events', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/events', + 'sorting' => '128', + 'deleted' => '0', + ], + 3 => [ + 'uid' => '4', + 'pid' => '1', + 'title' => 'Veranstaltungen', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/veranstaltungen', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 3, + 'l10n_source' => 3, + ], + 4 => [ + 'uid' => '5', + 'pid' => '1', + 'title' => 'Shop', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/shop', + 'sorting' => '128', + 'deleted' => '0', + ], + 5 => [ + 'uid' => '6', + 'pid' => '1', + 'title' => 'Shop', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/shop', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 5, + 'l10n_source' => 5, + ], + 6 => [ + 'uid' => '7', + 'pid' => '5', + 'title' => 'Events Folder 1', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/events-folder-1', + 'sorting' => '128', + 'deleted' => '0', + ], + 7 => [ + 'uid' => '8', + 'pid' => '5', + 'title' => 'Veranstaltungsordner 1', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/veranstaltungsordner-1', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 7, + 'l10n_source' => 7, + ], + 8 => [ + 'uid' => '9', + 'pid' => '5', + 'title' => 'Events Folder 2', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/events-folder-2', + 'sorting' => '128', + 'deleted' => '0', + ], + 9 => [ + 'uid' => '10', + 'pid' => '5', + 'title' => 'Veranstaltungsordner 2', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/veranstaltungsordner-2', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 9, + 'l10n_source' => 9, + ], + 10 => [ + 'uid' => '11', + 'pid' => '1', + 'title' => 'Cart', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/cart', + 'sorting' => '128', + 'deleted' => '0', + ], + 11 => [ + 'uid' => '12', + 'pid' => '1', + 'title' => 'Warenkorb', + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'slug' => '/warenkorb', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 11, + 'l10n_source' => 11, + ], + 12 => [ + 'uid' => '13', + 'pid' => '5', + 'title' => 'Orders', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/orders', + 'sorting' => '128', + 'deleted' => '0', + ], + 13 => [ + 'uid' => '14', + 'pid' => '5', + 'title' => 'Bestellungen', + 'doktype' => PageRepository::DOKTYPE_SYSFOLDER, + 'slug' => '/bestellungen', + 'sorting' => '128', + 'deleted' => '0', + 'sys_language_uid' => 2, + 'l10n_parent' => 13, + 'l10n_source' => 13, + ], + ], + 'sys_template' => [ + 0 => [ + 'uid' => '1', + 'pid' => '1', + 'title' => 'Test Template', + 'include_static_file' => 'EXT:fluid_styled_content/Configuration/TypoScript/,EXT:cart_events_test/Configuration/TypoScript,EXT:cart/Configuration/TypoScript,EXT:cart_events/Configuration/TypoScript', + ], + ], +]; diff --git a/Tests/Fixtures/cart_events_test/Configuration/TypoScript/setup.typoscript b/Tests/Fixtures/cart_events_test/Configuration/TypoScript/setup.typoscript new file mode 100644 index 0000000..2529a43 --- /dev/null +++ b/Tests/Fixtures/cart_events_test/Configuration/TypoScript/setup.typoscript @@ -0,0 +1,7 @@ +page = PAGE +page.10 < styles.content.get + +plugin.tx_cart.settings { + cart.pid = 11 + order.pid = 13 +} \ No newline at end of file diff --git a/Tests/Fixtures/cart_events_test/composer.json b/Tests/Fixtures/cart_events_test/composer.json new file mode 100644 index 0000000..2b59475 --- /dev/null +++ b/Tests/Fixtures/cart_events_test/composer.json @@ -0,0 +1,15 @@ +{ + "name": "extcode/cart-events-test", + "description": "Add a cart_events test extension", + "type": "typo3-cms-extension", + "license": "GPL-2.0-or-later", + "require": { + "typo3/cms-core": "*", + "extcode/cart-events": "@dev" + }, + "extra": { + "typo3/cms": { + "extension-key": "cart_events_test" + } + } +} \ No newline at end of file diff --git a/Tests/Fixtures/config/sites/default/config.yaml b/Tests/Fixtures/config/sites/default/config.yaml new file mode 100644 index 0000000..e10e224 --- /dev/null +++ b/Tests/Fixtures/config/sites/default/config.yaml @@ -0,0 +1,34 @@ +base: '/' +languages: + - + title: 'English' + enabled: true + base: '/' + typo3Language: 'default' + locale: 'en_US.UTF-8' + iso-639-1: 'en' + websiteTitle: '' + navigationTitle: 'English' + hreflang: 'en-GB' + direction: '' + flag: 'gb' + languageId: 0 + fallbackType: 'strict' + fallbacks: '0' + - + title: 'Deutsch' + enabled: true + base: '/de/' + typo3Language: 'de' + locale: 'de_DE.UTF-8' + iso-639-1: 'de' + navigationTitle: 'Deutsch' + hreflang: 'de-DE' + direction: 'ltr' + fallbackType: 'strict' + fallbacks: '' + flag: 'de' + languageId: 2 + websiteTitle: '' +rootPageId: 1 +websiteTitle: 'Cart Events Test - default' \ No newline at end of file diff --git a/Tests/Unit/Domain/Model/EventTest.php b/Tests/Unit/Domain/Model/EventTest.php index 4de80b6..5384c1f 100644 --- a/Tests/Unit/Domain/Model/EventTest.php +++ b/Tests/Unit/Domain/Model/EventTest.php @@ -1,5 +1,7 @@ assertSame( + self::assertSame( '', $this->event->getTeaser() ); @@ -45,11 +47,11 @@ public function getTeaserReturnsInitialValueForTeaser() /** * @test */ - public function setTeaserForStringSetsTeaser() + public function setTeaserForStringSetsTeaser(): void { $this->event->setTeaser('Conceived at T3CON10'); - $this->assertSame( + self::assertSame( 'Conceived at T3CON10', $this->event->getTeaser() ); diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000..9808a21 --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,45 @@ +namespace: 'Extcode\CartEvents\Tests\Acceptance\Support' + +paths: + tests: 'Tests/Acceptance' + data: 'Tests/Acceptance/Data' + output: '.build/web/typo3temp/var/tests/acceptance-reports' + support: 'Tests/Acceptance/Support' + +settings: + debug: true + +extensions: + enabled: + - + 'Codeception\Extension\RunProcess': + - 'geckodriver > .build/web/typo3temp/var/tests/acceptance-logs/geckodriver.log 2>&1' + - 'TYPO3_PATH_APP="$INSTANCE_PATH" TYPO3_PATH_ROOT="$INSTANCE_PATH" php -S 127.0.0.1:8080 -t "$INSTANCE_PATH" > .build/web/typo3temp/var/tests/acceptance-logs/php.log 2>&1' + - + 'Codeception\Extension\Recorder' + - + 'Extcode\CartEvents\Tests\Acceptance\Support\Environment': + typo3DatabaseDriver: 'pdo_sqlite' + +suites: + acceptance: + actor: 'Tester' + path: '.' + modules: + enabled: + - + WebDriver: + url: 'http://127.0.0.1:8080/' + browser: 'firefox' + restart: true + path: '' + wait: 5 + # Scrolling within iFrame doesn't work so well, so we use a bigger window size. + window_size: '1920x1080' + capabilities: + moz:firefoxOptions: + args: + - '-headless' + + step_decorators: + - 'Codeception\Step\Retry' diff --git a/composer.json b/composer.json index d05b8fe..0f33a89 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "authors": [ { "name": "Daniel Gohlke", - "email": "ext.cart@extco.de", + "email": "ext@extco.de", "role": "Developer" } ], @@ -33,58 +33,65 @@ } }, "config": { - "vendor-dir": ".build/vendor", - "bin-dir": ".build/bin" + "allow-plugins": { + "typo3/cms-composer-installers": true, + "typo3/class-alias-loader": true, + "sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": true + } }, "extra": { "typo3/cms": { "extension-key": "cart_events", - "app-dir": ".build", - "web-dir": ".build/public" + "web-dir": ".build/web" } }, "require": { - "php": "^7.2 || ^8.0", + "php": "^8.1", "ext-json": "*", "ext-pdo": "*", - "typo3/cms-core": "^10.4 || ^11.5", - "typo3/cms-extbase": "^10.4 || ^11.5", - "typo3/cms-fluid": "^10.4 || ^11.5", - "extcode/cart": "^8.2" + "extcode/cart": "^9.0", + "typo3/cms-core": "^12.4", + "typo3/cms-extbase": "^12.4", + "typo3/cms-fluid": "^12.4" }, "require-dev": { - "typo3/testing-framework": "^6.0", - "typo3/cms-install": "^10.4 || ^11.5", - "friendsofphp/php-cs-fixer": "^2.14", - "helmich/typo3-typoscript-lint": "^2.0", - "overtrue/phplint": "^1.1", - "rector/rector": "^0.11", - "phpstan/phpstan": "^0.12.99" + "codappix/typo3-php-datasets": "^1.5", + "codeception/codeception": "^5.0", + "codeception/module-db": "^3.1", + "codeception/module-webdriver": "^4.0", + "friendsofphp/php-cs-fixer": "^3.16", + "helmich/typo3-typoscript-lint": "^3.1", + "overtrue/phplint": "^5.5", + "phpstan/phpstan": "^1.10", + "ssch/typo3-rector": "^2.6", + "typo3/cms-fluid-styled-content": "^12.4", + "typo3/cms-install": "^12.4", + "typo3/testing-framework": "^8.0" }, "scripts": { "test:cgl": [ - ".build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --using-cache=no --path-mode=intersection ./" + "vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --using-cache=no --path-mode=intersection ./" ], "test:cgl:dry-run": [ - ".build/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./" + "vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --using-cache=no --path-mode=intersection ./" ], "test:php:lint": [ - ".build/bin/phplint -c Build/phplint.yaml" + "vendor/bin/phplint -c Build/phplint.yaml" ], "test:php:unit": [ - ".build/bin/phpunit -c Build/UnitTests.xml" + "vendor/bin/phpunit -c Build/UnitTests.xml" ], "test:phpstan:analyse": [ - ".build/bin/phpstan analyse -c Build/phpstan.neon" + "vendor/bin/phpstan analyse -c Build/phpstan.neon" ], "test:rector:process": [ - ".build/bin/rector process *" + "vendor/bin/rector process *" ], "test:rector:process:dry-run": [ - ".build/bin/rector process * --dry-run" + "vendor/bin/rector process * --dry-run" ], "test:typoscript:lint": [ - ".build/bin/typoscript-lint -c Build/typoscriptlint.yaml Configuration" + "vendor/bin/typoscript-lint -c Build/typoscriptlint.yaml Configuration" ], "test:php": [ "@test:php:lint", @@ -96,10 +103,6 @@ "@test:cgl", "@test:typoscript:lint", "@test:php" - ], - "post-autoload-dump": [ - "mkdir -p .build/public/typo3conf/ext/", - "[ -L .build/public/typo3conf/ext/cart_events ] || ln -snvf ../../../../. .build/public/typo3conf/ext/cart_events" ] } } diff --git a/ext_emconf.php b/ext_emconf.php index 085fcdb..a7a4906 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -4,28 +4,16 @@ 'title' => 'Cart - Events', 'description' => 'Shopping Cart(s) for TYPO3 - Event Extension', 'category' => 'plugin', - 'shy' => false, - 'version' => '4.1.2', - 'dependencies' => '', - 'conflicts' => '', - 'priority' => '', - 'loadOrder' => '', - 'module' => '', + 'version' => '5.0.0', 'state' => 'stable', - 'uploadfolder' => false, - 'createDirs' => '', - 'modify_tables' => '', 'clearcacheonload' => true, - 'lockType' => '', 'author' => 'Daniel Gohlke', 'author_email' => 'ext.cart@extco.de', 'author_company' => 'extco.de UG (haftungsbeschrΓ€nkt)', - 'CGLcompliance' => null, - 'CGLcompliance_note' => null, 'constraints' => [ 'depends' => [ - 'typo3' => '10.4.0-11.5.99', - 'cart' => '8.2.0' + 'typo3' => '12.4.0-12.4.99', + 'cart' => '9.0.0', ], 'conflicts' => [], 'suggests' => [], diff --git a/ext_localconf.php b/ext_localconf.php index ef673b3..241d818 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,112 +1,84 @@ 'show, list, form', + EventController::class => 'show, list, form', ], [ - \Extcode\CartEvents\Controller\EventController::class => 'form', + EventController::class => 'form', ] ); -\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( +ExtensionUtility::configurePlugin( 'cart_events', 'TeaserEvents', [ - \Extcode\CartEvents\Controller\EventController::class => 'teaser', + EventController::class => 'teaser', ], [ - \Extcode\CartEvents\Controller\EventController::class => '', + EventController::class => '', ] ); -\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( +ExtensionUtility::configurePlugin( 'cart_events', 'SingleEvent', [ - \Extcode\CartEvents\Controller\EventController::class => 'show, form', + EventController::class => 'show, form', ], [ - \Extcode\CartEvents\Controller\EventController::class => 'form', + EventController::class => 'form', ] ); -\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( +ExtensionUtility::configurePlugin( 'cart_events', 'EventDates', [ - \Extcode\CartEvents\Controller\EventDateController::class => 'list', + EventDateController::class => 'list', ], [ - \Extcode\CartEvents\Controller\EventDateController::class => '', + EventDateController::class => '', ] ); -// Icon Registry - -if (TYPO3_MODE === 'BE') { - $icons = [ - 'apps-pagetree-folder-cartevents-events' => 'apps_pagetree_folder_cartevents_events.svg', - 'apps-pagetree-page-cartevents-events' => 'apps_pagetree_page_cartevents_events.svg', - 'ext-cartevents-wizard-icon' => 'cartevents_plugin_wizard.svg', - ]; - - $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( - \TYPO3\CMS\Core\Imaging\IconRegistry::class - ); - - foreach ($icons as $identifier => $fileName) { - $iconRegistry->registerIcon( - $identifier, - \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class, - [ - 'source' => 'EXT:cart_events/Resources/Public/Icons/' . $fileName, - ] - ); - } -} - // TSconfig -\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(' +ExtensionManagementUtility::addPageTSConfig(' '); // Cart Hooks -if (TYPO3_MODE === 'FE') { - $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart']['CartEvents']['Form']['AddToCartFinisher'] = - \Extcode\CartEvents\Domain\Finisher\Form\AddToCartFinisher::class; -} - -// ke_search Hook - register indexer for events - -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['registerIndexerConfiguration'][] = - \Extcode\CartEvents\Hooks\KeSearchEventsIndexer::class; -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['customIndexer'][] = - \Extcode\CartEvents\Hooks\KeSearchEventsIndexer::class; -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['registerIndexerConfiguration'][] = - \Extcode\CartEvents\Hooks\KeSearchSingleEventIndexer::class; -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['customIndexer'][] = - \Extcode\CartEvents\Hooks\KeSearchSingleEventIndexer::class; +$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cart']['CartEvents']['Form']['AddToCartFinisher'] = + AddToCartFinisher::class; // processDatamapClass Hook $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['cartevents_allowed'] = - \Extcode\CartEvents\Hooks\DatamapDataHandlerHook::class; + DatamapDataHandlerHook::class; // clearCachePostProc Hook $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']['cartevents_clearcache'] = - \Extcode\CartEvents\Hooks\DataHandler::class . '->clearCachePostProc'; + DataHandler::class . '->clearCachePostProc'; // register "cartevents:" namespace $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['cartevents'][] @@ -114,7 +86,7 @@ // update wizard for slugs $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['cartEventsSlugUpdater'] = - \Extcode\CartEvents\Updates\SlugUpdater::class; + SlugUpdater::class; // translation overrides diff --git a/rector.php b/rector.php index d5e3953..d36c7b1 100644 --- a/rector.php +++ b/rector.php @@ -2,113 +2,51 @@ declare(strict_types=1); -use Rector\Core\Configuration\Option; -use Rector\Core\ValueObject\PhpVersion; -use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; +use Rector\Config\RectorConfig; use Rector\PostRector\Rector\NameImportingPostRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; +use Rector\ValueObject\PhpVersion; +use Ssch\TYPO3Rector\CodeQuality\General\ConvertImplicitVariablesToExplicitGlobalsRector; +use Ssch\TYPO3Rector\CodeQuality\General\ExtEmConfRector; use Ssch\TYPO3Rector\Configuration\Typo3Option; -use Ssch\TYPO3Rector\FileProcessor\Composer\Rector\ExtensionComposerRector; -use Ssch\TYPO3Rector\FileProcessor\TypoScript\Visitors\FileIncludeToImportStatementVisitor; -use Ssch\TYPO3Rector\Rector\General\ConvertTypo3ConfVarsRector; -use Ssch\TYPO3Rector\Rector\General\ExtEmConfRector; -use Ssch\TYPO3Rector\Rector\v9\v0\InjectAnnotationRector; +use Ssch\TYPO3Rector\Set\Typo3LevelSetList; use Ssch\TYPO3Rector\Set\Typo3SetList; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -return static function (ContainerConfigurator $containerConfigurator): void { - $parameters = $containerConfigurator->parameters(); - - $containerConfigurator->import(Typo3SetList::TYPO3_76); - $containerConfigurator->import(Typo3SetList::TYPO3_87); - $containerConfigurator->import(Typo3SetList::TYPO3_95); - $containerConfigurator->import(Typo3SetList::TYPO3_104); - - // In order to have a better analysis from phpstan we teach it here some more things - $parameters->set(Option::PHPSTAN_FOR_RECTOR_PATH, Typo3Option::PHPSTAN_FOR_RECTOR_PATH); - - // FQN classes are not imported by default. If you don't do it manually after every Rector run, enable it by: - $parameters->set(Option::AUTO_IMPORT_NAMES, true); - - // this will not import root namespace classes, like \DateTime or \Exception - $parameters->set(Option::IMPORT_SHORT_CLASSES, false); - - // this will not import classes used in PHP DocBlocks, like in /** @var \Some\Class */ - $parameters->set(Option::IMPORT_DOC_BLOCKS, false); - - // Define your target version which you want to support - $parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_72); - - // If you have an editorconfig and changed files should keep their format enable it here - // $parameters->set(Option::ENABLE_EDITORCONFIG, true); - - // If you only want to process one/some TYPO3 extension(s), you can specify its path(s) here. - // If you use the option --config change __DIR__ to getcwd() - // $parameters->set(Option::PATHS, [ - // __DIR__ . '/packages/acme_demo/', - // ]); - - // If you set option Option::AUTO_IMPORT_NAMES to true, you should consider excluding some TYPO3 files. - // If you use the option --config change __DIR__ to getcwd() - $parameters->set(Option::SKIP, [ +return RectorConfig::configure() + ->withImportNames(true, true, false, true) + ->withPaths([ + __DIR__ . '/Classes', + __DIR__ . '/Configuration', + __DIR__ . '/Tests', + __DIR__ . '/ext_emconf.php', + __DIR__ . '/ext_localconf.php', + ]) + // uncomment to reach your current PHP version + ->withPhpSets(php81: true) + ->withPhpVersion(PhpVersion::PHP_81) + ->withSets([ + Typo3SetList::CODE_QUALITY, + Typo3SetList::GENERAL, + Typo3LevelSetList::UP_TO_TYPO3_12, + ]) + // To have a better analysis from PHPStan, we teach it here some more things + ->withPHPStanConfigs([ + Typo3Option::PHPSTAN_FOR_RECTOR_PATH, + ]) + ->withRules([ + AddVoidReturnTypeWhereNoReturnRector::class, + ConvertImplicitVariablesToExplicitGlobalsRector::class, + ]) + ->withConfiguredRule(ExtEmConfRector::class, [ + ExtEmConfRector::PHP_VERSION_CONSTRAINT => '8.1.0-8.3.99', + ExtEmConfRector::TYPO3_VERSION_CONSTRAINT => '12.4.0-12.4.99', + ExtEmConfRector::ADDITIONAL_VALUES_TO_BE_REMOVED => [], + ]) + // If you use withImportNames(), you should consider excluding some TYPO3 files. + ->withSkip([ + // @see https://github.com/sabbelasichon/typo3-rector/issues/2536 + __DIR__ . '/**/Configuration/ExtensionBuilder/*', NameImportingPostRector::class => [ 'ClassAliasMap.php', - 'ext_emconf.php', - 'ext_localconf.php', - 'ext_tables.php', - __DIR__ . '/**/Configuration/AjaxRoutes.php', - __DIR__ . '/**/Configuration/Backend/AjaxRoutes.php', - __DIR__ . '/**/Configuration/Commands.php', - __DIR__ . '/**/Configuration/ExpressionLanguage.php', - __DIR__ . '/**/Configuration/Extbase/Persistence/Classes.php', - __DIR__ . '/**/Configuration/RequestMiddlewares.php', - __DIR__ . '/**/Configuration/TCA/*', ], - - // We skip those directories on purpose as there might be node_modules or similar - // that include typescript which would result in false positive processing - __DIR__ . '/**/Resources/**/node_modules/*', - __DIR__ . '/**/Resources/**/NodeModules/*', - __DIR__ . '/**/Resources/**/BowerComponents/*', - __DIR__ . '/**/Resources/**/bower_components/*', - __DIR__ . '/**/Resources/**/build/*', ]); - - // If you have trouble that rector cannot run because some TYPO3 constants are not defined add an additional constants file - // @see https://github.com/sabbelasichon/typo3-rector/blob/master/typo3.constants.php - // @see https://github.com/rectorphp/rector/blob/main/docs/static_reflection_and_autoload.md#include-files - // $parameters->set(Option::BOOTSTRAP_FILES, [ - // __DIR__ . '/typo3.constants.php' - // ]); - - // get services (needed for register a single rule) - $services = $containerConfigurator->services(); - - // register a single rule - // $services->set(InjectAnnotationRector::class); - - /** - * Useful rule from RectorPHP itself to transform i.e. GeneralUtility::makeInstance('TYPO3\CMS\Core\Log\LogManager') - * to GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class) calls. - * But be warned, sometimes it produces false positives (edge cases), so watch out - */ - // $services->set(StringClassNameToClassConstantRector::class); - - // Optional non-php file functionalities: - // @see https://github.com/sabbelasichon/typo3-rector/blob/main/docs/beyond_php_file_processors.md - - // Adapt your composer.json dependencies to the latest available version for the defined SetList - // $containerConfigurator->import(Typo3SetList::COMPOSER_PACKAGES_104_CORE); - // $containerConfigurator->import(Typo3SetList::COMPOSER_PACKAGES_104_EXTENSIONS); - - // Rewrite your extbase persistence class mapping from typoscript into php according to official docs. - // This processor will create a summarized file with all of the typoscript rewrites combined into a single file. - // The filename can be passed as argument, "Configuration_Extbase_Persistence_Classes.php" is default. - // $services->set(ExtbasePersistenceVisitor::class); - // Add some general TYPO3 rules - $services->set(ConvertTypo3ConfVarsRector::class); - $services->set(ExtEmConfRector::class); - $services->set(ExtensionComposerRector::class); - - // Do you want to modernize your TypoScript include statements for files and move from to @import use the FileIncludeToImportStatementVisitor - // $services->set(FileIncludeToImportStatementVisitor::class); -}; diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3b54c6c --- /dev/null +++ b/shell.nix @@ -0,0 +1,123 @@ +{ + pkgs ? import { } + ,phpVersion ? "php81" +}: + +let + php = pkgs.${phpVersion}.buildEnv { + extensions = { enabled, all }: enabled ++ (with all; [ + xdebug + ]); + + extraConfig = '' + xdebug.mode = debug + memory_limit = 4G + ''; + }; + inherit(pkgs."${phpVersion}Packages") composer; + + projectInstall = pkgs.writeShellApplication { + name = "project-install"; + runtimeInputs = [ + php + composer + ]; + text = '' + rm -rf .Build/ vendor/ composer.lock + composer update --prefer-dist --no-progress --working-dir="$PROJECT_ROOT" + ''; + }; + + projectPhpstan = pkgs.writeShellApplication { + name = "project-phpstan"; + + runtimeInputs = [ + php + ]; + + text = '' + ./vendor/bin/phpstan analyse -c Build/phpstan.neon --memory-limit 256M + ''; + }; + + projectCgl = pkgs.writeShellApplication { + name = "project-cgl"; + + runtimeInputs = [ + php + ]; + + text = '' + ./vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php -v --dry-run --diff + ''; + }; + + projectCglFix = pkgs.writeShellApplication { + name = "project-cgl-fix"; + + runtimeInputs = [ + php + ]; + + text = '' + ./vendor/bin/php-cs-fixer fix --config=Build/.php-cs-fixer.dist.php + ''; + }; + + projectTestUnit = pkgs.writeShellApplication { + name = "project-test-unit"; + runtimeInputs = [ + php + projectInstall + ]; + text = '' + project-install + ./vendor/bin/phpunit -c Build/UnitTests.xml + ''; + }; + + projectTestAcceptance = pkgs.writeShellApplication { + name = "project-test-acceptance"; + runtimeInputs = [ + projectInstall + pkgs.sqlite + pkgs.firefox + pkgs.geckodriver + pkgs.procps + php + ]; + text = '' + project-install + + mkdir -p "$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance" + mkdir -p "$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance-logs" + mkdir -p "$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance-reports" + mkdir -p "$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance-sqlite-dbs" + + export INSTANCE_PATH="$PROJECT_ROOT/.build/web/typo3temp/var/tests/acceptance" + + ./vendor/bin/codecept run + + pgrep -f "php -S" | xargs -r kill + ''; + }; + +in pkgs.mkShellNoCC { + name = "TYPO3 Extension extcode/cart-products"; + buildInputs = [ + php + composer + projectInstall + projectPhpstan + projectCgl + projectCglFix + projectTestUnit + projectTestAcceptance + ]; + + shellHook = '' + export PROJECT_ROOT="$(pwd)" + + export typo3DatabaseDriver=pdo_sqlite + ''; +}