From 4ac8c3e07c94a40d903f83c422996551d24972e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9otime?= Date: Thu, 23 Nov 2023 10:14:07 +0100 Subject: [PATCH] global refactoring for v2 --- .github/PULL_REQUEST_TEMPLATE.md | 11 - .github/issue_template.md | 9 - .github/workflows/auto-close-issue.yaml | 21 -- .github/workflows/auto-close-pr.yaml | 23 -- .github/workflows/ci.yml | 79 ++++++ .gitignore | 5 +- .php-cs-fixer.dist.php | 55 ++++ CHANGELOG.md | 23 ++ LICENSE | 12 +- Makefile | 4 + README.md | 16 +- bundle/Command/CleanupCommand.php | 33 +-- bundle/Command/InstallCommand.php | 81 ++++-- bundle/Command/MigrateCjwnlCommand.php | 187 +++++++------ bundle/Command/MigrateEzMailingCommand.php | 189 ++++++------- .../Command/MigrateNovaEzMailingCommand.php | 88 ++++++ bundle/Command/SendMailingCommand.php | 20 +- .../Command/SendMailingSubProcessCommand.php | 58 ++++ bundle/Command/SendTestMailingCommand.php | 40 +-- .../Controller/Admin/CampaignController.php | 107 +++----- bundle/Controller/Admin/ChartController.php | 98 +++---- .../Controller/Admin/DashboardController.php | 73 ++--- bundle/Controller/Admin/ExportController.php | 33 +-- bundle/Controller/Admin/MailingController.php | 109 ++++---- .../Admin/MailingListController.php | 129 ++++----- .../Admin/RegistrationController.php | 20 +- bundle/Controller/Admin/UserController.php | 52 ++-- bundle/Controller/RegistrationController.php | 128 ++++----- bundle/Controller/TrackController.php | 57 ++-- bundle/Core/AjaxGuard.php | 63 ++--- .../Core/ContainerEntityListenerResolver.php | 21 -- bundle/Core/DataHandler/Registration.php | 39 +-- bundle/Core/DataHandler/Unregistration.php | 32 +-- bundle/Core/DataHandler/UserImport.php | 14 +- bundle/Core/IOService.php | 12 +- bundle/Core/Import/User.php | 60 ++--- bundle/Core/Mailer/Mailing.php | 99 ++++--- bundle/Core/Mailer/MailingProcess.php | 132 +++++++++ bundle/Core/Mailer/Simple.php | 36 +-- bundle/Core/Modifier/ModifierInterface.php | 19 +- bundle/Core/Modifier/Packer.php | 16 +- bundle/Core/Modifier/Personalization.php | 18 +- bundle/Core/Modifier/Tracking.php | 34 +-- bundle/Core/Modifier/Unregistration.php | 28 +- bundle/Core/Processor/Processor.php | 12 +- bundle/Core/Processor/SendMailing.php | 56 +--- .../SendMailingProcessorInterface.php | 16 +- bundle/Core/Processor/TestMailing.php | 16 +- .../TestMailingProcessorInterface.php | 14 +- bundle/Core/Provider/Broadcast.php | 40 ++- bundle/Core/Provider/MailingContent.php | 79 ++---- bundle/Core/Provider/MessageContent.php | 123 ++++----- bundle/Core/Provider/User.php | 42 ++- bundle/Core/Registrar.php | 224 +++++++-------- bundle/Core/Tab/Campaigns.php | 27 +- bundle/Core/Tab/Mailings.php | 27 +- bundle/Core/Utils/Browser.php | 123 ++++----- bundle/Core/Utils/ChartDataBuilder.php | 90 +++---- bundle/Core/Utils/Clock.php | 38 +-- bundle/DataFixtures/CampaignFixtures.php | 39 ++- bundle/DataFixtures/MailingListFixtures.php | 14 +- .../UsersRegistrationsFixtures.php | 20 +- bundle/DependencyInjection/Configuration.php | 14 +- ...xtension.php => IbexaMailingExtension.php} | 21 +- bundle/Entity/Broadcast.php | 57 ++-- bundle/Entity/Campaign.php | 90 ++++--- bundle/Entity/Compose/Metadata.php | 26 +- bundle/Entity/Compose/Names.php | 32 +-- bundle/Entity/Compose/Remote.php | 21 +- bundle/Entity/ConfirmationToken.php | 24 +- bundle/Entity/Mailing.php | 112 ++++---- bundle/Entity/MailingList.php | 77 +++--- bundle/Entity/Registration.php | 59 ++-- bundle/Entity/StatHit.php | 25 +- bundle/Entity/User.php | 112 ++++---- bundle/Entity/eZ/Content.php | 13 +- bundle/Entity/eZ/ContentInterface.php | 18 +- bundle/Form/CampaignType.php | 23 +- bundle/Form/ImportType.php | 19 +- bundle/Form/MailingListType.php | 19 +- bundle/Form/MailingType.php | 27 +- bundle/Form/RegistrationType.php | 23 +- bundle/Form/UserType.php | 17 +- bundle/IbexaMailingBundle.php | 34 +++ bundle/Listener/EntityContentLink.php | 40 +-- bundle/Listener/LocationViewGroupTab.php | 22 +- bundle/Listener/MailingWorkflow.php | 14 +- bundle/Listener/PreContentView.php | 54 +--- bundle/Listener/TopMenu.php | 72 +++-- bundle/Menu/Builder.php | 105 ++------ bundle/NovaeZMailingBundle.php | 50 ---- bundle/Repository/Broadcast.php | 33 --- bundle/Repository/BroadcastRepository.php | 37 +++ bundle/Repository/Campaign.php | 23 -- bundle/Repository/CampaignRepository.php | 24 ++ bundle/Repository/ConfirmationToken.php | 23 -- .../ConfirmationTokenRepository.php | 24 ++ bundle/Repository/EntityRepository.php | 40 +-- ...lingList.php => MailingListRepository.php} | 31 ++- .../{Mailing.php => MailingRepository.php} | 38 +-- ...tration.php => RegistrationRepository.php} | 35 +-- .../{StatHit.php => StatHitRepository.php} | 56 ++-- .../{User.php => UserRepository.php} | 62 +++-- bundle/Resources/config/default_settings.yml | 12 +- bundle/Resources/config/ezadminui.yml | 14 +- bundle/Resources/config/logger.yml | 12 +- bundle/Resources/config/routing.yml | 12 +- bundle/Resources/config/services.yml | 86 +++--- bundle/Resources/config/views.yml | 4 +- bundle/Resources/config/workflow.yml | 2 +- bundle/Resources/doc/INSTALL.md | 60 ++--- bundle/Resources/doc/USAGE.md | 17 +- bundle/Resources/encore/ibexa.config.js | 7 +- .../Resources/public/admin/css/ezmailing.scss | 207 -------------- .../public/admin/css/ibexamailing.scss | 126 +++++++++ bundle/Resources/public/admin/css/tree.scss | 134 --------- .../public/admin/images/16x16/aborted.png | Bin 709 -> 0 bytes .../public/admin/images/16x16/aborted.svg | 3 + .../public/admin/images/16x16/archived.png | Bin 560 -> 0 bytes .../public/admin/images/16x16/archived.svg | 3 + .../public/admin/images/16x16/campaign.png | Bin 1547 -> 0 bytes .../public/admin/images/16x16/campaign.svg | 3 + .../public/admin/images/16x16/draft.png | Bin 1280 -> 0 bytes .../public/admin/images/16x16/draft.svg | 3 + .../public/admin/images/16x16/mailinglist.png | Bin 1579 -> 0 bytes .../public/admin/images/16x16/mailinglist.svg | 3 + .../public/admin/images/16x16/pending.png | Bin 720 -> 0 bytes .../public/admin/images/16x16/pending.svg | 3 + .../public/admin/images/16x16/processing.png | Bin 878 -> 0 bytes .../public/admin/images/16x16/processing.svg | 3 + .../public/admin/images/16x16/sent.png | Bin 803 -> 0 bytes .../public/admin/images/16x16/sent.svg | 3 + .../admin/images/16x16/subscriptions.png | Bin 945 -> 0 bytes .../admin/images/16x16/subscriptions.svg | 3 + .../public/admin/images/16x16/tested.png | Bin 434 -> 0 bytes .../public/admin/images/16x16/tested.svg | 3 + .../images/16x16/toggle-small-expand.png | Bin 469 -> 0 bytes .../admin/images/16x16/toggle-small.png | Bin 446 -> 0 bytes .../public/admin/images/16x16/user.png | Bin 673 -> 0 bytes .../public/admin/images/16x16/user.svg | 3 + .../public/admin/images/32x32/aborted.png | Bin 1568 -> 0 bytes .../public/admin/images/32x32/aborted.svg | 3 + .../public/admin/images/32x32/archived.png | Bin 1005 -> 0 bytes .../public/admin/images/32x32/archived.svg | 3 + .../public/admin/images/32x32/campaign.png | Bin 2340 -> 0 bytes .../public/admin/images/32x32/campaign.svg | 3 + .../public/admin/images/32x32/draft.png | Bin 1590 -> 0 bytes .../public/admin/images/32x32/draft.svg | 3 + .../public/admin/images/32x32/mailinglist.png | Bin 2589 -> 0 bytes .../public/admin/images/32x32/mailinglist.svg | 3 + .../public/admin/images/32x32/pending.png | Bin 1364 -> 0 bytes .../public/admin/images/32x32/pending.svg | 3 + .../public/admin/images/32x32/processing.png | Bin 2152 -> 0 bytes .../public/admin/images/32x32/processing.svg | 3 + .../public/admin/images/32x32/sent.png | Bin 1423 -> 0 bytes .../public/admin/images/32x32/sent.svg | 3 + .../admin/images/32x32/subscriptions.png | Bin 1817 -> 0 bytes .../admin/images/32x32/subscriptions.svg | 3 + .../public/admin/images/32x32/tested.png | Bin 1361 -> 0 bytes .../public/admin/images/32x32/tested.svg | 3 + .../public/admin/images/32x32/user.png | Bin 1633 -> 0 bytes .../public/admin/images/32x32/user.svg | 3 + bundle/Resources/public/admin/js/ezmailing.js | 38 --- .../Resources/public/admin/js/ibexamailing.js | 84 ++++++ .../public/admin/js/modules/approbation.js | 4 +- .../public/admin/js/modules/charts.js | 2 +- .../admin/js/modules/contentSelection.js | 4 +- .../Resources/public/admin/js/modules/doc.js | 2 +- .../public/admin/js/modules/editForms.js | 31 ++- .../public/admin/js/modules/search.js | 6 +- .../public/admin/js/modules/subitems.js | 4 +- ...cu.en.yml => ibexamailing+intl-icu.en.yml} | 51 ++-- ...cu.fr.yml => ibexamailing+intl-icu.fr.yml} | 21 +- .../admin/campaign/campaign_tabs.html.twig | 92 +++---- .../views/admin/campaign/details.html.twig | 104 ++++--- .../views/admin/campaign/edit.html.twig | 25 +- .../views/admin/campaign/mailings.html.twig | 17 +- .../admin/campaign/subscriptions.html.twig | 26 +- .../views/admin/chart/generic.html.twig | 2 +- .../common/list/broadcast_graphs.html.twig | 16 +- .../admin/common/list/broadcasts.html.twig | 14 +- .../admin/common/list/mailings.html.twig | 16 +- .../views/admin/common/list/users.html.twig | 32 +-- .../common/list/users_filterer.html.twig | 19 +- .../views/admin/common/menu.html.twig | 70 ++++- .../registration_approbation_button.html.twig | 8 +- .../views/admin/dashboard/index.html.twig | 22 +- .../views/admin/layout/footer.html.twig | 4 - .../views/admin/layout/header.html.twig | 84 +++--- .../views/admin/layout/pagelayout.html.twig | 94 ++++--- .../views/admin/mailing/details.html.twig | 154 ++++++----- .../views/admin/mailing/edit.html.twig | 28 +- .../admin/mailing/mailing_tabs.html.twig | 120 ++++----- .../views/admin/mailing/show.html.twig | 21 +- .../views/admin/mailing_list/edit.html.twig | 18 +- .../views/admin/mailing_list/import.html.twig | 47 ++-- .../views/admin/mailing_list/index.html.twig | 29 +- .../views/admin/mailing_list/show.html.twig | 66 +++-- .../views/admin/tabs/campaigns.html.twig | 8 +- .../views/admin/tabs/mailings.html.twig | 9 +- .../views/admin/user/index.html.twig | 31 ++- .../Resources/views/admin/user/show.html.twig | 254 +++++++++++------- .../novaezmailingfull/generic.html.twig | 28 +- .../views/ezadminui/javascripts.html.twig | 2 +- .../views/ezadminui/stylesheets.html.twig | 2 +- .../messages/confirmregistration.html.twig | 8 +- .../messages/confirmunregistration.html.twig | 8 +- .../views/messages/startsending.html.twig | 4 +- .../views/messages/stopsending.html.twig | 6 +- .../views/registration/register.html.twig | 2 +- .../register_confirmation.html.twig | 2 +- .../registration/register_default.html.twig | 2 +- .../views/registration/unregister.html.twig | 2 +- .../unregister_confirmation.html.twig | 2 +- bundle/Security/Voter/Campaign.php | 45 ++-- bundle/Security/Voter/Mailing.php | 20 +- bundle/Security/Voter/MailingList.php | 43 ++- bundle/Twig/Extension.php | 16 +- bundle/Validator/Constraints/ArrayRange.php | 28 +- .../Constraints/ArrayRangeValidator.php | 15 +- bundle/Validator/Constraints/Location.php | 14 +- .../Constraints/LocationValidator.php | 17 +- bundle/Validator/Constraints/Names.php | 14 +- .../Validator/Constraints/NamesValidator.php | 21 +- ci-config.yaml | 2 - composer.json | 39 ++- docker-compose.yml | 14 + phpmd.xml | 58 ++++ phpstan.neon.dist | 9 + phpunit.xml.dist | 18 ++ tests/Tests/Unit/ClockTest.php | 79 ++---- tests/phpunit.xml | 25 -- tests/provisioning/bundles.yaml | 2 +- tests/provisioning/configs.yaml | 24 +- tests/provisioning/routes.yaml | 4 +- 235 files changed, 3843 insertions(+), 4197 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/issue_template.md delete mode 100644 .github/workflows/auto-close-issue.yaml delete mode 100644 .github/workflows/auto-close-pr.yaml create mode 100644 .github/workflows/ci.yml create mode 100644 .php-cs-fixer.dist.php create mode 100644 CHANGELOG.md create mode 100644 Makefile create mode 100644 bundle/Command/MigrateNovaEzMailingCommand.php create mode 100644 bundle/Command/SendMailingSubProcessCommand.php delete mode 100644 bundle/Core/ContainerEntityListenerResolver.php create mode 100644 bundle/Core/Mailer/MailingProcess.php rename bundle/DependencyInjection/{NovaeZMailingExtension.php => IbexaMailingExtension.php} (84%) create mode 100644 bundle/IbexaMailingBundle.php delete mode 100644 bundle/NovaeZMailingBundle.php delete mode 100644 bundle/Repository/Broadcast.php create mode 100644 bundle/Repository/BroadcastRepository.php delete mode 100644 bundle/Repository/Campaign.php create mode 100644 bundle/Repository/CampaignRepository.php delete mode 100644 bundle/Repository/ConfirmationToken.php create mode 100644 bundle/Repository/ConfirmationTokenRepository.php rename bundle/Repository/{MailingList.php => MailingListRepository.php} (58%) rename bundle/Repository/{Mailing.php => MailingRepository.php} (65%) rename bundle/Repository/{Registration.php => RegistrationRepository.php} (70%) rename bundle/Repository/{StatHit.php => StatHitRepository.php} (77%) rename bundle/Repository/{User.php => UserRepository.php} (71%) delete mode 100644 bundle/Resources/public/admin/css/ezmailing.scss create mode 100644 bundle/Resources/public/admin/css/ibexamailing.scss delete mode 100755 bundle/Resources/public/admin/css/tree.scss delete mode 100644 bundle/Resources/public/admin/images/16x16/aborted.png create mode 100644 bundle/Resources/public/admin/images/16x16/aborted.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/archived.png create mode 100644 bundle/Resources/public/admin/images/16x16/archived.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/campaign.png create mode 100644 bundle/Resources/public/admin/images/16x16/campaign.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/draft.png create mode 100644 bundle/Resources/public/admin/images/16x16/draft.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/mailinglist.png create mode 100644 bundle/Resources/public/admin/images/16x16/mailinglist.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/pending.png create mode 100644 bundle/Resources/public/admin/images/16x16/pending.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/processing.png create mode 100644 bundle/Resources/public/admin/images/16x16/processing.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/sent.png create mode 100644 bundle/Resources/public/admin/images/16x16/sent.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/subscriptions.png create mode 100644 bundle/Resources/public/admin/images/16x16/subscriptions.svg delete mode 100644 bundle/Resources/public/admin/images/16x16/tested.png create mode 100644 bundle/Resources/public/admin/images/16x16/tested.svg delete mode 100755 bundle/Resources/public/admin/images/16x16/toggle-small-expand.png delete mode 100755 bundle/Resources/public/admin/images/16x16/toggle-small.png delete mode 100644 bundle/Resources/public/admin/images/16x16/user.png create mode 100644 bundle/Resources/public/admin/images/16x16/user.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/aborted.png create mode 100644 bundle/Resources/public/admin/images/32x32/aborted.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/archived.png create mode 100644 bundle/Resources/public/admin/images/32x32/archived.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/campaign.png create mode 100644 bundle/Resources/public/admin/images/32x32/campaign.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/draft.png create mode 100644 bundle/Resources/public/admin/images/32x32/draft.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/mailinglist.png create mode 100644 bundle/Resources/public/admin/images/32x32/mailinglist.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/pending.png create mode 100644 bundle/Resources/public/admin/images/32x32/pending.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/processing.png create mode 100644 bundle/Resources/public/admin/images/32x32/processing.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/sent.png create mode 100644 bundle/Resources/public/admin/images/32x32/sent.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/subscriptions.png create mode 100644 bundle/Resources/public/admin/images/32x32/subscriptions.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/tested.png create mode 100644 bundle/Resources/public/admin/images/32x32/tested.svg delete mode 100644 bundle/Resources/public/admin/images/32x32/user.png create mode 100644 bundle/Resources/public/admin/images/32x32/user.svg delete mode 100644 bundle/Resources/public/admin/js/ezmailing.js create mode 100644 bundle/Resources/public/admin/js/ibexamailing.js rename bundle/Resources/translations/{ezmailing+intl-icu.en.yml => ibexamailing+intl-icu.en.yml} (87%) rename bundle/Resources/translations/{ezmailing+intl-icu.fr.yml => ibexamailing+intl-icu.fr.yml} (93%) delete mode 100644 bundle/Resources/views/admin/layout/footer.html.twig delete mode 100644 ci-config.yaml create mode 100644 docker-compose.yml create mode 100644 phpmd.xml create mode 100644 phpstan.neon.dist create mode 100644 phpunit.xml.dist delete mode 100644 tests/phpunit.xml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index d626086..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -Thanks for your pull request! We love contributions. - -However, this repository is what we call a "subtree split": a read-only copy of one directory of the main repository. It is used by Composer to allow developers to depend on specific bundles. - -If you want to contribute, you should instead open a pull request on the main repository: - -https://github.com/Novactive/Nova-eZPlatform-Bundles - -Thank you for your contribution! - -PS: if you haven't already, please add tests. diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index c2421a8..0000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,9 +0,0 @@ -Thanks for reporting an issue! We love feedback. - -However, this repository is what we call a "subtree split": a read-only copy of one directory of the main repository. It is used by Composer to allow developers to depend on specific bundles. - -If you want to report or contribute, you should instead open your issue on the main repository: - -https://github.com/Novactive/Nova-eZPlatform-Bundles - -Thank you for your contribution! diff --git a/.github/workflows/auto-close-issue.yaml b/.github/workflows/auto-close-issue.yaml deleted file mode 100644 index 246c5df..0000000 --- a/.github/workflows/auto-close-issue.yaml +++ /dev/null @@ -1,21 +0,0 @@ -on: - issues: - types: [opened, edited] - -jobs: - autoclose: - runs-on: ubuntu-latest - steps: - - name: Close Issue - uses: peter-evans/close-issue@v1 - with: - comment: | - Thanks for reporting an issue! We love feedback. - - However, this repository is what we call a "subtree split": a read-only copy of one directory of the main repository. It is used by Composer to allow developers to depend on specific bundles. - - If you want to report or contribute, you should instead open your issue on the main repository: - - https://github.com/Novactive/Nova-eZPlatform-Bundles - - Thank you for your contribution! diff --git a/.github/workflows/auto-close-pr.yaml b/.github/workflows/auto-close-pr.yaml deleted file mode 100644 index 00ec921..0000000 --- a/.github/workflows/auto-close-pr.yaml +++ /dev/null @@ -1,23 +0,0 @@ -on: - pull_request: - types: [opened,edited,reopened] - -jobs: - autoclose: - runs-on: ubuntu-latest - steps: - - name: Close Pull Request - uses: peter-evans/close-pull@v1 - with: - comment: | - Thanks for your pull request! We love contributions. - - However, this repository is what we call a "subtree split": a read-only copy of one directory of the main repository. It is used by Composer to allow developers to depend on specific bundles. - - If you want to contribute, you should instead open a pull request on the main repository: - - https://github.com/Novactive/Nova-eZPlatform-Bundles - - Thank you for your contribution! - - PS: if you haven't already, please add tests. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..92db778 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,79 @@ +name: IbexaMailing + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + - name: Install dependencies + run: composer install --prefer-dist --no-progress + - name: Run test suite + run: composer run-script test + php-stan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: php-actions/composer@v6 + with: + php_extensions: gd zip intl xsl + - name: PHPStan Static Analysis + uses: php-actions/phpstan@v3 + with: + configuration: phpstan.neon.dist + memory_limit: 256M + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: PHP-CS-Fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php-cs-fixer.dist.php --diff --dry-run + phpmd: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Composer install + uses: php-actions/composer@v6 + with: + php_extensions: gd zip intl xsl + + - name: PHP Mess Detector + uses: php-actions/phpmd@v1 + with: + path: bundle/ + output: text + ruleset: phpmd.xml + exclude: '*/bundle/Entity/*' + sonar: + name: Sonar analyse + runs-on: ubuntu-latest + permissions: read-all + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: sonarsource/sonarqube-scan-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0d2007d..ed34b82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ /vendor/ composer.lock -.idea \ No newline at end of file +.idea +.phpunit.cache/ +phpunit.xml +/.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..692019d --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,55 @@ +in('bundle') + ->in('tests') + ->files()->name('*.php'); + +$config = new PhpCsFixer\Config(); +$config->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + '@PSR12' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'declare_strict_types' => true, + 'constant_case' => true, + 'combine_consecutive_unsets' => true, + 'native_function_invocation' => [ + 'include' => [ + '@compiler_optimized', + ], + ], + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'continue', + 'extra', + 'return', + 'throw', + 'use', + 'parenthesis_brace_block', + 'square_brace_block', + 'curly_brace_block', + ], + ], + 'no_superfluous_phpdoc_tags' => ['remove_inheritdoc' => false], + 'operator_linebreak' => ['position' => 'beginning'], + 'ordered_class_elements' => true, + 'ordered_imports' => true, + 'yoda_style' => [ + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, + 'always_move_variable' => false, + ], +]) + ->setRiskyAllowed(true) + ->setFinder( + $finder + ); + +return $config; diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ac8c577 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ + +# Change Log + +All notable changes to this project will be documented in this file. + +## [2.0.0] + +- Global refactoring +- Add CI +- Fix tests +- Fix bugs + +## [1.1.0] + +- Change send email to multi-process + +## [1.0.1] + +- Remove `reportEmail` as mandatory + +## [1.0.0] + +- Compatibiliy Ibexa 4.0 \ No newline at end of file diff --git a/LICENSE b/LICENSE index fe88877..483adfc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,14 +1,14 @@ -Copyright (c) 2020 Novactive, https://github.com/Novactive/NovaeZMailingBundle +Copyright (c) 2019 Code Rhapsodie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3758c9c --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +lint: + php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon.dist + ./vendor/bin/php-cs-fixer fix --dry-run --diff --config=.php-cs-fixer.dist.php + ./vendor/bin/phpmd bundle text phpmd.xml --exclude '*/bundle/Entity/*' \ No newline at end of file diff --git a/README.md b/README.md index 5587a5f..50a5473 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,15 @@ -# Novactive eZ Mailing Bundle +# Ibexa Mailing Bundle ---- -This repository is what we call a "subtree split": a read-only copy of one directory of the main repository. -It is used by Composer to allow developers to depend on specific bundles. - -If you want to report or contribute, you should instead open your issue on the main repository: https://github.com/Novactive/Nova-eZPlatform-Bundles +## History -Documentation is available in this repository via `.md` files but also packaged here: https://novactive.github.io/Nova-eZPlatform-Bundles/master/MailingBundle/README.md.html +This repository is a fork of https://github.com/Novactive/NovaeZMailingBundle +This repository is what we call a "subtree split": a read-only copy of one directory of the main repository. +It is used by Composer to allow developers to depend on specific bundles. ---- -[![Downloads](https://img.shields.io/packagist/dt/novactive/ezmailingbundle.svg?style=flat-square)](https://packagist.org/packages/novactive/ezmailingbundle) -[![Latest version](https://img.shields.io/github/release/Novactive/NovaeZMailingBundle.svg?style=flat-square)](https://github.com/Novactive/NovaeZMailingBundle/releases) -[![License](https://img.shields.io/packagist/l/novactive/ezmailingbundle.svg?style=flat-square)](LICENSE) Send eZ Contents by email based on the Mailing + Campaign configuration to a group of users (Mailing Lists) @@ -54,7 +50,7 @@ Wording Features -------- -Novactive eZ Mailing allows you to: **Send eZ Contents by email based on the Mailing + Campaign configuration to a group +Ibexa Mailing allows you to: **Send eZ Contents by email based on the Mailing + Campaign configuration to a group of users (Mailing Lists)** At a glance: diff --git a/bundle/Command/CleanupCommand.php b/bundle/Command/CleanupCommand.php index c42b868..a84cd1d 100644 --- a/bundle/Command/CleanupCommand.php +++ b/bundle/Command/CleanupCommand.php @@ -1,49 +1,28 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; -use Novactive\Bundle\eZMailingBundle\Core\Registrar; +use CodeRhapsodie\IbexaMailingBundle\Core\Registrar; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand(name: 'ibexamailing:cleanup', description: 'Clean expired items')] class CleanupCommand extends Command { - /** - * @var Registrar - */ - private $registrar; - - public function __construct(Registrar $registrar) + public function __construct(private readonly Registrar $registrar) { parent::__construct(); - $this->registrar = $registrar; - } - - protected function configure(): void - { - $this - ->setName('novaezmailing:cleanup') - ->setDescription('Clean expired items'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $io->title('Remove the expired ConfirmationToken'); + $io->title('Remove the expired ConfirmationTokenRepository'); $this->registrar->cleanup(); $io->success('Done.'); diff --git a/bundle/Command/InstallCommand.php b/bundle/Command/InstallCommand.php index 2128f7f..d9082db 100644 --- a/bundle/Command/InstallCommand.php +++ b/bundle/Command/InstallCommand.php @@ -1,49 +1,74 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\ConfirmationToken; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Entity\StatHit; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Tools\SchemaTool; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand(name: 'ibexamailing:install', description: 'Add IbexaMailing tables to database')] class InstallCommand extends Command { + public function __construct(private readonly EntityManagerInterface $entityManager) + { + parent::__construct(); + } + protected function configure(): void { - $this - ->setName('novaezmailing:install') - ->setDescription('Install what necessary in the DB'); + $this->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $io->title('Update the Database with Custom Novactive eZ Mailing Table'); - $command = $this->getApplication()->find('doctrine:schema:update'); - $arguments = [ - 'command' => 'doctrine:schema:update', - '--dump-sql' => true, - '--force' => true, - ]; - $arrayInput = new ArrayInput($arguments); - $command->run($arrayInput, $output); - - $io->success('Done.'); - - return Command::SUCCESS; + $schemaTool = new SchemaTool($this->entityManager); + $dumpSql = $input->getOption('dump-sql') === true; + + $ignore = $schemaTool->getCreateSchemaSql([]); + + $sqls = $schemaTool->getCreateSchemaSql([ + $this->entityManager->getClassMetadata(Broadcast::class), + $this->entityManager->getClassMetadata(Campaign::class), + $this->entityManager->getClassMetadata(ConfirmationToken::class), + $this->entityManager->getClassMetadata(Mailing::class), + $this->entityManager->getClassMetadata(MailingList::class), + $this->entityManager->getClassMetadata(Registration::class), + $this->entityManager->getClassMetadata(StatHit::class), + $this->entityManager->getClassMetadata(User::class), + ]); + + $sqls = array_diff($sqls, $ignore); + + if ($dumpSql) { + foreach ($sqls as $sql) { + $io->writeln($sql); + } + + return parent::SUCCESS; + } + + foreach ($sqls as $sql) { + $this->entityManager->getConnection()->executeQuery($sql); + } + + $io->info('Tables created'); + + return parent::SUCCESS; } } diff --git a/bundle/Command/MigrateCjwnlCommand.php b/bundle/Command/MigrateCjwnlCommand.php index eaf5ed6..d49221a 100644 --- a/bundle/Command/MigrateCjwnlCommand.php +++ b/bundle/Command/MigrateCjwnlCommand.php @@ -1,31 +1,21 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\IOService; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManagerInterface; use Ibexa\Contracts\Core\Repository\Repository; use Ibexa\Core\MVC\Symfony\SiteAccess; use Ibexa\Core\MVC\Symfony\SiteAccess\SiteAccessServiceInterface; -use Novactive\Bundle\eZMailingBundle\Core\IOService; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\Registration; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -35,49 +25,47 @@ /** * @SuppressWarnings(PHPMD) */ +#[AsCommand(name: 'ibexamailing:migrate:cjwnl', description: 'Import database from the old one.')] class MigrateCjwnlCommand extends Command { - /** - * @var SymfonyStyle - */ - private $io; + public const DEFAULT_FALLBACK_CONTENT_ID = 1; + public const DUMP_FOLDER = 'migrate/cjwnl'; + private SymfonyStyle $io; + /** + * @var array + */ private array $lists = []; + /** + * @var array + */ private array $campaigns = []; - public const DEFAULT_FALLBACK_CONTENT_ID = 1; - - public const DUMP_FOLDER = 'migrate/cjwnl'; - - public function __construct( - private readonly IOService $ioService, - private readonly EntityManagerInterface $entityManager, - private readonly Repository $ezRepository, + private readonly IOService $ioService, + private readonly EntityManagerInterface $entityManager, + private readonly Repository $ezRepository, private readonly SiteAccessServiceInterface $siteAccessAware, - private readonly Connection $connection - ) - { + private readonly Connection $connection + ) { parent::__construct(); } protected function configure(): void { $this - ->setName('novaezmailing:migrate:cjwnl') - ->setDescription('Import database from the old one.') ->addOption('export', null, InputOption::VALUE_NONE, 'Export from old DB to json files') ->addOption('import', null, InputOption::VALUE_NONE, 'Import from json files to new DB') ->addOption('clean', null, InputOption::VALUE_NONE, 'Clean the existing data') - ->setHelp('Run novaezmailing:migrate:cjwnl --export|--import|--clean'); + ->setHelp('Run ibexamailing:migrate:cjwnl --export|--import|--clean'); } protected function execute(InputInterface $input, OutputInterface $output): int { $this->io = new SymfonyStyle($input, $output); - $this->io->title('Update the Database with Custom Novactive EzMailing Tables'); + $this->io->title('Update the Database with Custom IbexaMailing Tables'); if ($input->getOption('export')) { $this->export(); @@ -86,7 +74,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } elseif ($input->getOption('clean')) { $this->clean(); } else { - $this->io->error('No export or import option found. Run novaezmailing:migrate:cjwnl --export|--import'); + $this->io->error('No export or import option found. Run ibexamailing:migrate:cjwnl --export|--import'); } return Command::SUCCESS; @@ -94,7 +82,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function export(): void { - // clean the 'ezmailing' dir + // clean the 'ibexamailing' dir $this->ioService->cleanDir(self::DUMP_FOLDER); $this->io->section('Cleaned the folder with json files.'); $this->io->section('Exporting from old database to json files.'); @@ -140,12 +128,12 @@ private function export(): void $listNames = []; foreach ($languages as $language) { $title = $listContent->getName($language->languageCode); - if (null !== $title) { + if ($title !== null) { $listNames[$language->languageCode] = $title; } } $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER . "/list/list_{$list_row['contentobject_id']}.json", + self::DUMP_FOLDER."/list/list_{$list_row['contentobject_id']}.json", json_encode( [ 'names' => $listNames, @@ -171,19 +159,26 @@ private function export(): void default => Mailing::DRAFT, }; + $mailingContent = null; + try { $mailingContent = $contentService->loadContent($mailing_row['edition_contentobject_id']); - } catch (\Exception $e) { + } catch (\Exception) { try { $listContent = $contentService->loadContent(self::DEFAULT_FALLBACK_CONTENT_ID); - } catch (\Exception $e) { + } catch (\Exception) { continue; } } + + if ($mailingContent === null) { + continue; + } + $mailingNames = []; foreach ($languages as $language) { $title = $mailingContent->getName($language->languageCode); - if (null !== $title) { + if ($title !== null) { $mailingNames[$language->languageCode] = $title; } } @@ -198,16 +193,16 @@ private function export(): void 'status' => $status, 'siteAccess' => $siteAccess, 'locationId' => $mailingContent->contentInfo->mainLocationId, - 'hoursOfDay' => (int)date('H', (int)$mailing_row['mailqueue_process_finished']), - 'daysOfMonth' => (int)date('d', (int)$mailing_row['mailqueue_process_finished']), - 'monthsOfYear' => (int)date('m', (int)$mailing_row['mailqueue_process_finished']), + 'hoursOfDay' => (int) date('H', (int) $mailing_row['mailqueue_process_finished']), + 'daysOfMonth' => (int) date('d', (int) $mailing_row['mailqueue_process_finished']), + 'monthsOfYear' => (int) date('m', (int) $mailing_row['mailqueue_process_finished']), 'subject' => $mailingContent->getName($defaultLanguageCode) ?? array_shift($mailingNames), ]; ++$mailingCounter; } $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER . "/campaign/campaign_{$list_row['contentobject_id']}.json", + self::DUMP_FOLDER."/campaign/campaign_{$list_row['contentobject_id']}.json", json_encode( [ 'names' => $listNames, @@ -271,17 +266,17 @@ private function export(): void default => User::PENDING, }; - $birthdate = empty($user_row['birthday']) ? null : new DateTime('2018-12-11'); + $birthdate = empty($user_row['birthday']) ? null : new \DateTime('2018-12-11'); $userId = $user_row['id']; if ($userId === 0) { - $maxId++; + ++$maxId; $userId = $maxId; } // Registrations - $sql = 'SELECT list_contentobject_id, approved, status FROM' . - ' cjwnl_subscription WHERE newsletter_user_id = ? and status not in (3, 4)'; + $sql = 'SELECT list_contentobject_id, approved, status FROM' + .' cjwnl_subscription WHERE newsletter_user_id = ? and status not in (3, 4)'; $subscription_rows = $this->runQuery($sql, [$user_row['id']]); $subscriptions = []; @@ -291,7 +286,7 @@ private function export(): void } $subscriptions[] = [ 'list_contentobject_id' => $subscription_row['list_contentobject_id'], - 'approved' => (bool)$subscription_row['approved'], + 'approved' => (bool) $subscription_row['approved'], ]; ++$registrationCounter; } @@ -302,9 +297,8 @@ private function export(): void default => null }; - $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER . "/user/user_{$userId}.json", + self::DUMP_FOLDER."/user/user_{$userId}.json", json_encode( [ 'email' => $user_row['email'], @@ -324,15 +318,15 @@ private function export(): void } $this->ioService->saveFile( - self::DUMP_FOLDER . '/manifest.json', + self::DUMP_FOLDER.'/manifest.json', json_encode(['lists' => $this->lists, 'campaigns' => $this->campaigns, 'users' => $users]) ); $this->io->progressFinish(); $this->io->section( - 'Total: ' . count($this->lists) . ' lists, ' . count($this->campaigns) . ' campaigns, ' . $mailingCounter . ' mailings, ' . - count($users) . ' users, ' . $registrationCounter . ' registrations.' + 'Total: '.\count($this->lists).' lists, '.\count($this->campaigns).' campaigns, '.$mailingCounter.' mailings, ' + .\count($users).' users, '.$registrationCounter.' registrations.' ); $this->io->success('Export done.'); } @@ -343,12 +337,12 @@ private function import(): void $this->clean(); $this->io->section('Importing from json files to new database.'); - $manifest = $this->ioService->readFile(self::DUMP_FOLDER . '/manifest.json'); + $manifest = $this->ioService->readFile(self::DUMP_FOLDER.'/manifest.json'); $fileNames = json_decode($manifest); // Lists $this->io->writeln('Lists:'); - $this->io->progressStart(count($fileNames->lists)); + $this->io->progressStart(\count($fileNames->lists)); $listCounter = $campaignCounter = $mailingCounter = $userCounter = $registrationCounter = 0; $listIds = []; @@ -358,10 +352,10 @@ private function import(): void $n = 0; foreach ($fileNames->lists as $listFile) { - $listData = json_decode($this->ioService->readFile(self::DUMP_FOLDER . '/list/' . $listFile . '.json')); + $listData = json_decode($this->ioService->readFile(self::DUMP_FOLDER.'/list/'.$listFile.'.json')); $mailingList = new MailingList(); - $mailingList->setNames((array)$listData->names); - $mailingList->setWithApproval((bool)$listData->withApproval); + $mailingList->setNames((array) $listData->names); + $mailingList->setWithApproval((bool) $listData->withApproval); $mailingList->setUpdated(new \DateTime()); $this->entityManager->persist($mailingList); @@ -369,7 +363,7 @@ private function import(): void $this->entityManager->flush(); $listIds[explode('_', $listFile)[1]] = $mailingList->getId(); ++$n; - if (0 === $n % 100) { + if ($n % 100 === 0) { $this->entityManager->clear(); } $this->io->progressAdvance(); @@ -378,15 +372,15 @@ private function import(): void // Campaigns with Mailings $this->io->writeln('Campaigns with Mailings:'); - $this->io->progressStart(count($fileNames->campaigns)); + $this->io->progressStart(\count($fileNames->campaigns)); $n = 0; foreach ($fileNames->campaigns as $campaignFile) { $campaignData = json_decode( - $this->ioService->readFile(self::DUMP_FOLDER . '/campaign/' . $campaignFile . '.json') + $this->ioService->readFile(self::DUMP_FOLDER.'/campaign/'.$campaignFile.'.json') ); $campaign = new Campaign(); - $campaign->setNames((array)$campaignData->names); + $campaign->setNames((array) $campaignData->names); $campaign->setReportEmail($campaignData->reportEmail); $campaign->setSenderEmail($campaignData->senderEmail); $campaign->setReturnPathEmail(''); @@ -399,13 +393,13 @@ private function import(): void $mailingList = $mailingListRepository->findOneBy( ['id' => $listIds[$campaignContentId]] ); - if (null !== $mailingList) { + if ($mailingList !== null) { $campaign->addMailingList($mailingList); } } foreach ($campaignData->mailings as $mailingData) { $mailing = new Mailing(); - $mailing->setNames((array)$mailingData->names); + $mailing->setNames((array) $mailingData->names); $mailing->setStatus($mailingData->status); $mailing->setRecurring(false); $mailing->setHoursOfDay([$mailingData->hoursOfDay]); @@ -422,7 +416,7 @@ private function import(): void $this->entityManager->persist($campaign); ++$campaignCounter; ++$n; - if (0 === $n % 100) { + if ($n % 100 === 0) { $this->entityManager->flush(); $this->entityManager->clear(); } @@ -433,14 +427,14 @@ private function import(): void // Users & Registrations $this->io->writeln('Users and Registrations:'); - $this->io->progressStart(count($fileNames->users)); + $this->io->progressStart(\count($fileNames->users)); $n = 0; foreach ($fileNames->users as $userFile) { - $userData = json_decode($this->ioService->readFile(self::DUMP_FOLDER . '/user/' . $userFile . '.json')); + $userData = json_decode($this->ioService->readFile(self::DUMP_FOLDER.'/user/'.$userFile.'.json')); // check if email already exists - $existingUser = $userRepository->existByEmail($userData->email); + $existingUser = $userRepository->findOneBy(['email' => $userData->email]); if (!$existingUser) { $user = new User(); @@ -464,7 +458,7 @@ private function import(): void $mailingList = $mailingListRepository->findOneBy( ['id' => $listIds[$subscription->list_contentobject_id]] ); - if (null !== $mailingList) { + if ($mailingList !== null) { $registration->setMailingList($mailingList); } $registration->setApproved($subscription->approved); @@ -475,7 +469,7 @@ private function import(): void $this->entityManager->persist($user); ++$userCounter; ++$n; - if (0 === $n % 100) { + if ($n % 100 === 0) { $this->entityManager->flush(); $this->entityManager->clear(); } @@ -487,8 +481,8 @@ private function import(): void $this->io->progressFinish(); $this->io->section( - 'Total: ' . $listCounter . ' lists, ' . $campaignCounter . ' campaigns, ' . $mailingCounter . ' mailings, ' . - $userCounter . ' users, ' . $registrationCounter . ' registrations.' + 'Total: '.$listCounter.' lists, '.$campaignCounter.' campaigns, '.$mailingCounter.' mailings, ' + .$userCounter.' users, '.$registrationCounter.' registrations.' ); $this->io->success('Import done.'); } @@ -496,29 +490,34 @@ private function import(): void private function clean(): void { // We don't run TRUNCATE command here because of foreign keys constraints - $this->connection->executeQuery('DELETE FROM novaezmailing_stats_hit'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_stats_hit AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_broadcast'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_broadcast AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_mailing'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_mailing AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_campaign_mailinglists_destination'); - $this->connection->executeQuery('DELETE FROM novaezmailing_campaign'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_campaign AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_confirmation_token'); - $this->connection->executeQuery('DELETE FROM novaezmailing_registrations'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_registrations AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_mailing_list'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_mailing_list AUTO_INCREMENT = 1'); - $this->connection->executeQuery('DELETE FROM novaezmailing_user'); - $this->connection->executeQuery('ALTER TABLE novaezmailing_user AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_stats_hit'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_stats_hit AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_broadcast'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_broadcast AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_mailing'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_mailing AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_campaign_mailinglists_destination'); + $this->connection->executeQuery('DELETE FROM ibexamailing_campaign'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_campaign AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_confirmation_token'); + $this->connection->executeQuery('DELETE FROM ibexamailing_registrations'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_registrations AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_mailing_list'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_mailing_list AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_user'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_user AUTO_INCREMENT = 1'); $this->io->section('Current tables in the new database have been cleaned.'); } + /** + * @param array $parameters + * + * @return \ArrayIterator + */ private function runQuery(string $sql, array $parameters = []): \Traversable { $stmt = $this->connection->prepare($sql); - for ($i = 1, $iMax = count($parameters); $i <= $iMax; ++$i) { + for ($i = 1, $iMax = \count($parameters); $i <= $iMax; ++$i) { $stmt->bindValue($i, $parameters[$i - 1]); } $result = $stmt->executeQuery(); diff --git a/bundle/Command/MigrateEzMailingCommand.php b/bundle/Command/MigrateEzMailingCommand.php index 8071ada..ce19654 100644 --- a/bundle/Command/MigrateEzMailingCommand.php +++ b/bundle/Command/MigrateEzMailingCommand.php @@ -1,92 +1,59 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; +use CodeRhapsodie\IbexaMailingBundle\Core\IOService; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManagerInterface; use Ibexa\Contracts\Core\Repository\Repository; -use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use Novactive\Bundle\eZMailingBundle\Core\IOService; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\Registration; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +/** + * @SuppressWarnings(PHPMD) + */ +#[AsCommand(name: 'ibexamailing:migrate:ibexamailing', description: 'Import database from the old one.')] class MigrateEzMailingCommand extends Command { - /** - * @var IOService - */ - private $ioService; - - /** - * @var SymfonyStyle - */ - private $io; - - /** - * @var EntityManagerInterface - */ - private $entityManager; - - /** - * @var Repository; - */ - private $ezRepository; - - /** - * @var ConfigResolverInterface - */ - private $configResolver; - public const DEFAULT_FALLBACK_LOCATION_ID = 2; - public const DUMP_FOLDER = 'migrate/ezmailing'; + public const DUMP_FOLDER = 'migrate/ibexamailing'; + private SymfonyStyle $io; + + private readonly Connection $connection; public function __construct( - IOService $ioService, - EntityManagerInterface $entityManager, - Repository $ezRepository, - ConfigResolverInterface $configResolver + private readonly IOService $ioService, + private readonly EntityManagerInterface $entityManager, + private readonly Repository $ezRepository, ) { parent::__construct(); - $this->ioService = $ioService; - $this->entityManager = $entityManager; - $this->ezRepository = $ezRepository; - $this->configResolver = $configResolver; + $this->connection = $this->entityManager->getConnection(); } protected function configure(): void { $this - ->setName('novaezmailing:migrate:ezmailing') - ->setDescription('Import database from the old one.') ->addOption('export', null, InputOption::VALUE_NONE, 'Export from old DB to json files') ->addOption('import', null, InputOption::VALUE_NONE, 'Import from json files to new DB') ->addOption('clean', null, InputOption::VALUE_NONE, 'Clean the existing data') - ->setHelp('Run novaezmailing:migrate:ezmailing --export|--import|--clean'); + ->setHelp('Run ibexamailing:migrate:ibexamailing --export|--import|--clean'); } protected function execute(InputInterface $input, OutputInterface $output): int { $this->io = new SymfonyStyle($input, $output); - $this->io->title('Update the Database with Custom Novactive EzMailing Tables'); + $this->io->title('Update the Database with Custom IbexaMailing Tables'); if ($input->getOption('export')) { $this->export(); @@ -95,7 +62,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } elseif ($input->getOption('clean')) { $this->clean(); } else { - $this->io->error('No export or import option found. Run novaezmailing:migrate:ezmailing --export|--import'); + $this->io->error('No export or import option found. Run ibexamailing:migrate:ibexamailing --export|--import'); } return Command::SUCCESS; @@ -103,7 +70,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function export(): void { - // clean the 'ezmailing' dir + // clean the 'ibexamailing' dir $this->ioService->cleanDir(self::DUMP_FOLDER); $this->io->section('Cleaned the folder with json files.'); $this->io->section('Exporting from old database to json files.'); @@ -119,11 +86,11 @@ private function export(): void $sql = 'SELECT id, name, lang FROM ezmailingmailinglist WHERE draft = 0'; - $list_rows = $this->runQuery($sql); - foreach ($list_rows as $list_row) { + $listRows = $this->runQuery($sql); + foreach ($listRows as $listRow) { $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER."/list/list_{$list_row['id']}.json", - json_encode([$list_row['lang'] => $list_row['name']]) // Approve should be false when importing + self::DUMP_FOLDER."/list/list_{$listRow['id']}.json", + json_encode([$listRow['lang'] => $listRow['name']]) // Approve should be false when importing ); $lists[] = pathinfo($fileName)['filename']; } @@ -134,17 +101,17 @@ private function export(): void $sql .= 'FROM ezmailingcampaign WHERE draft = 0'; - $campaign_rows = $this->runQuery($sql); - foreach ($campaign_rows as $campaign_row) { + $campaignRows = $this->runQuery($sql); + foreach ($campaignRows as $campaignRow) { $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER."/campaign/campaign_{$campaign_row['id']}.json", + self::DUMP_FOLDER."/campaign/campaign_{$campaignRow['id']}.json", json_encode( [ - 'name' => [$defaultLanguageCode => $campaign_row['subject']], - 'senderName' => $campaign_row['sender_name'], - 'senderEmail' => $campaign_row['sender_email'], - 'reportEmail' => $campaign_row['report_email'], - 'mailing_list' => $campaign_row['destination_mailing_list'], + 'name' => [$defaultLanguageCode => $campaignRow['subject']], + 'senderName' => $campaignRow['sender_name'], + 'senderEmail' => $campaignRow['sender_email'], + 'reportEmail' => $campaignRow['report_email'], + 'mailing_list' => $campaignRow['destination_mailing_list'], ] ) ); @@ -156,27 +123,27 @@ private function export(): void $sql .= 'AND (id, email) in (select max(id), email from ezmailinguser group by email)'; - $user_rows = $this->runQuery($sql); - foreach ($user_rows as $user_row) { + $userRows = $this->runQuery($sql); + foreach ($userRows as $userRow) { $sql = 'SELECT mailinglist_id, state FROM ezmailingregistration WHERE mailing_user_id = ?'; - $subscription_rows = $this->runQuery($sql, [$user_row['id']]); + $subscriptionRows = $this->runQuery($sql, [$userRow['id']]); $subscriptions = []; - foreach ($subscription_rows as $subscription_row) { + foreach ($subscriptionRows as $subscriptionRow) { $subscriptions[] = [ - 'mailinglist_id' => $subscription_row['mailinglist_id'], - 'approved' => 20 === $subscription_row['state'], + 'mailinglist_id' => $subscriptionRow['mailinglist_id'], + 'approved' => $subscriptionRow['state'] === 20, ]; ++$registrationCounter; } $fileName = $this->ioService->saveFile( - self::DUMP_FOLDER."/user/user_{$user_row['id']}.json", + self::DUMP_FOLDER."/user/user_{$userRow['id']}.json", json_encode( [ - 'email' => $user_row['email'], - 'firstName' => $user_row['first_name'], - 'lastName' => $user_row['last_name'], - 'origin' => $user_row['origin'], + 'email' => $userRow['email'], + 'firstName' => $userRow['first_name'], + 'lastName' => $userRow['last_name'], + 'origin' => $userRow['origin'], 'subscriptions' => $subscriptions, ] ) @@ -189,8 +156,8 @@ private function export(): void json_encode(['lists' => $lists, 'campaigns' => $campaigns, 'users' => $users]) ); $this->io->section( - 'Total: '.count($lists).' lists, '.count($campaigns).' campaigns, '.$mailingCounter.' mailings, '. - count($users).' users, '.$registrationCounter.' registrations.' + 'Total: '.\count($lists).' lists, '.\count($campaigns).' campaigns, '.$mailingCounter.' mailings, ' + .\count($users).' users, '.$registrationCounter.' registrations.' ); $this->io->success('Export done.'); } @@ -244,7 +211,7 @@ private function import(): void $mailingList = $mailingListRepository->findOneBy( ['id' => $listIds[$mailingListId]] ); - if (null !== $mailingList) { + if ($mailingList !== null) { $campaign->addMailingList($mailingList); } } @@ -259,8 +226,7 @@ private function import(): void $userData = json_decode($this->ioService->readFile(self::DUMP_FOLDER.'/user/'.$userFile.'.json')); // check if email already exists - $existingUser = $userRepository->findOneBy(['email' => $userData->email]); - if (null === $existingUser) { + if ($userRepository->findOneBy(['email' => $userData->email]) === null) { $user = new User(); $user ->setEmail($userData->email) @@ -275,7 +241,7 @@ private function import(): void $mailingList = $mailingListRepository->findOneBy( ['id' => $listIds[$subscription->mailinglist_id]] ); - if (null !== $mailingList) { + if ($mailingList !== null) { $registration = new Registration(); $registration->setMailingList($mailingList); $registration->setApproved($subscription->approved); @@ -291,8 +257,8 @@ private function import(): void $this->entityManager->flush(); $this->io->section( - 'Total: '.$listCounter.' lists, '.$campaignCounter.' campaigns, '.$mailingCounter.' mailings, '. - $userCounter.' users, '.$registrationCounter.' registrations.' + 'Total: '.$listCounter.' lists, '.$campaignCounter.' campaigns, '.$mailingCounter.' mailings, ' + .$userCounter.' users, '.$registrationCounter.' registrations.' ); $this->io->success('Import done.'); } @@ -300,33 +266,38 @@ private function import(): void private function clean(): void { // We don't run TRUNCATE command here because of foreign keys constraints - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_stats_hit'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_stats_hit AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_broadcast'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_broadcast AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_mailing'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_mailing AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_campaign_mailinglists_destination'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_campaign'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_campaign AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_confirmation_token'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_registrations'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_registrations AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_mailing_list'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_mailing_list AUTO_INCREMENT = 1'); - $this->entityManager->getConnection()->query('DELETE FROM novaezmailing_user'); - $this->entityManager->getConnection()->query('ALTER TABLE novaezmailing_user AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_stats_hit'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_stats_hit AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_broadcast'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_broadcast AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_mailing'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_mailing AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_campaign_mailinglists_destination'); + $this->connection->executeQuery('DELETE FROM ibexamailing_campaign'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_campaign AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_confirmation_token'); + $this->connection->executeQuery('DELETE FROM ibexamailing_registrations'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_registrations AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_mailing_list'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_mailing_list AUTO_INCREMENT = 1'); + $this->connection->executeQuery('DELETE FROM ibexamailing_user'); + $this->connection->executeQuery('ALTER TABLE ibexamailing_user AUTO_INCREMENT = 1'); $this->io->section('Current tables in the new database have been cleaned.'); } - private function runQuery(string $sql, array $parameters = [], $fetchMode = null): array + /** + * @param array $parameters + * + * @return array + */ + private function runQuery(string $sql, array $parameters = []): array { - $stmt = $this->entityManager->getConnection()->prepare($sql); - for ($i = 1, $iMax = count($parameters); $i <= $iMax; ++$i) { + $stmt = $this->connection->prepare($sql); + for ($i = 1, $iMax = \count($parameters); $i <= $iMax; ++$i) { $stmt->bindValue($i, $parameters[$i - 1]); } - $stmt->execute(); + $result = $stmt->executeQuery(); - return $stmt->fetchAll($fetchMode); + return $result->fetchAllAssociative(); } } diff --git a/bundle/Command/MigrateNovaEzMailingCommand.php b/bundle/Command/MigrateNovaEzMailingCommand.php new file mode 100644 index 0000000..0722844 --- /dev/null +++ b/bundle/Command/MigrateNovaEzMailingCommand.php @@ -0,0 +1,88 @@ + 'mailing_user', + 'novaezmailing_mailing_list' => 'mailing_mailing_list', + 'novaezmailing_campaign' => 'mailing_campaign', + 'novaezmailing_mailing' => 'mailing_mailing', + 'novaezmailing_campaign_mailinglists_destination' => 'mailing_campaign_mailinglists_destination', + 'novaezmailing_confirmation_token' => 'mailing_confirmation_token', + 'novaezmailing_broadcast' => 'mailing_broadcast', + 'novaezmailing_stats_hit' => 'mailing_stats_hit', + 'novaezmailing_registrations' => 'mailing_registrations', + ]; + + public function __construct(private readonly Connection $connection) + { + parent::__construct(); + } + + protected function configure(): void + { + $this + ->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.') + ->addOption('remove tables', null, InputOption::VALUE_NONE, 'Remove old tables.'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $dumpSql = $input->getOption('dump-sql') === true; + $removeTables = $input->getOption('remove tables') === true; + + foreach (self::TABLES as $oldTable => $newTable) { + try { + $this->connection->executeQuery("SELECT * from $oldTable"); + } catch (\Exception) { + $io->error("Missing table : $oldTable"); + + return parent::FAILURE; + } + + try { + $this->connection->executeQuery("SELECT * from $newTable"); + } catch (\Exception) { + $io->error("Missing table : $newTable (please execute ibexamailing:install)"); + + return parent::FAILURE; + } + + $sql = "INSERT INTO $newTable SELECT * FROM $oldTable"; + if ($dumpSql) { + $io->writeln($sql); + continue; + } + + $this->connection->executeQuery($sql); + } + + if ($removeTables) { + foreach (array_reverse(self::TABLES) as $oldTable => $newTable) { + $sql = "DROP TABLE $oldTable"; + if ($dumpSql) { + $io->writeln($sql); + continue; + } + + $this->connection->executeQuery($sql); + } + } + + return parent::SUCCESS; + } +} diff --git a/bundle/Command/SendMailingCommand.php b/bundle/Command/SendMailingCommand.php index f66fff1..d1015a2 100644 --- a/bundle/Command/SendMailingCommand.php +++ b/bundle/Command/SendMailingCommand.php @@ -1,27 +1,19 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; use Carbon\Carbon; -use Novactive\Bundle\eZMailingBundle\Core\Processor\SendMailingProcessorInterface as SendMailing; +use CodeRhapsodie\IbexaMailingBundle\Core\Processor\SendMailingProcessorInterface as SendMailing; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand('ibexamailing:send:mailing')] class SendMailingCommand extends Command { /** @@ -38,7 +30,7 @@ public function __construct(SendMailing $processor) protected function configure(): void { $this - ->setName('novaezmailing:send:mailing') + ->setName('ibexamailing:send:mailing') ->addOption( 'overrideDatetime', 'o', @@ -55,7 +47,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $overrideDatetime = null; if ($input->getOption('overrideDatetime')) { $overrideDatetime = Carbon::createFromFormat('Y-m-d H:i', $input->getOption('overrideDatetime')); - $io->comment('Using an override date: ' . $overrideDatetime->format('Y-m-d H:i') . ''); + $io->comment('Using an override date: '.$overrideDatetime->format('Y-m-d H:i').''); } $this->processor->execute($overrideDatetime); $io->success('Done.'); diff --git a/bundle/Command/SendMailingSubProcessCommand.php b/bundle/Command/SendMailingSubProcessCommand.php new file mode 100644 index 0000000..9fae6bd --- /dev/null +++ b/bundle/Command/SendMailingSubProcessCommand.php @@ -0,0 +1,58 @@ +addOption(name: 'broadcast-id', mode: InputOption::VALUE_REQUIRED) + ->addOption(name: 'users-id', mode: InputOption::VALUE_REQUIRED); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $usersId = explode(',', $input->getOption('users-id')); + /** @var \CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast $broadcast */ + $broadcast = $this->broadcastRepository->find($input->getOption('broadcast-id')); + $mailing = $broadcast->getMailing(); + + foreach ($usersId as $userId) { + $user = $this->userRepository->find($userId); + $contentMessage = $this->mailingContent->getContentMailing($mailing, $user, $broadcast); + $this->mailing->sendMessage($contentMessage); + + $this->broadcastProvider->increment($broadcast->getId()); + } + + return parent::SUCCESS; + } +} diff --git a/bundle/Command/SendTestMailingCommand.php b/bundle/Command/SendTestMailingCommand.php index e0da81b..fd8461b 100644 --- a/bundle/Command/SendTestMailingCommand.php +++ b/bundle/Command/SendTestMailingCommand.php @@ -1,53 +1,29 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Command; +namespace CodeRhapsodie\IbexaMailingBundle\Command; -use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Processor\TestMailingProcessorInterface as TestMailing; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Core\Processor\TestMailingProcessorInterface as TestMailing; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +#[AsCommand(name: 'ibexamailing:test:send:mailing', description: 'Send a mailing to an specific email', hidden: true)] class SendTestMailingCommand extends Command { - /** - * @var TestMailing - */ - private $processor; - - /** - * @var EntityManagerInterface - */ - private $entityManager; - - public function __construct(TestMailing $processor, EntityManagerInterface $entityManager) + public function __construct(private readonly TestMailing $processor, private readonly MailingRepository $mailingRepository) { parent::__construct(); - $this->processor = $processor; - $this->entityManager = $entityManager; } protected function configure(): void { $this - ->setName('novaezmailing:test:send:mailing') - ->setDescription('Send a mailing to an specific email') - ->setHidden(true) ->addArgument('mailingId', InputArgument::REQUIRED, 'The Mailing Id') ->addArgument('recipient', InputArgument::REQUIRED, "The recipient's email address"); } @@ -58,9 +34,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $mailingId = (int) $input->getArgument('mailingId'); $recipientEmail = $input->getArgument('recipient'); $io->title('Sending a Mailing for test'); - $io->writeln("Mailing ID: {$mailingId}"); + $io->writeln("MailingRepository ID: {$mailingId}"); $io->writeln("To: {$recipientEmail}"); - $mailing = $this->entityManager->getRepository(Mailing::class)->findOneById($mailingId); + $mailing = $this->mailingRepository->find($mailingId); $this->processor->execute($mailing, $recipientEmail); $io->success('Done.'); diff --git a/bundle/Controller/Admin/CampaignController.php b/bundle/Controller/Admin/CampaignController.php index 1f8d855..5fd15f3 100644 --- a/bundle/Controller/Admin/CampaignController.php +++ b/bundle/Controller/Admin/CampaignController.php @@ -1,55 +1,43 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\User as UserProvider; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Form\CampaignType; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; use Doctrine\ORM\EntityManagerInterface; use Ibexa\AdminUi\Tab\LocationView\ContentTab; -use Ibexa\Contracts\Core\Repository\Repository; +use Ibexa\Contracts\Core\Repository\ContentTypeService; use Ibexa\Core\Helper\TranslationHelper; -use Novactive\Bundle\eZMailingBundle\Core\Provider\User as UserProvider; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Form\CampaignType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Routing\RouterInterface; /** * @Route("/campaign") */ -class CampaignController +class CampaignController extends AbstractController { /** - * @Template() * @Security("is_granted('view', campaign)") */ public function campaignTabsAction( Campaign $campaign, - Repository $repository, + ContentTypeService $contentTypeService, ContentTab $contentTab, - EntityManagerInterface $entityManager, - string $status = 'all' - ): array { + MailingRepository $mailingRepository, + string $status = 'all', + ): Response { $content = $campaign->getContent(); - if (null !== $content) { - $contentType = $repository->getContentTypeService()->loadContentType( + if ($content !== null) { + $contentType = $contentTypeService->loadContentType( $content->contentInfo->contentTypeId ); $preview = $contentTab->renderView( @@ -60,26 +48,25 @@ public function campaignTabsAction( ] ); } - $repo = $entityManager->getRepository(Mailing::class); - $mailings = $repo->findByFilters( + $mailings = $mailingRepository->findByFilters( [ 'campaign' => $campaign, - 'status' => 'all' === $status ? null : $status, + 'status' => $status === 'all' ? null : $status, ] ); - return [ + return $this->render('@IbexaMailing/admin/campaign/campaign_tabs.html.twig', [ 'item' => $campaign, 'status' => $status, 'children' => $mailings, 'preview' => $preview ?? null, - ]; + ]); } /** - * @Route("/show/subscriptions/{campaign}/{status}/{page}/{limit}", name="novaezmailing_campaign_subscriptions", + * @Route("/show/subscriptions/{campaign}/{status}/{page}/{limit}", name="ibexamailing_campaign_subscriptions", * defaults={"page":1, "limit":10, "status":"all"}) - * @Template() + * * @Security("is_granted('view', campaign)") */ public function subscriptionsAction( @@ -88,95 +75,89 @@ public function subscriptionsAction( string $status = 'all', int $page = 1, int $limit = 10 - ): array { + ): Response { $filers = [ 'campaign' => $campaign, - 'status' => 'all' === $status ? null : $status, + 'status' => $status === 'all' ? null : $status, ]; - return [ + return $this->render('@IbexaMailing/admin/campaign/subscriptions.html.twig', [ 'pager' => $provider->getPagerFilters($filers, $page, $limit), 'statuses' => $provider->getStatusesData($filers), 'currentStatus' => $status, 'item' => $campaign, - ]; + ]); } /** - * @Route("/show/mailings/{campaign}/{status}", name="novaezmailing_campaign_mailings") - * @Template() + * @Route("/show/mailings/{campaign}/{status}", name="ibexamailing_campaign_mailings") + * * @Security("is_granted('view', campaign)") */ - public function mailingsAction(Campaign $campaign, EntityManagerInterface $entityManager, string $status): array + public function mailingsAction(Campaign $campaign, MailingRepository $mailingRepository, string $status): Response { - $repo = $entityManager->getRepository(Mailing::class); - $results = $repo->findByFilters( + $results = $mailingRepository->findByFilters( [ 'campaign' => $campaign, 'status' => $status, ] ); - return [ + return $this->render('@IbexaMailing/admin/campaign/mailings.html.twig', [ 'item' => $campaign, 'status' => $status, 'children' => $results, - ]; + ]); } /** - * @Route("/edit/{campaign}", name="novaezmailing_campaign_edit") - * @Route("/create", name="novaezmailing_campaign_create") - * @Security("is_granted('edit', campaign)") - * @Template() + * @Route("/edit/{campaign}", name="ibexamailing_campaign_edit") + * @Route("/create", name="ibexamailing_campaign_create") * - * @return array|RedirectResponse + * @Security("is_granted('edit', campaign)") */ public function editAction( ?Campaign $campaign, Request $request, - RouterInterface $router, EntityManagerInterface $entityManager, FormFactoryInterface $formFactory, TranslationHelper $translationHelper - ) { - if (null === $campaign) { + ): Response { + if ($campaign === null) { $campaign = new Campaign(); $languages = array_filter($translationHelper->getAvailableLanguages()); - $campaign->setNames(array_combine($languages, array_pad([], count($languages), ''))); + $campaign->setNames(array_combine($languages, array_pad([], \count($languages), ''))); } $form = $formFactory->create(CampaignType::class, $campaign); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $campaign->setUpdated(new DateTime()); + $campaign->setUpdated(new \DateTime()); $entityManager->persist($campaign); $entityManager->flush(); - return new RedirectResponse( - $router->generate('novaezmailing_campaign_subscriptions', ['campaign' => $campaign->getId()]) - ); + return $this->redirectToRoute('ibexamailing_campaign_subscriptions', ['campaign' => $campaign->getId()]); } - return [ + return $this->render('@IbexaMailing/admin/campaign/edit.html.twig', [ 'item' => $campaign, 'form' => $form->createView(), - ]; + ]); } /** - * @Route("/delete/{campaign}", name="novaezmailing_campaign_remove") + * @Route("/delete/{campaign}", name="ibexamailing_campaign_remove") + * * @Security("is_granted('edit', campaign)") */ public function deleteAction( Campaign $campaign, EntityManagerInterface $entityManager, - RouterInterface $router ): RedirectResponse { $entityManager->remove($campaign); $entityManager->flush(); - return new RedirectResponse($router->generate('novaezmailing_dashboard_index')); + return $this->redirectToRoute('ibexamailing_dashboard_index'); } } diff --git a/bundle/Controller/Admin/ChartController.php b/bundle/Controller/Admin/ChartController.php index 02481fa..fbd8145 100644 --- a/bundle/Controller/Admin/ChartController.php +++ b/bundle/Controller/Admin/ChartController.php @@ -1,90 +1,57 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Utils\ChartDataBuilder; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast; -use Novactive\Bundle\eZMailingBundle\Entity\StatHit; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use CodeRhapsodie\IbexaMailingBundle\Core\Utils\ChartDataBuilder; +use CodeRhapsodie\IbexaMailingBundle\Repository\BroadcastRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\StatHitRepository; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; -class ChartController +class ChartController extends AbstractController { - /** - * @Template("@NovaeZMailing/admin/chart/generic.html.twig") - */ - public function browserChart(int $broadcastId, EntityManagerInterface $entityManager): array + public function browserChart(int $broadcastId, BroadcastRepository $broadcastRepository, StatHitRepository $statHitRepository): Response { - $repo = $entityManager->getRepository(Broadcast::class); - /** @var Broadcast $item */ - $item = $repo->findOneById($broadcastId); - $hitRepo = $entityManager->getRepository(StatHit::class); - $data = $hitRepo->getBrowserMapCount([$item]); + $item = $broadcastRepository->find($broadcastId); + + $data = $statHitRepository->getBrowserMapCount([$item]); $chartBuilder = new ChartDataBuilder('Browser Repartition', 'doughnut'); $chartBuilder->addDataSet(array_values($data), array_keys($data)); - return ['chart' => $chartBuilder()]; + return $this->render('@IbexaMailing/admin/chart/generic.html.twig', ['chart' => $chartBuilder()]); } - /** - * @Template("@NovaeZMailing/admin/chart/generic.html.twig") - */ - public function osChart(int $broadcastId, EntityManagerInterface $entityManager): array + public function osChart(int $broadcastId, BroadcastRepository $broadcastRepository, StatHitRepository $statHitRepository): Response { - $repo = $entityManager->getRepository(Broadcast::class); - /** @var Broadcast $item */ - $item = $repo->findOneById($broadcastId); - $hitRepo = $entityManager->getRepository(StatHit::class); + $item = $broadcastRepository->find($broadcastId); - $data = $hitRepo->getOSMapCount([$item]); + $data = $statHitRepository->getOSMapCount([$item]); $chartBuilder = new ChartDataBuilder('OS Repartition', 'doughnut'); $chartBuilder->addDataSet(array_values($data), array_keys($data)); - return ['chart' => $chartBuilder()]; + return $this->render('@IbexaMailing/admin/chart/generic.html.twig', ['chart' => $chartBuilder()]); } - /** - * @Template("@NovaeZMailing/admin/chart/generic.html.twig") - */ - public function urlChart(int $broadcastId, EntityManagerInterface $entityManager): array + public function urlChart(int $broadcastId, BroadcastRepository $broadcastRepository, StatHitRepository $statHitRepository): Response { - $repo = $entityManager->getRepository(Broadcast::class); - /** @var Broadcast $item */ - $item = $repo->findOneById($broadcastId); - $hitRepo = $entityManager->getRepository(StatHit::class); + $item = $broadcastRepository->find($broadcastId); - $data = $hitRepo->getURLMapCount([$item]); + $data = $statHitRepository->getURLMapCount([$item]); $chartBuilder = new ChartDataBuilder('URLs Clicked Repartition', 'pie'); $chartBuilder->addDataSet(array_values($data), array_keys($data)); - return ['chart' => $chartBuilder()]; + return $this->render('@IbexaMailing/admin/chart/generic.html.twig', ['chart' => $chartBuilder()]); } - /** - * @Template("@NovaeZMailing/admin/chart/generic.html.twig") - */ - public function openedChart(int $broadcastId, EntityManagerInterface $entityManager): array + public function openedChart(int $broadcastId, BroadcastRepository $broadcastRepository, StatHitRepository $statHitRepository): Response { - $repo = $entityManager->getRepository(Broadcast::class); - /** @var Broadcast $item */ - $item = $repo->findOneById($broadcastId); - $hitRepo = $entityManager->getRepository(StatHit::class); - $openedCount = $hitRepo->getOpenedCount([[$item]]); + $item = $broadcastRepository->find($broadcastId); + $openedCount = $statHitRepository->getOpenedCount([$item]); $broadcastCount = $item->getEmailSentCount(); $data = [ 'Opened' => $openedCount, @@ -94,25 +61,20 @@ public function openedChart(int $broadcastId, EntityManagerInterface $entityMana $chartBuilder = new ChartDataBuilder('Opened emails', 'pie'); $chartBuilder->addDataSet(array_values($data), array_keys($data)); - return ['chart' => $chartBuilder()]; + return $this->render('@IbexaMailing/admin/chart/generic.html.twig', ['chart' => $chartBuilder()]); } - /** - * @Template("@NovaeZMailing/admin/chart/generic.html.twig") - */ - public function openedTimeChart(int $broadcastId, EntityManagerInterface $entityManager): array + public function openedTimeChart(int $broadcastId, BroadcastRepository $broadcastRepository, StatHitRepository $statHitRepository): Response { - $repo = $entityManager->getRepository(Broadcast::class); - /** @var Broadcast $item */ - $item = $repo->findOneById($broadcastId); - $hitRepo = $entityManager->getRepository(StatHit::class); - $data = $hitRepo->getOpenedCountPerDay([[$item]]); + $item = $broadcastRepository->find($broadcastId); + + $data = $statHitRepository->getOpenedCountPerDay([$item]); $chartBuilder = new ChartDataBuilder('Opened per day', 'bar'); $values = array_values($data); - $chartBuilder->addDataSet($values, array_keys($data), array_pad([], count($values), '#36a2eb')); + $chartBuilder->addDataSet($values, array_keys($data), array_pad([], \count($values), '#36a2eb')); $chartBuilder->addDataSet($values, array_keys($data), ['#ff6384'], 'line'); - return ['chart' => $chartBuilder()]; + return $this->render('@IbexaMailing/admin/chart/generic.html.twig', ['chart' => $chartBuilder()]); } } diff --git a/bundle/Controller/Admin/DashboardController.php b/bundle/Controller/Admin/DashboardController.php index 46d7eb9..27523d5 100644 --- a/bundle/Controller/Admin/DashboardController.php +++ b/bundle/Controller/Admin/DashboardController.php @@ -1,59 +1,42 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Repository\BroadcastRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingListRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Routing\RouterInterface; -class DashboardController +class DashboardController extends AbstractController { /** - * @Route("/", name="novaezmailing_dashboard_index") - * @Template() - * - * @return Response + * @Route("/", name="ibexamailing_dashboard_index") */ - public function indexAction(EntityManagerInterface $entityManager): array + public function indexAction(BroadcastRepository $broadcastRepository, UserRepository $userRepository, MailingRepository $mailingRepository): Response { - $repoBroadcast = $entityManager->getRepository(Broadcast::class); - $repoUsers = $entityManager->getRepository(User::class); - $repoMailings = $entityManager->getRepository(Mailing::class); - - return [ - 'broadcasts' => $repoBroadcast->findLastBroadcasts(5), - 'mailings' => $repoMailings->findLastUpdated(5), - 'users' => $repoUsers->findLastUpdated(5), - ]; + return $this->render('@IbexaMailing/admin/dashboard/index.html.twig', [ + 'broadcasts' => $broadcastRepository->findLastBroadcasts(5), + 'mailings' => $mailingRepository->findLastUpdated(5), + 'users' => $userRepository->findLastUpdated(5), + ]); } /** - * @Route("/search/autocomplete", name="novaezmailing_dashboard_search_autocomplete") + * @Route("/search/autocomplete", name="ibexamailing_dashboard_search_autocomplete") */ public function autocompleteSearchAction( Request $request, - RouterInterface $router, - EntityManagerInterface $entityManager + MailingListRepository $mailingListRepository, + UserRepository $userRepository ): JsonResponse { if (!$request->isXmlHttpRequest()) { return new JsonResponse('Not Authorized', 403); @@ -61,32 +44,30 @@ public function autocompleteSearchAction( $query = $request->query->get('query'); - $repo = $entityManager->getRepository(User::class); - $users = $repo->findByFilters(['query' => $query]); + $users = $userRepository->findByFilters(['query' => $query]); $userResults = array_map( - function (User $user) use ($router) { + function (User $user) { $userName = trim($user->getFirstName().' '.$user->getLastName()); - if ('' === $userName) { + if ($userName === '') { $userName = $user->getEmail(); } return [ 'value' => $userName, - 'data' => $router->generate('novaezmailing_user_show', ['user' => $user->getId()]), + 'data' => $this->generateUrl('ibexamailing_user_show', ['user' => $user->getId()]), ]; }, $users ); - $repo = $entityManager->getRepository(MailingList::class); - $mailingLists = $repo->findByFilters(['query' => $query]); + $mailingLists = $mailingListRepository->findByFilters(['query' => $query]); $mailingListResults = array_map( - function (MailingList $mailingList) use ($router) { + function (MailingList $mailingList) { return [ 'value' => trim($mailingList->getName()), - 'data' => $router->generate( - 'novaezmailing_mailinglist_show', + 'data' => $this->generateUrl( + 'ibexamailing_mailinglist_show', ['mailingList' => $mailingList->getId()] ), ]; diff --git a/bundle/Controller/Admin/ExportController.php b/bundle/Controller/Admin/ExportController.php index c21b6ae..f74b917 100644 --- a/bundle/Controller/Admin/ExportController.php +++ b/bundle/Controller/Admin/ExportController.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; use Doctrine\DBAL\Connection; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Annotation\Route; @@ -17,40 +17,41 @@ class ExportController { /** - * @Route("/mailing-list/{mailinglist}", name="novaezmailing_mailinglist_export") + * @Route("/mailing-list/{mailinglist}", name="ibexamailing_mailinglist_export") * * @Security("is_granted('view', mailinglist)") */ public function showAction( MailingList $mailinglist, - Connection $connection, - ) - { + Connection $connection, + ): Response { $sql = 'SELECT u.USER_email, u.USER_first_name, u.USER_last_name, u.USER_gender,u.USER_birth_date,u.USER_phone,u.USER_zipcode,u.USER_city,u.USER_state,u.USER_country,u.USER_job_title,u.USER_company ,u.USER_status -from novaezmailing_user u -inner join novaezmailing_registrations nr on u.USER_id = nr.USER_id +from mailing_user u +inner join mailing_registrations nr on u.USER_id = nr.USER_id where nr.ML_id = ?'; - return new StreamedResponse($this->generate($connection, $sql, [$mailinglist->getId()]), headers: ['Content-Type' => 'text/csv; charset=utf-8', 'Content-Disposition' => 'attachment; filename="' . urlencode(str_replace(' ', '_', $mailinglist->getName())) . '.csv"']); + return new StreamedResponse($this->generate($connection, $sql, [$mailinglist->getId()]), headers: ['Content-Type' => 'text/csv; charset=utf-8', 'Content-Disposition' => 'attachment; filename="'.urlencode(str_replace(' ', '_', $mailinglist->getName())).'.csv"']); } /** - * @Route("/users", name="novaezmailing_users_export") - * + * @Route("/users", name="ibexamailing_users_export") */ - public function exportUsersAction(Connection $connection) + public function exportUsersAction(Connection $connection): Response { $sql = 'SELECT u.USER_email, u.USER_first_name, u.USER_last_name, u.USER_gender,u.USER_birth_date,u.USER_phone,u.USER_zipcode,u.USER_city,u.USER_state,u.USER_country,u.USER_job_title,u.USER_company ,u.USER_status -from novaezmailing_user u;'; +from mailing_user u;'; return new StreamedResponse($this->generate($connection, $sql), headers: ['Content-Type' => 'text/csv; charset=utf-8', 'Content-Disposition' => 'attachment; filename="users.csv"']); } - private function generate(Connection $connection, string $sql, $parameters = []): \Closure + /** + * @param array $parameters + */ + private function generate(Connection $connection, string $sql, array $parameters = []): \Closure { return function () use ($connection, $sql, $parameters) { $csv = fopen('php://output', 'w+'); - fputcsv($csv, ['Courriel', 'Prénom', 'Nom', 'Sexe', 'Date de naissance', 'Téléphone', 'Code postal', 'Ville', 'Etat', 'Pays', 'Profession', 'Société','status'], ';'); + fputcsv($csv, ['Courriel', 'Prénom', 'Nom', 'Sexe', 'Date de naissance', 'Téléphone', 'Code postal', 'Ville', 'Etat', 'Pays', 'Profession', 'Société', 'status'], ';'); foreach ($connection->iterateAssociative($sql, $parameters) as $user) { fputcsv($csv, $user, ';'); diff --git a/bundle/Controller/Admin/MailingController.php b/bundle/Controller/Admin/MailingController.php index 72cb7aa..60aebe3 100644 --- a/bundle/Controller/Admin/MailingController.php +++ b/bundle/Controller/Admin/MailingController.php @@ -1,58 +1,48 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\Processor\TestMailingProcessorInterface as TestMailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Form\MailingType; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; use Doctrine\ORM\EntityManagerInterface; use Ibexa\AdminUi\Form\Factory\FormFactory; use Ibexa\AdminUi\Tab\LocationView\ContentTab; use Ibexa\AdminUi\UI\Module\Subitems\ContentViewParameterSupplier; use Ibexa\Contracts\Core\Repository\Repository; use Ibexa\Core\Helper\TranslationHelper; +use Ibexa\Core\MVC\Symfony\SiteAccess\Router; use Ibexa\Core\MVC\Symfony\View\ContentView; -use Novactive\Bundle\eZMailingBundle\Core\Processor\TestMailingProcessorInterface as TestMailing; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use Novactive\Bundle\eZMailingBundle\Form\MailingType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Workflow\Registry; /** * @Route("/mailing") */ -class MailingController +class MailingController extends AbstractController { /** - * @Route("/show/{mailing}", name="novaezmailing_mailing_show") - * @Template() + * @Route("/show/{mailing}", name="ibexamailing_mailing_show") + * * @IsGranted("view", subject="mailing") */ public function showAction( Mailing $mailing, ContentViewParameterSupplier $contentViewParameterSupplier, FormFactory $formFactory - ): array { + ): Response { $contentView = new ContentView(); $contentView->setLocation($mailing->getLocation()); $contentView->setContent($mailing->getContent()); @@ -63,23 +53,22 @@ public function showAction( 'form_subitems_content_edit' ); - return [ + return $this->render('@IbexaMailing/admin/mailing/show.html.twig', [ 'item' => $mailing, 'form_subitems_content_edit' => $subitemsContentEdit->createView(), 'subitems_module' => $contentView->getParameter('subitems_module'), - ]; + ]); } /** - * @Template() * @IsGranted("view", subject="mailing") */ public function mailingTabsAction( Mailing $mailing, Repository $repository, ContentTab $contentTab, - EntityManagerInterface $entityManager - ): array { + UserRepository $userRepository + ): Response { $content = $mailing->getContent(); $contentType = $repository->getContentTypeService()->loadContentType( $content->contentInfo->contentTypeId @@ -92,42 +81,43 @@ public function mailingTabsAction( ] ); - return [ + return $this->render('@IbexaMailing/admin/mailing/mailing_tabs.html.twig', [ 'item' => $mailing, - 'totalRecipients' => $entityManager->getRepository(User::class)->countValidRecipients( - $mailing->getCampaign()->getMailingLists() + 'totalRecipients' => $userRepository->countValidRecipients( + $mailing->getCampaign()->getMailingLists()->toArray() ), 'preview' => $preview, - ]; + ]); } /** - * @Route("/edit/{mailing}", name="novaezmailing_mailing_edit") - * @ParamConverter("mailing", class="Novactive\Bundle\eZMailingBundle\Entity\Mailing", options={"id"="mailing"}) - * @Route("/create/{campaign}", name="novaezmailing_mailing_create") - * @ParamConverter("campaign", class="Novactive\Bundle\eZMailingBundle\Entity\Campaign", options={"id"="campaign"}) - * @Template() + * @Route("/edit/{mailing}", name="ibexamailing_mailing_edit") + * + * @ParamConverter("mailing", class="CodeRhapsodie\IbexaMailingBundle\Entity\Mailing", options={"id"="mailing"}) + * + * @Route("/create/{campaign}", name="ibexamailing_mailing_create") * - * @return array|RedirectResponse + * @ParamConverter("campaign", class="CodeRhapsodie\IbexaMailingBundle\Entity\Campaign", options={"id"="campaign"}) + * + * @return Response */ public function editAction( ?Mailing $mailing, ?Campaign $campaign, Request $request, - RouterInterface $router, FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, Registry $workflows, TranslationHelper $translationHelper, Repository $repository ) { - if (null === $mailing) { + if ($mailing === null) { $mailing = new Mailing(); $mailing ->setStatus(Mailing::DRAFT) ->setCampaign($campaign); $languages = array_filter($translationHelper->getAvailableLanguages()); - $mailing->setNames(array_combine($languages, array_pad([], count($languages), ''))); + $mailing->setNames(array_combine($languages, array_pad([], \count($languages), ''))); } $machine = $workflows->get($mailing); @@ -140,71 +130,72 @@ public function editAction( if ($form->isSubmitted() && $form->isValid()) { $machine->apply($mailing, 'edit'); - $mailing->setUpdated(new DateTime()); + $mailing->setUpdated(new \DateTime()); $entityManager->persist($mailing); $entityManager->flush(); - return new RedirectResponse( - $router->generate('novaezmailing_mailing_show', ['mailing' => $mailing->getId()]) - ); + return $this->redirectToRoute('ibexamailing_mailing_show', ['mailing' => $mailing->getId()]); } - if (null !== $mailing->getLocationId()) { + if ($mailing->getLocationId() !== null) { $location = $repository->getLocationService()->loadLocation($mailing->getLocationId()); $content = $repository->getContentService()->loadContentByContentInfo($location->contentInfo); $mailing->setLocation($location); $mailing->setContent($content); } - return [ + return $this->render('@IbexaMailing/admin/mailing/edit.html.twig', [ 'item' => $mailing, 'form' => $form->createView(), - ]; + ]); } /** - * @Route("/confirm/{mailing}", name="novaezmailing_mailing_confirm") - * @Route("/archive/{mailing}", name="novaezmailing_mailing_archive") - * @Route("/abort/{mailing}", name="novaezmailing_mailing_cancel") + * @Route("/confirm/{mailing}", name="ibexamailing_mailing_confirm") + * @Route("/archive/{mailing}", name="ibexamailing_mailing_archive") + * @Route("/abort/{mailing}", name="ibexamailing_mailing_cancel") + * * @IsGranted("view", subject="mailing") */ public function statusAction( Request $request, Mailing $mailing, - RouterInterface $router, EntityManagerInterface $entityManager, Registry $workflows ): RedirectResponse { - $action = substr($request->get('_route'), \strlen('novaezmailing_mailing_')); + $action = substr($request->get('_route'), \strlen('ibexamailing_mailing_')); $machine = $workflows->get($mailing); $machine->apply($mailing, $action); $entityManager->flush(); - return new RedirectResponse($router->generate('novaezmailing_mailing_show', ['mailing' => $mailing->getId()])); + return $this->redirectToRoute('ibexamailing_mailing_show', ['mailing' => $mailing->getId()]); } /** - * @Route("/test/{mailing}", name="novaezmailing_mailing_test", methods={"POST"}) + * @Route("/test/{mailing}", name="ibexamailing_mailing_test", methods={"POST"}) + * * @IsGranted("view", subject="mailing") */ public function testAction( Request $request, Mailing $mailing, TestMailing $processor, - RouterInterface $router, EntityManagerInterface $entityManager, - Registry $workflows + Registry $workflows, + Router $ibexaRouter ): RedirectResponse { $machine = $workflows->get($mailing); + $siteaccess = $ibexaRouter->getSiteAccess()->name; + if ($machine->can($mailing, 'test')) { $ccEmail = $request->request->get('cc'); - if (\strlen($ccEmail) > 0) { + if ($ccEmail !== '') { $processor->execute($mailing, $ccEmail); $machine->apply($mailing, 'test'); $entityManager->flush(); } } - return new RedirectResponse($router->generate('novaezmailing_mailing_show', ['mailing' => $mailing->getId()])); + return $this->redirectToRoute('ibexamailing_mailing_show', ['mailing' => $mailing->getId(), 'siteaccess' => $siteaccess]); } } diff --git a/bundle/Controller/Admin/MailingListController.php b/bundle/Controller/Admin/MailingListController.php index 6ea7116..e9834a1 100644 --- a/bundle/Controller/Admin/MailingListController.php +++ b/bundle/Controller/Admin/MailingListController.php @@ -1,102 +1,85 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\UserImport; +use CodeRhapsodie\IbexaMailingBundle\Core\Import\User; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\User as UserProvider; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\User as UserEntity; +use CodeRhapsodie\IbexaMailingBundle\Form\ImportType; +use CodeRhapsodie\IbexaMailingBundle\Form\MailingListType; use Doctrine\ORM\EntityManagerInterface; use Ibexa\Core\Helper\TranslationHelper; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\UserImport; -use Novactive\Bundle\eZMailingBundle\Core\Import\User; -use Novactive\Bundle\eZMailingBundle\Core\Provider\User as UserProvider; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\User as UserEntity; -use Novactive\Bundle\eZMailingBundle\Form\ImportType; -use Novactive\Bundle\eZMailingBundle\Form\MailingListType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; /** * @Route("/mailinglist") */ -class MailingListController +class MailingListController extends AbstractController { /** - * @Route("/show/{mailingList}/{status}/{page}/{limit}", name="novaezmailing_mailinglist_show", + * @Route("/show/{mailingList}/{status}/{page}/{limit}", name="ibexamailing_mailinglist_show", * defaults={"page":1, "limit":10, "status":"all"}) + * * @Security("is_granted('view', mailingList)") - * @Template() */ public function showAction( - MailingList $mailingList, + MailingList $mailingList, UserProvider $provider, - string $status = 'all', - int $page = 1, - int $limit = 10 - ): array - { + string $status = 'all', + int $page = 1, + int $limit = 10 + ): Response { $filers = [ 'mailingLists' => [$mailingList], - 'status' => 'all' === $status ? null : $status, + 'status' => $status === 'all' ? null : $status, ]; - return [ + return $this->render('@IbexaMailing/admin/mailing_list/show.html.twig', [ 'pager' => $provider->getPagerFilters($filers, $page, $limit), 'item' => $mailingList, 'statuses' => $provider->getStatusesData($filers), 'currentStatus' => $status, - ]; + ]); } /** - * @Route("", name="novaezmailing_mailinglist_index") - * @Template() + * @Route("", name="ibexamailing_mailinglist_index") */ - public function indexAction(EntityManagerInterface $entityManager): array + public function indexAction(EntityManagerInterface $entityManager): Response { $repo = $entityManager->getRepository(MailingList::class); - return ['items' => $repo->findAll()]; + return $this->render('@IbexaMailing/admin/mailing_list/index.html.twig', ['items' => $repo->findAll()]); } /** - * @Route("/edit/{mailinglist}", name="novaezmailing_mailinglist_edit") - * @Route("/create", name="novaezmailing_mailinglist_create") - * @Security("is_granted('edit', mailinglist)") - * @Template() + * @Route("/edit/{mailinglist}", name="ibexamailing_mailinglist_edit") + * @Route("/create", name="ibexamailing_mailinglist_create") * - * @return array|RedirectResponse + * @Security("is_granted('edit', mailinglist)") */ public function editAction( - ?MailingList $mailinglist, - Request $request, - RouterInterface $router, - FormFactoryInterface $formFactory, + ?MailingList $mailinglist, + Request $request, + FormFactoryInterface $formFactory, EntityManagerInterface $entityManager, - TranslationHelper $translationHelper - ) - { - if (null === $mailinglist) { + TranslationHelper $translationHelper + ): Response { + if ($mailinglist === null) { $mailinglist = new MailingList(); $languages = array_filter($translationHelper->getAvailableLanguages()); - $mailinglist->setNames(array_combine($languages, array_pad([], count($languages), ''))); + $mailinglist->setNames(array_combine($languages, array_pad([], \count($languages), ''))); } $form = $formFactory->create(MailingListType::class, $mailinglist); @@ -104,50 +87,46 @@ public function editAction( if ($form->isSubmitted() && $form->isValid()) { $mailinglist - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $entityManager->persist($mailinglist); $entityManager->flush(); - return new RedirectResponse( - $router->generate('novaezmailing_mailinglist_show', ['mailingList' => $mailinglist->getId()]) - ); + return $this->redirectToRoute('ibexamailing_mailinglist_show', ['mailingList' => $mailinglist->getId()]); } - return [ + return $this->render('@IbexaMailing/admin/mailing_list/edit.html.twig', [ 'item' => $mailinglist, 'form' => $form->createView(), - ]; + ]); } /** - * @Route("/delete/{mailinglist}", name="novaezmailing_mailinglist_remove") + * @Route("/delete/{mailinglist}", name="ibexamailing_mailinglist_remove") + * * @Security("is_granted('edit', mailinglist)") */ public function deleteAction( - MailingList $mailinglist, + MailingList $mailinglist, EntityManagerInterface $entityManager, - RouterInterface $router - ): RedirectResponse - { + ): RedirectResponse { $entityManager->remove($mailinglist); $entityManager->flush(); - return new RedirectResponse($router->generate('novaezmailing_mailinglist_index')); + return $this->redirectToRoute('ibexamailing_mailinglist_index'); } /** - * @Route("/import/{mailinglist}", name="novaezmailing_mailinglist_import") + * @Route("/import/{mailinglist}", name="ibexamailing_mailinglist_import") + * * @Security("is_granted('edit', mailinglist)") - * @Template() */ public function importAction( - MailingList $mailinglist, + MailingList $mailinglist, FormFactoryInterface $formFactory, - Request $request, - User $importer, - ValidatorInterface $validator - ): array - { + Request $request, + User $importer, + ValidatorInterface $validator + ): Response { $userImport = new UserImport(); $form = $formFactory->create(ImportType::class, $userImport); $form->handleRequest($request); @@ -158,9 +137,9 @@ public function importAction( try { $user = $importer->hydrateUser($row); $user - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $errors = $validator->validate($user); - if (count($errors) > 0) { + if (\count($errors) > 0) { $errorList["Line {$index}"] = $errors; continue; } @@ -175,11 +154,11 @@ public function importAction( } } - return [ + return $this->render('@IbexaMailing/admin/mailing_list/import.html.twig', [ 'count' => $count, 'error_list' => $errorList, 'item' => $mailinglist, 'form' => $form->createView(), - ]; + ]); } } diff --git a/bundle/Controller/Admin/RegistrationController.php b/bundle/Controller/Admin/RegistrationController.php index 20025ac..4193a16 100644 --- a/bundle/Controller/Admin/RegistrationController.php +++ b/bundle/Controller/Admin/RegistrationController.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; -use Novactive\Bundle\eZMailingBundle\Core\AjaxGuard; -use Novactive\Bundle\eZMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Core\AjaxGuard; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; @@ -26,7 +16,7 @@ class RegistrationController { /** - * @Route("/accept/{registration}", name="novaezmailing_registration_accept", methods={"POST"}) + * @Route("/accept/{registration}", name="ibexamailing_registration_accept", methods={"POST"}) */ public function acceptAction( Request $request, @@ -47,7 +37,7 @@ function (Registration $registration) { } /** - * @Route("/deny/{registration}", name="novaezmailing_registration_deny") + * @Route("/deny/{registration}", name="ibexamailing_registration_deny") */ public function denyAction( Request $request, diff --git a/bundle/Controller/Admin/UserController.php b/bundle/Controller/Admin/UserController.php index b5c3dcc..30d8eba 100644 --- a/bundle/Controller/Admin/UserController.php +++ b/bundle/Controller/Admin/UserController.php @@ -1,24 +1,16 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller\Admin; +namespace CodeRhapsodie\IbexaMailingBundle\Controller\Admin; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\User as UserProvider; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Provider\User as UserProvider; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Ibexa\User\UserSetting\UserSettingService; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\RouterInterface; @@ -26,25 +18,24 @@ /** * @Route("/user") */ -class UserController +class UserController extends AbstractController { /** - * @Route("/show/{user}", name="novaezmailing_user_show") - * @Template() + * @Route("/show/{user}", name="ibexamailing_user_show") */ - public function showAction(User $user): array + public function showAction(User $user): Response { if ($user->isRestricted()) { - throw new AccessDeniedHttpException('User has been restricted'); + throw new AccessDeniedHttpException('UserRepository has been restricted'); } - return [ + return $this->render('@IbexaMailing/admin/user/show.html.twig', [ 'item' => $user, - ]; + ]); } /** - * @Route("/delete/{user}", name="novaezmailing_user_remove") + * @Route("/delete/{user}", name="ibexamailing_user_remove") */ public function deleteAction( User $user, @@ -54,24 +45,23 @@ public function deleteAction( $entityManager->remove($user); $entityManager->flush(); - return new RedirectResponse($router->generate('novaezmailing_user_index')); + return new RedirectResponse($router->generate('ibexamailing_user_index')); } /** - * @Route("/{status}/{page}/{limit}", name="novaezmailing_user_index", - * defaults={"page":1, "limit":10, "status":"all"}) - * @Template() + * @Route("/{status}/{page}", name="ibexamailing_user_index", + * defaults={"page":1, "status":"all"}) */ - public function indexAction(UserProvider $provider, string $status = 'all', int $page = 1, int $limit = 10): array + public function indexAction(UserProvider $provider, UserSettingService $userSettingService, string $status = 'all', int $page = 1): Response { $filters = [ - 'status' => 'all' === $status ? null : $status, + 'status' => $status === 'all' ? null : $status, ]; - return [ - 'pager' => $provider->getPagerFilters($filters, $page, $limit), + return $this->render('@IbexaMailing/admin/user/index.html.twig', [ + 'pager' => $provider->getPagerFilters($filters, $page, (int) $userSettingService->getUserSetting('subitems_limit')->value), 'statuses' => $provider->getStatusesData($filters), 'currentStatus' => $status, - ]; + ]); } } diff --git a/bundle/Controller/RegistrationController.php b/bundle/Controller/RegistrationController.php index 60e0213..8bb4492 100644 --- a/bundle/Controller/RegistrationController.php +++ b/bundle/Controller/RegistrationController.php @@ -1,52 +1,43 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller; - +namespace CodeRhapsodie\IbexaMailingBundle\Controller; + +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Registration; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Unregistration; +use CodeRhapsodie\IbexaMailingBundle\Core\Registrar; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\ConfirmationToken; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Form\RegistrationType; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Campaign as CampaignVoter; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Mailing as MailingVoter; use Doctrine\ORM\EntityManagerInterface; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Registration; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Unregistration; -use Novactive\Bundle\eZMailingBundle\Core\Registrar; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\ConfirmationToken; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use Novactive\Bundle\eZMailingBundle\Form\RegistrationType; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Campaign as CampaignVoter; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Mailing as MailingVoter; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; -class RegistrationController +class RegistrationController extends AbstractController { - public function __construct( - private readonly Registrar $registrar, - private readonly ConfigResolverInterface $configResolver, - private readonly EntityManagerInterface $entityManager, + private readonly Registrar $registrar, + private readonly ConfigResolverInterface $configResolver, + private readonly EntityManagerInterface $entityManager, private readonly AuthorizationCheckerInterface $authorizationChecker - ) - { + ) { } /** - * @Route("/register", name="novaezmailing_registration_create") + * @Route("/register", name="ibexamailing_registration_create") * - * @Template() + * @SuppressWarnings(PHPMD.ElseExpression) */ - public function registerAction(Request $request, FormFactoryInterface $formFactory): array + public function registerAction(Request $request, FormFactoryInterface $formFactory): Response { $params = [ 'pagelayout' => $this->getPagelayout(), @@ -66,15 +57,15 @@ public function registerAction(Request $request, FormFactoryInterface $formFacto ]; } - return $params; + return $this->render('@IbexaMailing/registration/register.html.twig', $params); } /** - * @Route("/register/default", name="novaezmailing_registration_default_create") + * @Route("/register/default", name="ibexamailing_registration_default_create") * - * @Template() + * @SuppressWarnings(PHPMD.ElseExpression) */ - public function registerDefaultAction(Request $request, FormFactoryInterface $formFactory): array + public function registerDefaultAction(Request $request, FormFactoryInterface $formFactory): Response { $params = [ 'pagelayout' => $this->getPagelayout(), @@ -98,29 +89,25 @@ public function registerDefaultAction(Request $request, FormFactoryInterface $fo ]; } - return $params; + return $this->render('@IbexaMailing/registration/register_default.html.twig', $params); } /** - * @Route("/register/confirm/{id}", name="novaezmailing_registration_confirm") - * - * @Template() + * @Route("/register/confirm/{id}", name="ibexamailing_registration_confirm") */ - public function registerConfirmationAction(ConfirmationToken $token): array + public function registerConfirmationAction(ConfirmationToken $token): Response { - return [ + return $this->render('@IbexaMailing/registration/register_confirmation.html.twig', [ 'pagelayout' => $this->getPagelayout(), 'title' => 'Confirm registration to Mailing Lists', 'isConfirmed' => $this->registrar->confirm($token), - ]; + ]); } /** - * @Route("/unregister/{email}", name="novaezmailing_registration_remove") - * - * @Template() + * @Route("/unregister/{email}", name="ibexamailing_registration_remove") */ - public function unregisterAction(string $email = null, Request $request, FormFactoryInterface $formFactory): array + public function unregisterAction(string $email = null, Request $request, FormFactoryInterface $formFactory): Response { $params = [ 'pagelayout' => $this->getPagelayout(), @@ -137,21 +124,8 @@ public function unregisterAction(string $email = null, Request $request, FormFac $unregistration->setUser($user); } - if ($this->configResolver->getParameter('unsubscribe_all', 'nova_ezmailing')) { - $allowedMailingList = []; - $campaignRepository = $this->entityManager->getRepository(Campaign::class); - // permissions on Campaing can be more complex, then we don't filter in SQL - foreach ($campaignRepository->findAll() as $campaign) { - if ($this->authorizationChecker->isGranted(CampaignVoter::VIEW, $campaign)) { - foreach ($campaign->getMailingLists() as $mailingList) { - if ($this->authorizationChecker->isGranted(MailingVoter::VIEW, $mailingList)) { - $allowedMailingList[] = $mailingList; - } - } - } - } - - $unregistration->setMailingLists($allowedMailingList); + if ($this->configResolver->getParameter('unsubscribe_all', 'ibexamailing')) { + $this->unsubscribeAll($unregistration); } $form = $formFactory->create(RegistrationType::class, $unregistration); @@ -160,34 +134,50 @@ public function unregisterAction(string $email = null, Request $request, FormFac if ($form->isSubmitted() && $form->isValid()) { if ($this->registrar->askForUnregisterConfirmation($unregistration)) { - return $params; + return $this->render('@IbexaMailing/registration/register_confirmation.html.twig', $params); } } $params += [ 'form' => $form->createView(), - 'unsubscribeAll' => $this->configResolver->getParameter('unsubscribe_all', 'nova_ezmailing'), + 'unsubscribeAll' => $this->configResolver->getParameter('unsubscribe_all', 'ibexamailing'), ]; - return $params; + return $this->render('@IbexaMailing/registration/unregister.html.twig', $params); } /** - * @Route("/unregister/confirm/{id}", name="novaezmailing_unregistration_confirm") - * - * @Template() + * @Route("/unregister/confirm/{id}", name="ibexamailing_unregistration_confirm") */ - public function unregisterConfirmationAction(ConfirmationToken $token): array + public function unregisterConfirmationAction(ConfirmationToken $token): Response { - return [ + return $this->render('@IbexaMailing/registration/unregister_confirmation.html.twig', [ 'pagelayout' => $this->getPagelayout(), 'title' => 'Confirm unregistration to Mailing Lists', 'isConfirmed' => $this->registrar->confirm($token), - ]; + ]); } private function getPagelayout(): string { return $this->configResolver->getParameter('pagelayout'); } + + private function unsubscribeAll(Unregistration $unregistration): void + { + $allowedMailingList = []; + $campaignRepository = $this->entityManager->getRepository(Campaign::class); + // permissions on Campaing can be more complex, then we don't filter in SQL + foreach ($campaignRepository->findAll() as $campaign) { + if ($this->authorizationChecker->isGranted(CampaignVoter::VIEW, $campaign)) { + foreach ($campaign->getMailingLists() as $mailingList) { + if ($this->authorizationChecker->isGranted(MailingVoter::VIEW, $mailingList)) { + $allowedMailingList[] = $mailingList; + } + } + } + } + + $unregistration->setMailingLists($allowedMailingList); + } } diff --git a/bundle/Controller/TrackController.php b/bundle/Controller/TrackController.php index 4921f97..fc146b8 100644 --- a/bundle/Controller/TrackController.php +++ b/bundle/Controller/TrackController.php @@ -1,24 +1,13 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Controller; +namespace CodeRhapsodie\IbexaMailingBundle\Controller; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\Utils\Browser; +use CodeRhapsodie\IbexaMailingBundle\Entity\StatHit; +use CodeRhapsodie\IbexaMailingBundle\Repository\BroadcastRepository; use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Utils\Browser; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast; -use Novactive\Bundle\eZMailingBundle\Entity\StatHit; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -33,18 +22,18 @@ class TrackController public const PIXEL_CONTENT_TYPE = 'image/gif'; /** - * @Route("/continue/{salt}/{broadcastId}/{url}", name="novaezmailing_t_continue") + * @Route("/continue/{salt}/{broadcastId}/{url}", name="ibexamailing_t_continue") */ public function continueAction( - string $salt, - int $broadcastId, - string $url, + string $salt, + int $broadcastId, + string $url, EntityManagerInterface $entityManager, - Request $request - ): RedirectResponse - { - $broadcast = $entityManager->getRepository(Broadcast::class)->findOneByid($broadcastId); - $browser = new Browser($request->headers->get('User-Agent')); + BroadcastRepository $broadcastRepository, + Request $request + ): RedirectResponse { + $broadcast = $broadcastRepository->find($broadcastId); + $browser = new Browser($request->headers->get('user-agent', 'Unknown')); $stat = new StatHit(); $decodedUrl = base64_decode(str_replace(['-', '_'], ['+', '/'], $url)); $stat @@ -53,7 +42,7 @@ public function continueAction( ->setUserKey($salt) ->setUrl($decodedUrl) ->setBroadcast($broadcast) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $entityManager->persist($stat); $entityManager->flush(); @@ -61,17 +50,17 @@ public function continueAction( } /** - * @Route("/read/{salt}/{broadcastId}", name="novaezmailing_t_read") + * @Route("/read/{salt}/{broadcastId}", name="ibexamailing_t_read") */ public function readAction( - string $salt, - int $broadcastId, + string $salt, + int $broadcastId, EntityManagerInterface $entityManager, - Request $request - ): Response - { - $broadcast = $entityManager->getRepository(Broadcast::class)->findOneByid($broadcastId); - $browser = new Browser($request->headers->get('User-Agent')); + Request $request, + BroadcastRepository $broadcastRepository + ): Response { + $broadcast = $broadcastRepository->find($broadcastId); + $browser = new Browser($request->headers->get('user-agent', 'Unknown')); $stat = new StatHit(); $stat ->setOsName($browser->getPlatform()) @@ -79,7 +68,7 @@ public function readAction( ->setUserKey($salt) ->setUrl('-') ->setBroadcast($broadcast) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $entityManager->persist($stat); $entityManager->flush(); diff --git a/bundle/Core/AjaxGuard.php b/bundle/Core/AjaxGuard.php index 56b914a..2a141bf 100644 --- a/bundle/Core/AjaxGuard.php +++ b/bundle/Core/AjaxGuard.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core; +namespace CodeRhapsodie\IbexaMailingBundle\Core; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Persistence\Proxy; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Security\Csrf\CsrfToken; @@ -23,41 +13,21 @@ class AjaxGuard { - /** - * @var CsrfTokenManagerInterface - */ - private $csrfTokenManager; - - /** - * @var EntityManagerInterface - */ - private $entityManager; - - public function __construct(CsrfTokenManagerInterface $csrfTokenManager, EntityManagerInterface $entityManager) + public function __construct(private readonly CsrfTokenManagerInterface $csrfTokenManager, private readonly EntityManagerInterface $entityManager) { - $this->csrfTokenManager = $csrfTokenManager; - $this->entityManager = $entityManager; } - private function isEntity($class): bool - { - if (\is_object($class)) { - $class = ($class instanceof Proxy) - ? get_parent_class($class) - : \get_class($class); - } - - return !$this->entityManager->getMetadataFactory()->isTransient($class); - } - - public function execute(Request $request, $subject, callable $callback): array + /** + * @return array + */ + public function execute(Request $request, mixed $subject, callable $callback): array { $token = $request->request->get('token'); if ( - !$request->isXmlHttpRequest() || null === $token || - !$this->isEntity($subject) || - !method_exists($subject, 'getId') || - !$this->csrfTokenManager->isTokenValid(new CsrfToken((string) $subject->getId(), $token)) + !$request->isXmlHttpRequest() || $token === null + || !$this->isEntity($subject) + || !method_exists($subject, 'getId') + || !$this->csrfTokenManager->isTokenValid(new CsrfToken((string) $subject->getId(), $token)) ) { throw new AccessDeniedHttpException('Not Allowed'); } @@ -67,4 +37,15 @@ public function execute(Request $request, $subject, callable $callback): array return ['token' => $this->csrfTokenManager->getToken((string) $subject->getId())->getValue()] + $results; } + + private function isEntity(mixed $class): bool + { + if (\is_object($class)) { + $class = ($class instanceof Proxy) + ? get_parent_class($class) + : $class::class; + } + + return !$this->entityManager->getMetadataFactory()->isTransient($class); + } } diff --git a/bundle/Core/ContainerEntityListenerResolver.php b/bundle/Core/ContainerEntityListenerResolver.php deleted file mode 100644 index 219e2e6..0000000 --- a/bundle/Core/ContainerEntityListenerResolver.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - -declare(strict_types=1); - -namespace Novactive\Bundle\eZMailingBundle\Core; - -use Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver as DoctrineContainerEntityListenerResolver; - -class ContainerEntityListenerResolver extends DoctrineContainerEntityListenerResolver -{ -} diff --git a/bundle/Core/DataHandler/Registration.php b/bundle/Core/DataHandler/Registration.php index 75fac93..8c6a697 100644 --- a/bundle/Core/DataHandler/Registration.php +++ b/bundle/Core/DataHandler/Registration.php @@ -1,43 +1,26 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\DataHandler; +namespace CodeRhapsodie\IbexaMailingBundle\Core\DataHandler; -use Doctrine\Common\Collections\ArrayCollection; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; class Registration { - /** - * @var User - */ - private $user; + private ?User $user; /** - * @var MailingList[] + * @var array */ - private $mailingLists; + private array $mailingLists; public function __construct() { - $this->mailingLists = new ArrayCollection(); + $this->mailingLists = []; } - /** - * @return User - */ public function getUser(): ?User { return $this->user; @@ -54,19 +37,19 @@ public function setUser(User $user): self } /** - * @return MailingList[]|ArrayCollection + * @return MailingList[] */ - public function getMailingLists() + public function getMailingLists(): array { return $this->mailingLists; } /** - * @param MailingList[]|ArrayCollection $mailingLists + * @param MailingList[] $mailingLists * * @return $this */ - public function setMailingLists($mailingLists): self + public function setMailingLists(array $mailingLists): self { $this->mailingLists = $mailingLists; diff --git a/bundle/Core/DataHandler/Unregistration.php b/bundle/Core/DataHandler/Unregistration.php index 06fccf5..f1e5362 100644 --- a/bundle/Core/DataHandler/Unregistration.php +++ b/bundle/Core/DataHandler/Unregistration.php @@ -1,38 +1,24 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\DataHandler; +namespace CodeRhapsodie\IbexaMailingBundle\Core\DataHandler; -use Doctrine\Common\Collections\ArrayCollection; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; class Unregistration { - /** - * @var User - */ - private $user; + private ?User $user; /** - * @var MailingList[] + * @var array */ - private $mailingLists; + private array $mailingLists; public function __construct() { - $this->mailingLists = new ArrayCollection(); + $this->mailingLists = []; } public function getUser(): ?User @@ -48,9 +34,9 @@ public function setUser(User $user): self } /** - * @return MailingList[]|mixed + * @return MailingList[] */ - public function getMailingLists() + public function getMailingLists(): array { return $this->mailingLists; } diff --git a/bundle/Core/DataHandler/UserImport.php b/bundle/Core/DataHandler/UserImport.php index ccf513f..05de9ec 100644 --- a/bundle/Core/DataHandler/UserImport.php +++ b/bundle/Core/DataHandler/UserImport.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\DataHandler; +namespace CodeRhapsodie\IbexaMailingBundle\Core\DataHandler; use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\Validator\Constraints as Assert; @@ -21,7 +11,9 @@ class UserImport { /** * @var File + * * @Assert\NotBlank() + * * @Assert\File( * mimeTypes={"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" , "text/csv" , "text/plain"}, * mimeTypesMessage="Please upload a valid file (xls, xlsx , csv)" diff --git a/bundle/Core/IOService.php b/bundle/Core/IOService.php index 19f1bee..87bb404 100644 --- a/bundle/Core/IOService.php +++ b/bundle/Core/IOService.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core; +namespace CodeRhapsodie\IbexaMailingBundle\Core; use Ibexa\Core\IO\IOServiceInterface; use Symfony\Component\Filesystem\Filesystem; diff --git a/bundle/Core/Import/User.php b/bundle/Core/Import/User.php index ad16262..e0d04c7 100644 --- a/bundle/Core/Import/User.php +++ b/bundle/Core/Import/User.php @@ -1,47 +1,27 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Import; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Import; use Carbon\Carbon; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\UserImport; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Entity\User as UserEntity; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; use Doctrine\ORM\EntityManagerInterface; -use Exception; -use Generator; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\UserImport; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\Registration; -use Novactive\Bundle\eZMailingBundle\Entity\User as UserEntity; -use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Csv; use PhpOffice\PhpSpreadsheet\Shared\Date; class User { - /** - * @var EntityManagerInterface - */ - private $entityManager; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private readonly EntityManagerInterface $entityManager, private readonly UserRepository $userRepository) { - $this->entityManager = $entityManager; } - public function rowsIterator(UserImport $userImport): Generator + public function rowsIterator(UserImport $userImport): \Generator { - $encoding = Csv::guessEncoding($userImport->getFile()->getPathname()); $reader = new Csv(); $reader->setInputEncoding($encoding); @@ -49,7 +29,7 @@ public function rowsIterator(UserImport $userImport): Generator $worksheet = $spreadsheet->getActiveSheet(); foreach ($worksheet->getRowIterator() as $row) { - if (1 === $row->getRowIndex()) { + if ($row->getRowIndex() === 1) { continue; } $cells = []; @@ -65,17 +45,19 @@ public function rowsIterator(UserImport $userImport): Generator /** * Hydrate user. * + * @param array $cells + * * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function hydrateUser(array $cells): UserEntity { - $repo = $this->entityManager->getRepository(UserEntity::class); $user = new UserEntity(); if (isset($cells[0])) { - $user = $repo->findOneByEmail($cells[0]); + $user = $this->userRepository->findOneBy(['email' => $cells[0]]); if (!$user instanceof UserEntity) { $user = new UserEntity(); - $user->setEmail(filter_var($cells[0], FILTER_SANITIZE_EMAIL)); + $user->setEmail(filter_var($cells[0], \FILTER_SANITIZE_EMAIL)); } } if (isset($cells[1])) { @@ -89,17 +71,17 @@ public function hydrateUser(array $cells): UserEntity } if (isset($cells[4])) { try { - $date = Carbon::createFromFormat('Y-m-d', (string)$cells[4]); - } catch (Exception $e) { - $date = Date::excelToDateTimeObject((string)$cells[4]); + $date = Carbon::createFromFormat('Y-m-d', (string) $cells[4]); + } catch (\Exception) { + $date = Date::excelToDateTimeObject((int) $cells[4]); } $user->setBirthDate($date); } if (isset($cells[5])) { - $user->setPhone((string)$cells[5]); + $user->setPhone((string) $cells[5]); } if (isset($cells[6])) { - $user->setZipcode((string)$cells[6]); + $user->setZipcode((string) $cells[6]); } if (isset($cells[7])) { $user->setCity($cells[7]); @@ -127,7 +109,7 @@ public function hydrateUser(array $cells): UserEntity } /** - * Register the user to the MailingList. + * Register the user to the MailingListRepository. */ public function registerUser(UserEntity $user, MailingList $mailingList): UserEntity { @@ -136,7 +118,7 @@ public function registerUser(UserEntity $user, MailingList $mailingList): UserEn ->setUser($user) ->setMailingList($mailingList) ->setApproved(true) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $user->addRegistration($registration); $this->entityManager->persist($user); $this->entityManager->flush(); diff --git a/bundle/Core/Mailer/Mailing.php b/bundle/Core/Mailer/Mailing.php index 116210b..fbeaefa 100644 --- a/bundle/Core/Mailer/Mailing.php +++ b/bundle/Core/Mailer/Mailing.php @@ -1,43 +1,33 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Mailer; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Mailer; -use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Provider\Broadcast; -use Novactive\Bundle\eZMailingBundle\Core\Provider\MailingContent; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing as MailingEntity; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\Broadcast; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\MailingContent; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing as MailingEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Message; /** - * Class Mailing. + * Class MailingRepository. */ class Mailing { public function __construct( - private readonly Simple $simpleMailer, - private readonly MailingContent $contentProvider, - private readonly LoggerInterface $logger, - private readonly Broadcast $broadcastProvider, - private readonly EntityManagerInterface $entityManager, - private readonly MailerInterface $mailer, - private readonly string $mailing - ) - { + private readonly Simple $simpleMailer, + private readonly MailingContent $contentProvider, + private readonly LoggerInterface $logger, + private readonly Broadcast $broadcastProvider, + private readonly MailerInterface $mailer, + private readonly string $mailing, + private readonly UserRepository $userRepository, + private readonly MailingProcess $mailingProcess + ) { } public function sendMailing(MailingEntity $mailing, string $forceRecipient = null): void @@ -46,31 +36,31 @@ public function sendMailing(MailingEntity $mailing, string $forceRecipient = nul $broadcast = $this->broadcastProvider->start($mailing, $nativeHtml); $this->simpleMailer->sendStartSendingMailingMessage($mailing); + if ($forceRecipient) { $fakeUser = new User(); $fakeUser->setEmail($forceRecipient); $fakeUser->setFirstName('XXXX'); $fakeUser->setLastName('YYYY'); $contentMessage = $this->contentProvider->getContentMailing($mailing, $fakeUser, $broadcast); - $this->logger->debug("Mailing Mailer starts to test {$contentMessage->getSubject()}."); + $this->logger->debug("MailingRepository Mailer starts to test {$contentMessage->getSubject()}."); $this->sendMessage($contentMessage); - } else { + } elseif (!$forceRecipient) { $campaign = $mailing->getCampaign(); - $this->logger->notice("Mailing Mailer starts to send Mailing {$mailing->getName()}"); + $this->logger->notice("MailingRepository Mailer starts to send Mailing {$mailing->getName()}"); $recipientCounts = 0; - $userRepo = $this->entityManager->getRepository(User::class); - $recipients = $userRepo->findValidRecipients($campaign->getMailingLists()); - foreach ($recipients as $user) { - /** @var User $user */ - $contentMessage = $this->contentProvider->getContentMailing($mailing, $user, $broadcast); - $this->sendMessage($contentMessage); - ++$recipientCounts; + $recipients = $this->userRepository->findValidRecipients($campaign->getMailingLists()->toArray()); + + $this->mailingProcess->runParallelProcess($broadcast->getId(), $this->fetchIterationFromUserList($recipients, 10)); + + // send copy of email + $fakeUser = new User(); + $fakeUser->setEmail($mailing->getCampaign()->getReportEmail()); + $fakeUser->setFirstName('XXXX'); + $fakeUser->setLastName('YYYY'); + $contentMessage = $this->contentProvider->getContentMailing($mailing, $fakeUser, $broadcast); + $this->sendMessage($contentMessage); - if (0 === $recipientCounts % 10) { - $broadcast->setEmailSentCount($recipientCounts); - $this->broadcastProvider->store($broadcast); - } - } $this->broadcastProvider->store($broadcast); $this->logger->notice("Mailing {$mailing->getName()} induced {$recipientCounts} emails sent."); } @@ -78,9 +68,34 @@ public function sendMailing(MailingEntity $mailing, string $forceRecipient = nul $this->broadcastProvider->end($broadcast); } - private function sendMessage(Message $message): void + public function sendMessage(Message $message): void { $message->getHeaders()->addTextHeader('X-Transport', $this->mailing); $this->mailer->send($message); } + + /** + * @param array $users + */ + private function fetchIterationFromUserList(array $users, int $iterationCount): \Generator + { + do { + $usersId = []; + + foreach ($users as $key => $user) { + $usersId[] = $user->getId(); + unset($users[$key]); + + if (\count($usersId) === $iterationCount) { + $data = $usersId; + $usersId = []; + yield $data; + } + } + + if (!empty($usersId)) { + yield $usersId; + } + } while (!empty($users)); + } } diff --git a/bundle/Core/Mailer/MailingProcess.php b/bundle/Core/Mailer/MailingProcess.php new file mode 100644 index 0000000..e6c192b --- /dev/null +++ b/bundle/Core/Mailer/MailingProcess.php @@ -0,0 +1,132 @@ +getNumberOfCPUCores() - 1, null); + do { + /** @var \Symfony\Component\Process\Process $process */ + foreach ($processes as $key => $process) { + if ($process !== null && $process->isRunning()) { + continue; + } + + if ($process !== null) { + // One of the processes just finished, so we increment progress bar + + if (!$process->isSuccessful()) { + $this->logger->error( + sprintf( + 'Child indexer process returned: %s - %s', + $process->getExitCodeText(), + $process->getErrorOutput() + ) + ); + } + } + + if (!$generator->valid()) { + unset($processes[$key]); + continue; + } + + $processes[$key] = $this->getPhpProcess($broadcastId, $generator->current()); + $processes[$key]->start(); + $generator->next(); + } + + if (!empty($processes)) { + sleep(1); + } + } while (!empty($processes)); + } + + /** + * @param array $usersId + */ + private function getPhpProcess(int $broadcastId, array $usersId): Process + { + if (empty($usersId)) { + throw new InvalidArgumentException('--users-id', '$usersId cannot be empty'); + } + + $consolePath = file_exists(sprintf('%s/bin/console', $this->projectDir)) ? sprintf('%s/bin/console', $this->projectDir) : sprintf('%s/app/console', $this->projectDir); + $subProcessArgs = [ + $this->getPhpPath(), + $consolePath, + 'ibexamailing:send:mailing-subprocess', + '--broadcast-id='.$broadcastId, + '--users-id='.implode(',', $usersId), + '--env='.$this->kernelEnv, + ]; + + $process = new Process($subProcessArgs); + $process->setTimeout(null); + + return $process; + } + + private function getPhpPath(): string + { + if ($this->phpPath) { + return $this->phpPath; + } + + $phpFinder = new PhpExecutableFinder(); + $this->phpPath = $phpFinder->find(); + if (!$this->phpPath) { + throw new \RuntimeException('The php executable could not be found. It is needed for executing parallel subprocesses, so add it to your PATH environment variable and try again'); + } + + return $this->phpPath; + } + + /** + * @return int + */ + private function getNumberOfCPUCores() + { + $cores = 1; + if (is_file('/proc/cpuinfo')) { + // Linux (and potentially Windows with linux sub systems) + $cpuinfo = file_get_contents('/proc/cpuinfo'); + preg_match_all('/^processor/m', $cpuinfo, $matches); + $cores = \count($matches[0]); + } elseif (\DIRECTORY_SEPARATOR === '\\') { + // Windows + if (($process = @popen('wmic cpu get NumberOfCores', 'rb')) !== false) { + fgets($process); + $cores = (int) fgets($process); + pclose($process); + } + } elseif (($process = @popen('sysctl -a', 'rb')) !== false) { + // *nix (Linux, BSD and Mac) + $output = stream_get_contents($process); + if (preg_match('/hw.ncpu: (\d+)/', $output, $matches)) { + $cores = (int) $matches[1][0]; + } + pclose($process); + } + + return $cores; + } +} diff --git a/bundle/Core/Mailer/Simple.php b/bundle/Core/Mailer/Simple.php index 3c53db1..cda8a1b 100644 --- a/bundle/Core/Mailer/Simple.php +++ b/bundle/Core/Mailer/Simple.php @@ -1,36 +1,26 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Mailer; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Mailer; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Registration; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Unregistration; -use Novactive\Bundle\eZMailingBundle\Core\Provider\MessageContent; -use Novactive\Bundle\eZMailingBundle\Entity\ConfirmationToken; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing as MailingEntity; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Registration; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Unregistration; +use CodeRhapsodie\IbexaMailingBundle\Core\Provider\MessageContent; +use CodeRhapsodie\IbexaMailingBundle\Entity\ConfirmationToken; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing as MailingEntity; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Message; class Simple { - public function __construct(private readonly MessageContent $messageProvider, - private readonly LoggerInterface $logger, - private readonly MailerInterface $mailer, - private readonly string $simpleMailer - ) - { + public function __construct( + private readonly MessageContent $messageProvider, + private readonly LoggerInterface $logger, + private readonly MailerInterface $mailer, + private readonly string $simpleMailer + ) { } public function sendStartSendingMailingMessage(MailingEntity $mailing): void @@ -59,7 +49,7 @@ public function sendUnregistrationConfirmation(Unregistration $unregistration, C private function sendMessage(Message $message): void { - $this->logger->debug("Simple Mailer sends {$message->getSubject()}."); + $this->logger->debug("Simple Mailer sends {$message->getHeaders()->get('subject')->getBody()}."); $message->getHeaders()->addTextHeader('X-Transport', $this->simpleMailer); $this->mailer->send($message); diff --git a/bundle/Core/Modifier/ModifierInterface.php b/bundle/Core/Modifier/ModifierInterface.php index 20a313b..96bff7f 100644 --- a/bundle/Core/Modifier/ModifierInterface.php +++ b/bundle/Core/Modifier/ModifierInterface.php @@ -1,23 +1,16 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Modifier; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Modifier; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; interface ModifierInterface { + /** + * @param array $options + */ public function modify(Mailing $mailing, User $user, string $html, array $options = []): string; } diff --git a/bundle/Core/Modifier/Packer.php b/bundle/Core/Modifier/Packer.php index c54892e..4facd8d 100644 --- a/bundle/Core/Modifier/Packer.php +++ b/bundle/Core/Modifier/Packer.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Modifier; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Modifier; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; class Packer implements ModifierInterface { diff --git a/bundle/Core/Modifier/Personalization.php b/bundle/Core/Modifier/Personalization.php index 6aa3b5d..752c27a 100644 --- a/bundle/Core/Modifier/Personalization.php +++ b/bundle/Core/Modifier/Personalization.php @@ -1,23 +1,13 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Modifier; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Modifier; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; -class Personalization +class Personalization implements ModifierInterface { public function modify(Mailing $mailing, User $user, string $html, array $options = []): string { diff --git a/bundle/Core/Modifier/Tracking.php b/bundle/Core/Modifier/Tracking.php index c7aa8b8..915f234 100644 --- a/bundle/Core/Modifier/Tracking.php +++ b/bundle/Core/Modifier/Tracking.php @@ -1,44 +1,28 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Modifier; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Modifier; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; class Tracking implements ModifierInterface { - /** - * @var - */ - private $router; - - public function __construct(RouterInterface $router) + public function __construct(private readonly RouterInterface $router) { - $this->router = $router; } public function modify(Mailing $mailing, User $user, string $html, array $options = []): string { /** @var Broadcast $broadcast */ $broadcast = $options['broadcast']; - $uniqId = uniqid('novaezmailing-', true); + $uniqId = uniqid('ibexamailing-', true); $readUrl = $this->router->generate( - 'novaezmailing_t_read', + 'ibexamailing_t_read', [ 'salt' => $uniqId, 'broadcastId' => $broadcast->getId(), @@ -54,11 +38,11 @@ public function modify(Mailing $mailing, User $user, string $html, array $option '/]*)href="http(s)?(.[^"]*)"/uimx', function ($aInput) use ($uniqId, $broadcast, $mailing) { $continueUrl = $this->router->generate( - 'novaezmailing_t_continue', + 'ibexamailing_t_continue', [ 'salt' => str_replace('.', '', $uniqId), 'broadcastId' => $broadcast->getId(), - 'url' => str_replace(['+', '/'], ['-', '_'], base64_encode('http' . trim($aInput[1]) . trim($aInput[2]) . trim($aInput[3]))), + 'url' => str_replace(['+', '/'], ['-', '_'], base64_encode('http'.trim($aInput[1]).trim($aInput[2]).trim($aInput[3]))), 'siteaccess' => $mailing->getSiteAccess(), ], UrlGeneratorInterface::ABSOLUTE_URL diff --git a/bundle/Core/Modifier/Unregistration.php b/bundle/Core/Modifier/Unregistration.php index 418da76..14a4099 100644 --- a/bundle/Core/Modifier/Unregistration.php +++ b/bundle/Core/Modifier/Unregistration.php @@ -1,40 +1,24 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Modifier; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Modifier; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; -class Unregistration +class Unregistration implements ModifierInterface { - /** - * @var - */ - private $router; - - public function __construct(RouterInterface $router) + public function __construct(private readonly RouterInterface $router) { - $this->router = $router; } public function modify(Mailing $mailing, User $user, string $html, array $options = []): string { $url = $this->router->generate( - 'novaezmailing_registration_remove', + 'ibexamailing_registration_remove', [ 'email' => $user->getEmail(), 'siteaccess' => $mailing->getSiteAccess(), diff --git a/bundle/Core/Processor/Processor.php b/bundle/Core/Processor/Processor.php index e232975..bd631bb 100644 --- a/bundle/Core/Processor/Processor.php +++ b/bundle/Core/Processor/Processor.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Processor; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Processor; use Psr\Log\LoggerInterface; diff --git a/bundle/Core/Processor/SendMailing.php b/bundle/Core/Processor/SendMailing.php index 45187a8..d81ca02 100644 --- a/bundle/Core/Processor/SendMailing.php +++ b/bundle/Core/Processor/SendMailing.php @@ -1,58 +1,30 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Processor; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Processor; use Carbon\Carbon; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\Mailer\Mailing as MailingMailer; +use CodeRhapsodie\IbexaMailingBundle\Core\Utils\Clock; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Core\Mailer\Mailing as MailingMailer; -use Novactive\Bundle\eZMailingBundle\Core\Utils\Clock; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; use Symfony\Component\Workflow\Registry; class SendMailing extends Processor implements SendMailingProcessorInterface { - /** - * @var EntityManagerInterface - */ - private $entityManager; - - /** - * @var MailingMailer - */ - private $mailingMailer; - - /** - * @var Registry - */ - private $workflows; - public function __construct( - EntityManagerInterface $entityManager, - MailingMailer $mailingMailer, - Registry $workflows + private readonly EntityManagerInterface $entityManager, + private readonly MailingMailer $mailingMailer, + private readonly Registry $workflows, + private readonly MailingRepository $mailingRepository ) { - $this->entityManager = $entityManager; - $this->mailingMailer = $mailingMailer; - $this->workflows = $workflows; } - public function execute(?DateTime $overrideDatetime = null): void + public function execute(\DateTime $overrideDatetime = null): void { - $mailingRepository = $this->entityManager->getRepository(Mailing::class); - $pendingMailings = $mailingRepository->findByStatus(Mailing::PENDING); + $pendingMailings = $this->mailingRepository->findBy(['status' => Mailing::PENDING]); $clockDate = $overrideDatetime ?? Carbon::now(); $clock = new Clock($clockDate); $matched = $sent = 0; @@ -62,10 +34,10 @@ public function execute(?DateTime $overrideDatetime = null): void ++$matched; $this->logger->notice("{$mailing->getName()} has been matched pending and ready to be send."); if ( - null !== $mailing->getLastSent() && - $mailing->getLastSent()->format('Y-m-d-H') === $clockDate->format('Y-m-d-H') + $mailing->getLastSent() !== null + && $mailing->getLastSent()->format('Y-m-d-H') === $clockDate->format('Y-m-d-H') ) { - //Security here, if is has been sent during this current hour already, do nothing + // Security here, if is has been sent during this current hour already, do nothing $this->logger->debug( "{$mailing->getName()} has been matched and IGNORED. It has been sent during this hour already." ); diff --git a/bundle/Core/Processor/SendMailingProcessorInterface.php b/bundle/Core/Processor/SendMailingProcessorInterface.php index 416e3c5..8ae40a1 100644 --- a/bundle/Core/Processor/SendMailingProcessorInterface.php +++ b/bundle/Core/Processor/SendMailingProcessorInterface.php @@ -1,22 +1,10 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Processor; - -use DateTime; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Processor; interface SendMailingProcessorInterface { - public function execute(?DateTime $overrideDatetime = null): void; + public function execute(\DateTime $overrideDatetime = null): void; } diff --git a/bundle/Core/Processor/TestMailing.php b/bundle/Core/Processor/TestMailing.php index 628cf17..e678d4e 100644 --- a/bundle/Core/Processor/TestMailing.php +++ b/bundle/Core/Processor/TestMailing.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Processor; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Processor; -use Novactive\Bundle\eZMailingBundle\Core\Mailer\Mailing as MailingMailer; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Core\Mailer\Mailing as MailingMailer; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; class TestMailing extends Processor implements TestMailingProcessorInterface { diff --git a/bundle/Core/Processor/TestMailingProcessorInterface.php b/bundle/Core/Processor/TestMailingProcessorInterface.php index 6da75af..e6c2303 100644 --- a/bundle/Core/Processor/TestMailingProcessorInterface.php +++ b/bundle/Core/Processor/TestMailingProcessorInterface.php @@ -1,20 +1,10 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Processor; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Processor; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; interface TestMailingProcessorInterface { diff --git a/bundle/Core/Provider/Broadcast.php b/bundle/Core/Provider/Broadcast.php index 863b1ab..fc74f9b 100644 --- a/bundle/Core/Provider/Broadcast.php +++ b/bundle/Core/Provider/Broadcast.php @@ -1,35 +1,19 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Provider; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Provider; use Carbon\Carbon; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast as BroadcastEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use Doctrine\DBAL\ParameterType; use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast as BroadcastEntity; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; class Broadcast { - /** - * @var EntityManagerInterface - */ - private $entityManager; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private readonly EntityManagerInterface $entityManager) { - $this->entityManager = $entityManager; } public function start(Mailing $mailing, string $html): BroadcastEntity @@ -39,12 +23,24 @@ public function start(Mailing $mailing, string $html): BroadcastEntity ->setMailing($mailing) ->setStarted(Carbon::now()) ->setHtml($html) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $this->store($broadcast); return $broadcast; } + public function increment(int $broadcastId, int $increment = 1): void + { + $this->entityManager->createQueryBuilder() + ->update(BroadcastEntity::class, 'b') + ->set('b.emailSentCount', 'b.emailSentCount + :increment') + ->where('b.id = :id') + ->setParameter('id', $broadcastId) + ->setParameter('increment', $increment, ParameterType::INTEGER) + ->getQuery() + ->execute(); + } + public function end(BroadcastEntity $broadcast): void { $broadcast->setEnded(Carbon::now()); diff --git a/bundle/Core/Provider/MailingContent.php b/bundle/Core/Provider/MailingContent.php index 5a0e732..7ac0b6d 100644 --- a/bundle/Core/Provider/MailingContent.php +++ b/bundle/Core/Provider/MailingContent.php @@ -1,26 +1,17 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Provider; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Provider; -use App\Kernel; -use Novactive\Bundle\eZMailingBundle\Core\Modifier\ModifierInterface; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast as BroadcastEntity; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User as UserEntity; +use CodeRhapsodie\IbexaMailingBundle\Core\Modifier\ModifierInterface; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast as BroadcastEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\User as UserEntity; +use Ibexa\Core\MVC\Symfony\SiteAccess\Router; use Symfony\Bridge\Twig\Mime\TemplatedEmail; -use Symfony\Component\HttpKernel\HttpKernelBrowser; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -29,37 +20,23 @@ class MailingContent { /** - * @var array + * @var array */ protected $nativeContent; - /** - * @var ModifierInterface[] - */ - protected $modifiers; - - /** - * @var RouterInterface - */ - protected $router; - /** * MailingContent constructor. * * @param ModifierInterface[] $modifiers */ - public function __construct(iterable $modifiers, RouterInterface $router, private readonly string $kernelEnv) + public function __construct(protected readonly iterable $modifiers, protected readonly RouterInterface $router, private readonly HttpKernelInterface $httpKernel, private readonly Router $ibexaRouter) { - $this->modifiers = $modifiers; - $this->router = $router; } public function preFetchContent(Mailing $mailing): string { - $kernel = new Kernel($this->kernelEnv, false); - $client = new HttpKernelBrowser($kernel); $url = $this->router->generate( - '_novaezmailing_ez_content_view', + '_ibexamailing_ez_content_view', [ 'locationId' => $mailing->getLocation()->id, 'contentId' => $mailing->getContent()->id, @@ -68,29 +45,21 @@ public function preFetchContent(Mailing $mailing): string ], UrlGeneratorInterface::ABSOLUTE_URL ); - - $crawler = $client->request('/GET', $url); - $this->nativeContent[$mailing->getLocationId()] = "{$crawler->html()}"; - - return $this->nativeContent[$mailing->getLocationId()]; - } - - private function getNativeContent(Mailing $mailing): string - { - if (!isset($this->nativeContent[$mailing->getLocationId()])) { - $this->preFetchContent($mailing); - } + $request = Request::create($url); + $request->attributes->set('siteaccess', $this->ibexaRouter->matchByName($mailing->getSiteAccess())); + $response = $this->httpKernel->handle($request); + $this->nativeContent[$mailing->getLocationId()] = $response->getContent(); return $this->nativeContent[$mailing->getLocationId()]; } public function getContentMailing( - Mailing $mailing, - UserEntity $recipient, + Mailing $mailing, + UserEntity $recipient, BroadcastEntity $broadcast - ): Email - { + ): Email { $html = $this->getNativeContent($mailing); + foreach ($this->modifiers as $modifier) { $html = $modifier->modify($mailing, $recipient, $html, ['broadcast' => $broadcast]); } @@ -100,11 +69,19 @@ public function getContentMailing( $campaign = $mailing->getCampaign(); $message->from(new Address($campaign->getSenderEmail(), $campaign->getSenderName())); $message->to($recipient->getEmail()); - $message->bcc($campaign->getReportEmail()); if (!empty($campaign->getReturnPathEmail())) { $message->returnPath($campaign->getReturnPathEmail()); } return $message; } + + public function getNativeContent(Mailing $mailing): string + { + if (!isset($this->nativeContent[$mailing->getLocationId()])) { + $this->preFetchContent($mailing); + } + + return $this->nativeContent[$mailing->getLocationId()]; + } } diff --git a/bundle/Core/Provider/MessageContent.php b/bundle/Core/Provider/MessageContent.php index 049f224..ffd8b8f 100644 --- a/bundle/Core/Provider/MessageContent.php +++ b/bundle/Core/Provider/MessageContent.php @@ -1,85 +1,35 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Provider; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Provider; -use Ibexa\Bundle\Core\DependencyInjection\Configuration\ConfigResolver; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Registration; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Unregistration; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\ConfirmationToken; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Registration; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Unregistration; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\ConfirmationToken; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use RuntimeException; use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\Mime\Address; use Symfony\Contracts\Translation\TranslatorInterface; class MessageContent { - /** - * @var ConfigResolver - */ - private $configResolver; - - /** - * @var TranslatorInterface - */ - private $translator; - public function __construct( - ConfigResolverInterface $configResolver, - TranslatorInterface $translator - ) - { - $this->configResolver = $configResolver; - $this->translator = $translator; - } - - private function createMessage(string $subject, ?Campaign $campaign = null): TemplatedEmail - { - $prefix = $this->configResolver->getParameter('email_subject_prefix', 'nova_ezmailing'); - $message = new TemplatedEmail(); - $message->subject("{$prefix} {$subject}"); - if (null !== $campaign) { - $message->from(new Address($campaign->getSenderEmail(), $campaign->getSenderName())); - if (!empty($campaign->getReturnPathEmail())) { - $message->returnPath($campaign->getReturnPathEmail()); - } - - return $message; - } - $message->from( - new Address( - $this->configResolver->getParameter('email_from_address', 'nova_ezmailing'), - $this->configResolver->getParameter('email_from_name', 'nova_ezmailing') - ) - ); - if (!empty($this->configResolver->getParameter('email_return_path', 'nova_ezmailing'))) { - $message->returnPath($this->configResolver->getParameter('email_return_path', 'nova_ezmailing')); - } - return $message; + private readonly ConfigResolverInterface $configResolver, + private readonly TranslatorInterface $translator + ) { } public function getStartSendingMailing(Mailing $mailing): TemplatedEmail { - $translated = $this->translator->trans('messages.start_sending.being_sent3', [], 'ezmailing'); + $translated = $this->translator->trans('messages.start_sending.being_sent3', [], 'ibexamailing'); $message = $this->createMessage($translated, $mailing->getCampaign()); $campaign = $mailing->getCampaign(); $message->to($campaign->getReportEmail()); - $message->htmlTemplate('@NovaeZMailing/messages/startsending.html.twig'); + $message->htmlTemplate('@IbexaMailing/messages/startsending.html.twig'); $message->context(['item' => $mailing]); return $message; @@ -87,12 +37,12 @@ public function getStartSendingMailing(Mailing $mailing): TemplatedEmail public function getStopSendingMailing(Mailing $mailing): TemplatedEmail { - $translated = $this->translator->trans('messages.stop_sending.sent3', [], 'ezmailing'); + $translated = $this->translator->trans('messages.stop_sending.sent3', [], 'ibexamailing'); $message = $this->createMessage($translated, $mailing->getCampaign()); $campaign = $mailing->getCampaign(); $message->to($campaign->getReportEmail()); - $message->htmlTemplate('@NovaeZMailing/messages/stopsending.html.twig'); + $message->htmlTemplate('@IbexaMailing/messages/stopsending.html.twig'); $message->context(['item' => $mailing]); return $message; @@ -100,14 +50,14 @@ public function getStopSendingMailing(Mailing $mailing): TemplatedEmail public function getRegistrationConfirmation(Registration $registration, ConfirmationToken $token): TemplatedEmail { - $translated = $this->translator->trans('messages.confirm_registration.confirm', [], 'ezmailing'); + $translated = $this->translator->trans('messages.confirm_registration.confirm', [], 'ibexamailing'); $message = $this->createMessage($translated); $user = $registration->getUser(); - if (null === $user) { - throw new RuntimeException('User cannot be empty.'); + if ($user === null) { + throw new \RuntimeException('UserRepository cannot be empty.'); } $message->to($user->getEmail()); - $message->htmlTemplate('@NovaeZMailing/messages/confirmregistration.html.twig'); + $message->htmlTemplate('@IbexaMailing/messages/confirmregistration.html.twig'); $message->context([ 'registration' => $registration, 'token' => $token, @@ -117,18 +67,17 @@ public function getRegistrationConfirmation(Registration $registration, Confirma } public function getUnregistrationConfirmation( - Unregistration $unregistration, + Unregistration $unregistration, ConfirmationToken $token - ): TemplatedEmail - { - $translated = $this->translator->trans('messages.confirm_unregistration.confirmation', [], 'ezmailing'); + ): TemplatedEmail { + $translated = $this->translator->trans('messages.confirm_unregistration.confirmation', [], 'ibexamailing'); $message = $this->createMessage($translated); $user = $unregistration->getUser(); - if (null === $user) { - throw new RuntimeException('User cannot be empty.'); + if ($user === null) { + throw new \RuntimeException('UserRepository cannot be empty.'); } $message->to($user->getEmail()); - $message->htmlTemplate('@NovaeZMailing/messages/confirmunregistration.html.twig'); + $message->htmlTemplate('@IbexaMailing/messages/confirmunregistration.html.twig'); $message->context([ 'unregistration' => $unregistration, 'token' => $token, @@ -136,4 +85,30 @@ public function getUnregistrationConfirmation( return $message; } + + private function createMessage(string $subject, Campaign $campaign = null): TemplatedEmail + { + $prefix = $this->configResolver->getParameter('email_subject_prefix', 'ibexamailing'); + $message = new TemplatedEmail(); + $message->subject("{$prefix} {$subject}"); + if ($campaign !== null) { + $message->from(new Address($campaign->getSenderEmail(), $campaign->getSenderName())); + if (!empty($campaign->getReturnPathEmail())) { + $message->returnPath($campaign->getReturnPathEmail()); + } + + return $message; + } + $message->from( + new Address( + $this->configResolver->getParameter('email_from_address', 'ibexamailing'), + $this->configResolver->getParameter('email_from_name', 'ibexamailing') + ) + ); + if (!empty($this->configResolver->getParameter('email_return_path', 'ibexamailing'))) { + $message->returnPath($this->configResolver->getParameter('email_return_path', 'ibexamailing')); + } + + return $message; + } } diff --git a/bundle/Core/Provider/User.php b/bundle/Core/Provider/User.php index e2f1ce8..f3a4260 100644 --- a/bundle/Core/Provider/User.php +++ b/bundle/Core/Provider/User.php @@ -1,40 +1,28 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Provider; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Provider; -use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Entity\User as UserEntity; -use Pagerfanta\Adapter\DoctrineORMAdapter; +use CodeRhapsodie\IbexaMailingBundle\Entity\User as UserEntity; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; +use Pagerfanta\Doctrine\ORM\QueryAdapter; use Pagerfanta\Pagerfanta; class User { - /** - * @var EntityManagerInterface - */ - private $entityManager; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private readonly UserRepository $userRepository) { - $this->entityManager = $entityManager; } + /** + * @param array $filters + * + * @return Pagerfanta<\CodeRhapsodie\IbexaMailingBundle\Entity\User> + */ public function getPagerFilters(array $filters = [], int $page = 1, int $limit = 25): Pagerfanta { - $repo = $this->entityManager->getRepository(UserEntity::class); - $adapter = new DoctrineORMAdapter($repo->createQueryBuilderForFilters($filters)); + $adapter = new QueryAdapter($this->userRepository->createQueryBuilderForFilters($filters)); $pager = new Pagerfanta($adapter); $pager->setMaxPerPage($limit); $pager->setCurrentPage($page); @@ -42,14 +30,18 @@ public function getPagerFilters(array $filters = [], int $page = 1, int $limit = return $pager; } + /** + * @param array $filters + * + * @return array + */ public function getStatusesData(array $filters = []): array { unset($filters['status']); - $repo = $this->entityManager->getRepository(UserEntity::class); $total = 0; $statuses = []; foreach (UserEntity::STATUSES as $status) { - $statuses[$status] = $repo->countByFilters($filters + ['status' => $status]); + $statuses[$status] = $this->userRepository->countByFilters($filters + ['status' => $status]); $total += $statuses[$status]; } diff --git a/bundle/Core/Registrar.php b/bundle/Core/Registrar.php index d385a60..a020513 100644 --- a/bundle/Core/Registrar.php +++ b/bundle/Core/Registrar.php @@ -1,34 +1,25 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core; +namespace CodeRhapsodie\IbexaMailingBundle\Core; use Carbon\Carbon; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Registration; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\Unregistration; +use CodeRhapsodie\IbexaMailingBundle\Core\Mailer\Simple as SimpleMailer; +use CodeRhapsodie\IbexaMailingBundle\Entity\ConfirmationToken; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration as RegistrationEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Repository\ConfirmationTokenRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingListRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityManagerInterface; -use Ibexa\Bundle\Core\DependencyInjection\Configuration\ConfigResolver; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; use Ibexa\Core\MVC\Symfony\SiteAccess; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Registration; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\Unregistration; -use Novactive\Bundle\eZMailingBundle\Core\Mailer\Simple as SimpleMailer; -use Novactive\Bundle\eZMailingBundle\Entity\ConfirmationToken; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\Registration as RegistrationEntity; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use RuntimeException; class Registrar { @@ -37,47 +28,25 @@ class Registrar */ public const TOKEN_EXPIRATION_HOURS = 5; - /** - * @var EntityManagerInterface - */ - private $entityManager; - - /** - * @var SiteAccess - */ - private $siteAccess; - - /** - * @var SimpleMailer - */ - private $mailer; - - /** - * @var ConfigResolver - */ - protected $configResolver; - public function __construct( - EntityManagerInterface $entityManager, - SiteAccess $siteAccess, - SimpleMailer $mailer, - ConfigResolverInterface $configResolver, - ) - { - $this->entityManager = $entityManager; - $this->siteAccess = $siteAccess; - $this->mailer = $mailer; - $this->configResolver = $configResolver; + private readonly EntityManagerInterface $entityManager, + private readonly SiteAccess $siteAccess, + private readonly SimpleMailer $mailer, + protected readonly ConfigResolverInterface $configResolver, + private readonly UserRepository $userRepository, + private readonly MailingListRepository $mailingListRepository, + private readonly ConfirmationTokenRepository $confirmationTokenRepository + ) { } public function askForConfirmation(Registration $registration): void { $user = $registration->getUser(); - if (null === $user) { - throw new RuntimeException('User cannot be empty.'); + if ($user === null) { + throw new \RuntimeException('UserRepository cannot be empty.'); } - $userRepo = $this->entityManager->getRepository(User::class); - $fetchUser = $userRepo->findOneByEmail($user->getEmail()); + + $fetchUser = $this->userRepository->findOneBy(['email' => $user->getEmail()]); if (!$fetchUser instanceof User) { $user->setStatus(User::PENDING); @@ -98,11 +67,10 @@ public function askForConfirmation(Registration $registration): void public function askForUnregisterConfirmation(Unregistration $unregistration): bool { $user = $unregistration->getUser(); - if (null === $user) { - throw new RuntimeException('User cannot be empty.'); + if ($user === null) { + throw new \RuntimeException('UserRepository cannot be empty.'); } - $userRepo = $this->entityManager->getRepository(User::class); - $fetchUser = $userRepo->findOneByEmail($user->getEmail()); + $fetchUser = $this->userRepository->findOneBy(['email' => $user->getEmail()]); if (!$fetchUser instanceof User) { return false; @@ -120,39 +88,7 @@ public function askForUnregisterConfirmation(Unregistration $unregistration): bo } /** - * @param array|ArrayCollection $mailingLists - */ - private function createConfirmationToken( - string $action, - User $user, - mixed $mailingLists - ): ConfirmationToken - { - if ($mailingLists instanceof ArrayCollection) { - $mailingLists = $mailingLists->toArray(); - } - /** @var ArrayCollection $mailingListIds */ - $mailingListIds = array_map(function (MailingList $mailingList) { - return $mailingList->getId(); - }, $mailingLists); - - $confirmationToken = new ConfirmationToken(); - $confirmationToken->setPayload( - [ - 'action' => $action, - 'userId' => $user->getId(), - 'mailingListIds' => $mailingListIds, - ] - ); - $this->entityManager->persist($confirmationToken); - $this->entityManager->flush(); - - return $confirmationToken; - } - - /** - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.UndefinedVariable) + * @SuppressWarnings(PHPMD.ElseExpression) */ public function confirm(ConfirmationToken $token): bool { @@ -166,35 +102,12 @@ public function confirm(ConfirmationToken $token): bool if (!\in_array($action, [ConfirmationToken::REGISTER, ConfirmationToken::UNREGISTER])) { return false; } - $mailingListRepo = $this->entityManager->getRepository(MailingList::class); - $userRepo = $this->entityManager->getRepository(User::class); - $user = $userRepo->findOneById($userId); + $user = $this->userRepository->find($userId); if (!$user instanceof User) { return false; } - foreach ($mailingListIds as $id) { - $mailingList = $mailingListRepo->findOneById($id); - if (!$mailingList instanceof MailingList) { - continue; - } - - if (ConfirmationToken::REGISTER == $action) { - $registration = new RegistrationEntity(); - $registration->setApproved(!$mailingList->isWithApproval()); - $registration->setMailingList($mailingList); - $user->addRegistration($registration); - } - - if (ConfirmationToken::UNREGISTER == $action) { - $currentRegistrations = $user->getRegistrations(); - foreach ($currentRegistrations as $registration) { - if ($registration->getMailingList()->getId() === $id) { - $user->removeRegistration($registration); - } - } - } - } + $this->addMailingLists($mailingListIds, $action, $user); // in any case we can confirm the email here if ($user->isPending()) { @@ -202,8 +115,8 @@ public function confirm(ConfirmationToken $token): bool } // if no more registration then we remove the user - if (0 == $user->getRegistrations()->count()) { - if ($this->configResolver->getParameter('delete_user', 'nova_ezmailing')) { + if ($user->getRegistrations()->isEmpty()) { + if ($this->configResolver->getParameter('delete_user', 'ibexamailing')) { $this->entityManager->remove($user); } else { $user->setStatus(User::REMOVED); @@ -217,14 +130,13 @@ public function confirm(ConfirmationToken $token): bool } /** - * Clean the ConfirmationToken expired records. + * Clean the ConfirmationTokenRepository expired records. */ public function cleanup(): void { - $repo = $this->entityManager->getRepository(ConfirmationToken::class); $criteria = new Criteria(); $criteria->where(Criteria::expr()->lt('created', Carbon::now()->subHours(static::TOKEN_EXPIRATION_HOURS))); - $results = $repo->matching($criteria); + $results = $this->confirmationTokenRepository->matching($criteria); foreach ($results as $result) { $this->entityManager->remove($result); @@ -232,16 +144,76 @@ public function cleanup(): void $this->entityManager->flush(); } + /** + * @return ArrayCollection + */ public function getDefaultMailingList(): ArrayCollection { $mailingListId = null; - if ($this->configResolver->hasParameter('default_mailinglist_id', 'nova_ezmailing')) { - $mailingListId = $this->configResolver->getParameter('default_mailinglist_id', 'nova_ezmailing'); + if ($this->configResolver->hasParameter('default_mailinglist_id', 'ibexamailing')) { + $mailingListId = $this->configResolver->getParameter('default_mailinglist_id', 'ibexamailing'); } - $mailingList = $this->entityManager->getRepository(MailingList::class)->findOneBy( - ['id' => $mailingListId] - ); + $mailingList = $this->mailingListRepository->find($mailingListId); return new ArrayCollection([$mailingList]); } + + /** + * @param array|ArrayCollection $mailingLists + */ + private function createConfirmationToken( + string $action, + User $user, + mixed $mailingLists + ): ConfirmationToken { + if ($mailingLists instanceof ArrayCollection) { + $mailingLists = $mailingLists->toArray(); + } + /** @var array $mailingListIds */ + $mailingListIds = array_map(function (MailingList $mailingList) { + return $mailingList->getId(); + }, $mailingLists); + + $confirmationToken = new ConfirmationToken(); + $confirmationToken->setPayload( + [ + 'action' => $action, + 'userId' => $user->getId(), + 'mailingListIds' => $mailingListIds, + ] + ); + $this->entityManager->persist($confirmationToken); + $this->entityManager->flush(); + + return $confirmationToken; + } + + /** + * @param array $mailingListIds + */ + private function addMailingLists(array $mailingListIds, string $action, User $user): void + { + foreach ($mailingListIds as $id) { + $mailingList = $this->mailingListRepository->find($id); + if (!$mailingList instanceof MailingList) { + continue; + } + + if ($action == ConfirmationToken::REGISTER) { + $registration = new RegistrationEntity(); + $registration->setApproved(!$mailingList->isWithApproval()); + $registration->setMailingList($mailingList); + $user->addRegistration($registration); + } + + if ($action == ConfirmationToken::UNREGISTER) { + $currentRegistrations = $user->getRegistrations(); + foreach ($currentRegistrations as $registration) { + if ($registration->getMailingList()->getId() === $id) { + $user->removeRegistration($registration); + } + } + } + } + } } diff --git a/bundle/Core/Tab/Campaigns.php b/bundle/Core/Tab/Campaigns.php index 7262e8a..6889a10 100644 --- a/bundle/Core/Tab/Campaigns.php +++ b/bundle/Core/Tab/Campaigns.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Tab; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Tab; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign as CampaignEntity; use Ibexa\Contracts\AdminUi\Tab\AbstractTab; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign as CampaignEntity; class Campaigns extends AbstractTab { @@ -26,19 +16,24 @@ class Campaigns extends AbstractTab public function getIdentifier(): string { - return 'novaezmailing-campaign-tab'; + return 'ibexamailing-campaign-tab'; } public function getName(): string { - return /* @Desc("Nova eZ Mailing - Campaigns Tab") */ - $this->translator->trans('campaigns.tab.name', ['count' => count($this->campaigns)], 'ezmailing'); + return /* @Desc("Ibexa Mailing - Campaigns Tab") */ + $this->translator->trans('campaigns.tab.name', ['count' => \count($this->campaigns)], 'ibexamailing'); } + /** + * {@inheritdoc} + * + * @param array $parameters + */ public function renderView(array $parameters): string { return $this->twig->render( - '@NovaeZMailing/admin/tabs/campaigns.html.twig', + '@IbexaMailing/admin/tabs/campaigns.html.twig', [ 'items' => $this->campaigns, ] diff --git a/bundle/Core/Tab/Mailings.php b/bundle/Core/Tab/Mailings.php index 4f1c76c..96528a5 100644 --- a/bundle/Core/Tab/Mailings.php +++ b/bundle/Core/Tab/Mailings.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Tab; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Tab; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing as MailingEntity; use Ibexa\Contracts\AdminUi\Tab\AbstractTab; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing as MailingEntity; class Mailings extends AbstractTab { @@ -26,19 +16,24 @@ class Mailings extends AbstractTab public function getIdentifier(): string { - return 'novaezmailing-mailings-tab'; + return 'ibexamailing-mailings-tab'; } public function getName(): string { - return /* @Desc("Nova eZ Mailing - Mailings Tab") */ - $this->translator->trans('mailings.tab.name', ['count' => count($this->mailings)], 'ezmailing'); + return /* @Desc("Ibexa Mailing - Mailings Tab") */ + $this->translator->trans('mailings.tab.name', ['count' => \count($this->mailings)], 'ibexamailing'); } + /** + * {@inheritdoc} + * + * @param array $parameters + */ public function renderView(array $parameters): string { return $this->twig->render( - '@NovaeZMailing/admin/tabs/mailings.html.twig', + '@IbexaMailing/admin/tabs/mailings.html.twig', [ 'items' => $this->mailings, ] diff --git a/bundle/Core/Utils/Browser.php b/bundle/Core/Utils/Browser.php index 0330cbd..58aef93 100644 --- a/bundle/Core/Utils/Browser.php +++ b/bundle/Core/Utils/Browser.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Utils; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Utils; class Browser { @@ -36,77 +26,36 @@ class Browser */ private $platform; - /** - * @SuppressWarnings(PHPMD.NPathComplexity) - */ public function __construct(string $userAgent) { $bname = 'Unknown'; - $platform = 'Unknown'; - - // First get the platform - if (false !== stripos($userAgent, 'linux')) { - $platform = 'Linux'; - } elseif (preg_match('/macintosh|mac os x/i', $userAgent)) { - $platform = 'Mac'; - } elseif (preg_match('/windows|win32/i', $userAgent)) { - $platform = 'Windows'; - } + $userAgentBrand = 'Unknown'; // Next get the name of the useragent - if (false !== stripos($userAgent, 'MSIE') && !false !== stripos($userAgent, 'Opera')) { + if (stripos($userAgent, 'MSIE') !== false && stripos($userAgent, 'Opera') === false) { $bname = 'Internet Explorer'; $userAgentBrand = 'MSIE'; - } elseif (false !== stripos($userAgent, 'Firefox')) { + } elseif (stripos($userAgent, 'Firefox') !== false) { $bname = 'Mozilla Firefox'; $userAgentBrand = 'Firefox'; - } elseif (false !== stripos($userAgent, 'Chrome')) { + } elseif (stripos($userAgent, 'Chrome') !== false) { $bname = 'Google Chrome'; $userAgentBrand = 'Chrome'; - } elseif (false !== stripos($userAgent, 'Safari')) { + } elseif (stripos($userAgent, 'Safari') !== false) { $bname = 'Apple Safari'; $userAgentBrand = 'Safari'; - } elseif (false !== stripos($userAgent, 'Opera')) { + } elseif (stripos($userAgent, 'Opera') !== false) { $bname = 'Opera'; $userAgentBrand = 'Opera'; - } elseif (false !== stripos($userAgent, 'Netscape')) { + } elseif (stripos($userAgent, 'Netscape') !== false) { $bname = 'Netscape'; $userAgentBrand = 'Netscape'; } - // finally get the correct version number - $known = [ - 'Version', - $userAgentBrand, - 'other', - ]; - $matches = null; - $pattern = '#(?'.join('|', $known).')[/ ]+(?[0-9.|a-zA-Z.]*)#'; - preg_match_all($pattern, $userAgent, $matches); - - // see how many we have - $i = count($matches['browser']); - if (1 != $i) { - //we will have two since we are not using 'other' argument yet - //see if version is before or after the name - if (strripos($userAgent, 'Version') < strripos($userAgent, $userAgentBrand)) { - $version = $matches['version'][0]; - } else { - $version = $matches['version'][1]; - } - } else { - $version = $matches['version'][0]; - } - - // check if we have a number - if (null == $version || '' == $version) { - $version = '?'; - } - $this->userAgent = $userAgent; $this->name = $bname; - $this->version = $version; - $this->platform = $platform; + $this->version = $this->setVersion($userAgentBrand, $userAgent); + $this->platform = $this->setPlatform($userAgent); } public function getName(): string @@ -133,4 +82,56 @@ public function getVersion(): string { return $this->version; } + + private function setPlatform(string $userAgent): string + { + $platform = 'Unknown'; + // First get the platform + if (stripos($userAgent, 'linux') !== false) { + $platform = 'Linux'; + } elseif (preg_match('/macintosh|mac os x/i', $userAgent)) { + $platform = 'Mac'; + } elseif (preg_match('/windows|win32/i', $userAgent)) { + $platform = 'Windows'; + } + + return $platform; + } + + /** + * @SuppressWarnings(PHPMD.ElseExpression) + */ + private function setVersion(string $userAgentBrand, string $userAgent): string + { + // finally get the correct version number + $known = [ + 'Version', + $userAgentBrand, + 'other', + ]; + $matches = null; + $version = null; + $pattern = '#(?'.implode('|', $known).')[/ ]+(?[0-9.|a-zA-Z.]*)#'; + preg_match_all($pattern, $userAgent, $matches); + + // see how many we have + if (\count($matches['browser']) > 1) { + // we will have two since we are not using 'other' argument yet + // see if version is before or after the name + if (strripos($userAgent, 'Version') < strripos($userAgent, $userAgentBrand)) { + $version = $matches['version'][0]; + } else { + $version = $matches['version'][1]; + } + } elseif (!empty($matches['version'])) { + $version = $matches['version'][0]; + } + + // check if we have a number + if ($version == null || $version == '') { + $version = '?'; + } + + return $version; + } } diff --git a/bundle/Core/Utils/ChartDataBuilder.php b/bundle/Core/Utils/ChartDataBuilder.php index 80555f2..12e524e 100644 --- a/bundle/Core/Utils/ChartDataBuilder.php +++ b/bundle/Core/Utils/ChartDataBuilder.php @@ -1,46 +1,33 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Utils; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Utils; class ChartDataBuilder { - /** - * @var string - */ - private $title; + private string $title; /** - * @var array + * @var array */ - private $options; + private array $options; /** - * @var array + * @var array */ - private $dataSets; + private array $dataSets; + + private string $type; /** - * @var string + * @var array */ - private $type; + private array $colorsSets; /** - * @var array + * @param array $options */ - private $colorsSets; - public function __construct(string $title, string $type, array $options = []) { $this->title = $title; @@ -54,28 +41,9 @@ public function __construct(string $title, string $type, array $options = []) ]; } - public function addDataSet(array $data, array $labels, ?array $colors = null, ?string $type = null): self - { - if (null === $type) { - $this->dataSets[] = [ - 'data' => $data, - 'labels' => $labels, - 'colors' => $colors, - ]; - - return $this; - } - - $this->dataSets[] = [ - 'data' => $data, - 'labels' => $labels, - 'colors' => $colors, - 'type' => $type, - ]; - - return $this; - } - + /** + * @return array + */ public function __invoke(): array { $datasets = []; @@ -99,12 +67,11 @@ public function __invoke(): array $options['title']['display'] = true; $options['title']['text'] = $this->title; - if ('bar' === $this->type) { + if ($this->type === 'bar') { $options['legend'] = false; $options['scales']['y']['ticks'] = [ 'stepSize' => 1, 'beginAtZero' => true, - ]; $options['barThickness'] = 3; } @@ -118,4 +85,31 @@ public function __invoke(): array ], ]; } + + /** + * @param array $data + * @param array $labels + * @param array|null $colors + */ + public function addDataSet(array $data, array $labels, array $colors = null, string $type = null): self + { + if ($type === null) { + $this->dataSets[] = [ + 'data' => $data, + 'labels' => $labels, + 'colors' => $colors, + ]; + + return $this; + } + + $this->dataSets[] = [ + 'data' => $data, + 'labels' => $labels, + 'colors' => $colors, + 'type' => $type, + ]; + + return $this; + } } diff --git a/bundle/Core/Utils/Clock.php b/bundle/Core/Utils/Clock.php index 9822d8a..4569610 100644 --- a/bundle/Core/Utils/Clock.php +++ b/bundle/Core/Utils/Clock.php @@ -1,23 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Core\Utils; +namespace CodeRhapsodie\IbexaMailingBundle\Core\Utils; use Carbon\Carbon; -use DateTime; -use LogicException; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; class Clock { @@ -26,7 +14,7 @@ class Clock */ private $time; - public function __construct(DateTime $time) + public function __construct(\DateTime $time) { $this->time = Carbon::instance($time); } @@ -81,10 +69,10 @@ public function match(Mailing $mailing): bool foreach ($testMethods as $testMethodClock => $testMethodMailing) { $possibilities = $mailing->$testMethodMailing(); - $countPossibilities = count($possibilities); + $countPossibilities = \count($possibilities); if ( - 0 === $countPossibilities || - (1 === $countPossibilities && '' === $possibilities[0]) + $countPossibilities === 0 + || ($countPossibilities === 1 && $possibilities[0] === '') ) { // which means nothing then * continue; } @@ -96,7 +84,7 @@ public function match(Mailing $mailing): bool return true; } - public function nextTick(Mailing $mailing): DateTime + public function nextTick(Mailing $mailing): \DateTime { // Not sure that is great but it is a loop of 365 max, then might be the simplest and the best perf $now = $this->time; @@ -104,18 +92,18 @@ public function nextTick(Mailing $mailing): DateTime $hours = $mailing->getHoursOfDay(); for ($i = 0; $i < 365; ++$i) { - $testClock = new static($tick); + $testClock = new self($tick); if (!$testClock->match($mailing)) { // set the first hours - $tick->setTime((int) $hours[0], 0, 0); - $testClock = new static($tick); + $tick->setTime((int) $hours[0], 0); + $testClock = new self($tick); } if ($testClock->match($mailing)) { if ($tick->timestamp == $now->timestamp) { foreach ($hours as $hour) { if ($hour > $now->hour) { - $tick->setTime((int) $hour, 0, 0); + $tick->setTime((int) $hour, 0); return $tick; } @@ -123,12 +111,12 @@ public function nextTick(Mailing $mailing): DateTime $tick->addDay(); continue; } - $tick->setTime((int) $hours[0], 0, 0); + $tick->setTime((int) $hours[0], 0); return $tick; } $tick->addDay(); } - throw new LogicException("There is not next tick for Mailing {$mailing->getName()}"); + throw new \LogicException("There is not next tick for Mailing {$mailing->getName()}"); } } diff --git a/bundle/DataFixtures/CampaignFixtures.php b/bundle/DataFixtures/CampaignFixtures.php index 9ef49a2..2f687c6 100644 --- a/bundle/DataFixtures/CampaignFixtures.php +++ b/bundle/DataFixtures/CampaignFixtures.php @@ -1,34 +1,29 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\DataFixtures; +namespace CodeRhapsodie\IbexaMailingBundle\DataFixtures; use Carbon\Carbon; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Entity\StatHit; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; use Faker; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\StatHit; +/** + * @SuppressWarnings(PHPMD) + */ class CampaignFixtures extends Fixture implements DependentFixtureInterface { public const FIXTURE_COUNT_CAMPAIGN = 10; + /** + * {@inheritDoc} + */ public function load(ObjectManager $manager): void { $faker = Faker\Factory::create(); @@ -46,7 +41,7 @@ public function load(ObjectManager $manager): void ->setSenderEmail($faker->email) ->setReturnPathEmail($faker->email) ->setSenderName($faker->name) - ->setUpdated(new DateTime()) + ->setUpdated(new \DateTime()) ->setLocationId(2); // create MailingLists $nbDestinations = $faker->numberBetween(0, MailingListFixtures::FIXTURE_COUNT_MAILINGLIST); @@ -92,7 +87,7 @@ public function load(ObjectManager $manager): void ->setStarted($faker->dateTimeThisYear) ->setEnded($endDate) ->setHtml("Fixture {$i}{$k}{$l}") - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $mailing->addBroadcast($broadcast); // create Stats Hit @@ -103,7 +98,7 @@ public function load(ObjectManager $manager): void $hit->setUserKey($key); $hit->setUrl('-'); $hit->setCreated($faker->dateTimeThisYear) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $hit->setBrowserName( $faker->randomElement(['Chrome', 'Firefox', 'Safari', 'Internet Explorer']) ); @@ -114,14 +109,14 @@ public function load(ObjectManager $manager): void for ($n = 0; $n < $nbSubHits; ++$n) { $hit = new StatHit(); $hit->setUserKey($key) - ->setUpdated(new DateTime()); + ->setUpdated(new \DateTime()); $hit->setBrowserName( $faker->randomElement(['Chrome', 'Firefox', 'Safari', 'Internet Explorer']) ); $hit->setOsName($faker->randomElement(['Mac OS X', 'Windows', 'Linux'])); $hit->setUrl( - 'https://'.$faker->randomElement(['facebook', 'skype', 'google', 'lycos', 'caramail']). - '.com' + 'https://'.$faker->randomElement(['facebook', 'skype', 'google', 'lycos', 'caramail']) + .'.com' ); $hit->setBroadcast($broadcast); $manager->persist($hit); diff --git a/bundle/DataFixtures/MailingListFixtures.php b/bundle/DataFixtures/MailingListFixtures.php index 66d943e..f0e49c6 100644 --- a/bundle/DataFixtures/MailingListFixtures.php +++ b/bundle/DataFixtures/MailingListFixtures.php @@ -1,23 +1,13 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\DataFixtures; +namespace CodeRhapsodie\IbexaMailingBundle\DataFixtures; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; use Faker; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; class MailingListFixtures extends Fixture { diff --git a/bundle/DataFixtures/UsersRegistrationsFixtures.php b/bundle/DataFixtures/UsersRegistrationsFixtures.php index 0a8d9c7..3975006 100644 --- a/bundle/DataFixtures/UsersRegistrationsFixtures.php +++ b/bundle/DataFixtures/UsersRegistrationsFixtures.php @@ -1,26 +1,16 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\DataFixtures; +namespace CodeRhapsodie\IbexaMailingBundle\DataFixtures; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; use Faker; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Entity\Registration; -use Novactive\Bundle\eZMailingBundle\Entity\User; class UsersRegistrationsFixtures extends Fixture implements DependentFixtureInterface { @@ -42,7 +32,7 @@ public function load(ObjectManager $manager): void ->setGender($faker->title) ->setJobTitle($faker->jobTitle) ->setPhone($faker->phoneNumber) - ->setState($faker->state) + ->setState($faker->text) ->setZipcode($faker->postcode) ->setStatus($faker->randomElement(User::STATUSES)) ->setOrigin($faker->randomElement(['site', 'import'])); diff --git a/bundle/DependencyInjection/Configuration.php b/bundle/DependencyInjection/Configuration.php index b2ecb52..a672d19 100644 --- a/bundle/DependencyInjection/Configuration.php +++ b/bundle/DependencyInjection/Configuration.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\DependencyInjection; +namespace CodeRhapsodie\IbexaMailingBundle\DependencyInjection; use Ibexa\Bundle\Core\DependencyInjection\Configuration\SiteAccessAware; use Symfony\Component\Config\Definition\Builder\TreeBuilder; @@ -21,7 +11,7 @@ class Configuration extends SiteAccessAware\Configuration { public function getConfigTreeBuilder(): TreeBuilder { - $treeBuilder = new TreeBuilder('nova_ezmailing'); + $treeBuilder = new TreeBuilder('ibexamailing'); $rootNode = $treeBuilder->getRootNode(); $systemNode = $this->generateScopeBaseNode($rootNode); diff --git a/bundle/DependencyInjection/NovaeZMailingExtension.php b/bundle/DependencyInjection/IbexaMailingExtension.php similarity index 84% rename from bundle/DependencyInjection/NovaeZMailingExtension.php rename to bundle/DependencyInjection/IbexaMailingExtension.php index 0dfe8d7..33d59a0 100644 --- a/bundle/DependencyInjection/NovaeZMailingExtension.php +++ b/bundle/DependencyInjection/IbexaMailingExtension.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\DependencyInjection; +namespace CodeRhapsodie\IbexaMailingBundle\DependencyInjection; use Ibexa\Bundle\Core\DependencyInjection\Configuration\SiteAccessAware\ConfigurationProcessor; use Symfony\Component\Config\FileLocator; @@ -23,13 +13,18 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Yaml\Yaml; -class NovaeZMailingExtension extends Extension implements PrependExtensionInterface +class IbexaMailingExtension extends Extension implements PrependExtensionInterface { public function getAlias(): string { - return 'nova_ezmailing'; + return 'ibexamailing'; } + /** + * {@inheritdoc} + * + * @param array $configs + */ public function load(array $configs, ContainerBuilder $container): void { $configuration = $this->getConfiguration($configs, $container); diff --git a/bundle/Entity/Broadcast.php b/bundle/Entity/Broadcast.php index b30003b..24a94dc 100644 --- a/bundle/Entity/Broadcast.php +++ b/bundle/Entity/Broadcast.php @@ -1,31 +1,23 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; use DateTime; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** - * A Broadcast is a record of a Mailing "sending" at a certain point in time + * A BroadcastRepository is a record of a Mailing "sending" at a certain point in time * to a certain number of approved registrations * with a certain html contents (we will backup here) * It's really a record of a Mailing broadcast. * - * @ORM\Table(name="novaezmailing_broadcast") + * @ORM\Table(name="mailing_broadcast") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\Broadcast") + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\BroadcastRepository") */ class Broadcast { @@ -33,55 +25,65 @@ class Broadcast /** * @var int + * * @ORM\Column(name="BDCST_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="BDCST_started", type="datetime", nullable=false) */ private $started; /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="BDCST_ended", type="datetime", nullable=true) */ private $ended; /** * @var int + * * @ORM\Column(name="BDCST_email_sent_count", type="integer", nullable=false) */ private $emailSentCount; /** * @var string + * * @ORM\Column(name="BDCST_html", type="text", nullable=false) */ private $html; /** * @var Mailing - * @ORM\ManyToOne(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Mailing", inversedBy="broadcasts") + * + * @ORM\ManyToOne(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Mailing", inversedBy="broadcasts") + * * @ORM\JoinColumn(name="MAIL_id", referencedColumnName="MAIL_id") */ private $mailing; /** - * @var StatHit[] - * @ORM\OneToMany(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\StatHit", mappedBy="broadcast", + * @var ArrayCollection + * + * @ORM\OneToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\StatHit", mappedBy="broadcast", * cascade={"persist","remove"}, * fetch="EXTRA_LAZY") */ - private $statHits; + private Collection $statHits; public function __construct() { $this->emailSentCount = 0; - $this->created = new DateTime(); + $this->created = new \DateTime(); } public function getId(): int @@ -96,24 +98,24 @@ public function setId(int $id): self return $this; } - public function getStarted(): DateTime + public function getStarted(): \DateTime { return $this->started; } - public function setStarted(DateTime $started): self + public function setStarted(\DateTime $started): self { $this->started = $started; return $this; } - public function getEnded(): ?DateTime + public function getEnded(): ?\DateTime { return $this->ended; } - public function setEnded(DateTime $ended): self + public function setEnded(\DateTime $ended): self { $this->ended = $ended; @@ -156,7 +158,10 @@ public function setHtml(string $html): self return $this; } - public function getStatHits(): array + /** + * @return ArrayCollection + */ + public function getStatHits(): Collection { return $this->statHits; } diff --git a/bundle/Entity/Campaign.php b/bundle/Entity/Campaign.php index 6e4f4e5..86d7585 100644 --- a/bundle/Entity/Campaign.php +++ b/bundle/Entity/Campaign.php @@ -1,32 +1,23 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; /** - * A Campaign contains generic information shared between the Mailings it contains. + * A CampaignRepository contains generic information shared between the Mailings it contains. * It owns also a Link to a eZ Content that is going to be injected in the template. * - * @ORM\Table(name="novaezmailing_campaign") + * @ORM\Table(name="mailing_campaign") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\Campaign") - * @ORM\EntityListeners({"Novactive\Bundle\eZMailingBundle\Listener\EntityContentLink"}) + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\CampaignRepository") + * + * @ORM\EntityListeners({"CodeRhapsodie\IbexaMailingBundle\Listener\EntityContentLink"}) */ class Campaign implements eZ\ContentInterface { @@ -35,79 +26,94 @@ class Campaign implements eZ\ContentInterface use eZ\Content; /** - * @var int * @ORM\Column(name="CAMP_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private int $id; /** * @var string + * * @Assert\NotBlank() + * * @ORM\Column(name="CAMP_sender_name", type="string", length=255, nullable=false) */ private $senderName; /** * @var string + * * @Assert\NotBlank() + * * @Assert\Email() + * * @ORM\Column(name="CAMP_sender_email", type="string", length=255, nullable=false) */ private $senderEmail; /** * @var string + * * @Assert\NotBlank() + * * @Assert\Email() + * * @ORM\Column(name="CAMP_report_email", type="string", length=255, nullable=false) */ private $reportEmail; /** - * @var string - * @Assert\NotBlank() + * @var string|null + * * @Assert\Email() - * @ORM\Column(name="CAMP_return_path_email", type="string", length=255, nullable=false) + * + * @ORM\Column(name="CAMP_return_path_email", type="string", length=255, nullable=true) */ private $returnPathEmail; /** * @var array + * * @ORM\Column(name="CAMP_siteaccess_limit", type="array", nullable=true) */ private $siteaccessLimit; /** - * @var MailingList[] - * @ORM\ManyToMany(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\MailingList", inversedBy="campaigns") - * @ORM\JoinTable(name="novaezmailing_campaign_mailinglists_destination", + * @var ArrayCollection + * + * @ORM\ManyToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\MailingList", inversedBy="campaigns") + * + * @ORM\JoinTable(name="mailing_campaign_mailinglists_destination", * joinColumns={@ORM\JoinColumn(name="ML_id", referencedColumnName="CAMP_id")}, * inverseJoinColumns={@ORM\JoinColumn(name="CAMP_id", referencedColumnName="ML_id")} * ) + * * @ORM\OrderBy({"created" = "ASC"}) */ - private $mailingLists; + private Collection $mailingLists; /** - * @var Mailing[] - * @ORM\OneToMany(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Mailing", mappedBy="campaign", + * @var ArrayCollection + * + * @ORM\OneToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Mailing", mappedBy="campaign", * cascade={"persist","remove"}) */ - private $mailings; + private Collection $mailings; public function __construct() { $this->mailingLists = new ArrayCollection(); $this->mailings = new ArrayCollection(); - $this->created = new DateTime(); + $this->created = new \DateTime(); $this->siteaccessLimit = []; } public function getId(): int { - return (int) $this->id; + return $this->id; } public function setId(int $id): self @@ -141,7 +147,7 @@ public function setSenderEmail(string $senderEmail): self return $this; } - public function getReportEmail(): ?string + public function getReportEmail(): string { return $this->reportEmail; } @@ -166,13 +172,16 @@ public function setSiteaccessLimit(array $siteaccessLimit): self } /** - * @return MailingList[]|ArrayCollection + * @return ArrayCollection */ - public function getMailingLists() + public function getMailingLists(): Collection { return $this->mailingLists; } + /** + * @param array $mailingLists + */ public function setMailingLists(array $mailingLists): self { foreach ($mailingLists as $mailingList) { @@ -194,21 +203,22 @@ public function addMailingList(MailingList $mailingList): self } /** - * @return ArrayCollection|Mailing[] + * @return ArrayCollection */ - public function getMailings() + public function getMailings(): Collection { return $this->mailings; } + /** + * @param array $mailings + */ public function setMailings(array $mailings): self { foreach ($mailings as $mailing) { $this->addMailing($mailing); } - $this->mailings = $mailings; - return $this; } @@ -217,9 +227,11 @@ public function addMailing(Mailing $mailing): self if ($this->mailings->contains($mailing)) { return $this; } - $this->mailings->add($mailing); + $mailing->setCampaign($this); + $this->mailings->add($mailing); + return $this; } @@ -228,7 +240,7 @@ public function getReturnPathEmail(): ?string return $this->returnPathEmail; } - public function setReturnPathEmail(string $returnPathEmail): self + public function setReturnPathEmail(?string $returnPathEmail): self { $this->returnPathEmail = $returnPathEmail; diff --git a/bundle/Entity/Compose/Metadata.php b/bundle/Entity/Compose/Metadata.php index 60c08a2..41c2fb2 100644 --- a/bundle/Entity/Compose/Metadata.php +++ b/bundle/Entity/Compose/Metadata.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity\Compose; +namespace CodeRhapsodie\IbexaMailingBundle\Entity\Compose; use DateTime; use Doctrine\ORM\Mapping as ORM; @@ -20,35 +10,37 @@ trait Metadata { /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="OBJ_created", type="datetime") */ private $created; /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="OBJ_updated", type="datetime") */ private $updated; - public function getCreated(): DateTime + public function getCreated(): \DateTime { return $this->created; } - public function setCreated(DateTime $created): self + public function setCreated(\DateTime $created): self { $this->created = $created; return $this; } - public function getUpdated(): DateTime + public function getUpdated(): \DateTime { return $this->updated; } - public function setUpdated(DateTime $updated): self + public function setUpdated(\DateTime $updated): self { $this->updated = $updated; diff --git a/bundle/Entity/Compose/Names.php b/bundle/Entity/Compose/Names.php index 8820ba1..29acc6a 100644 --- a/bundle/Entity/Compose/Names.php +++ b/bundle/Entity/Compose/Names.php @@ -1,39 +1,34 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity\Compose; +namespace CodeRhapsodie\IbexaMailingBundle\Entity\Compose; -use Symfony\Component\Validator\Constraints as Assert; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; trait Names { /** - * @var array + * @var array + * * @Assert\NotBlank() + * * @ORM\Column(name="OBJ_names", type="array", nullable=false) */ - private $names; + private array $names; /** - * @return array + * @return array|null */ public function getNames(): ?array { return $this->names; } + /** + * @param array $names + */ public function setNames(array $names): self { $this->names = $names; @@ -41,12 +36,9 @@ public function setNames(array $names): self return $this; } - public function getName(?string $lang = null): ?string + public function getName(string $lang = null): ?string { - if (null === $this->names) { - return null; - } - if (null === $lang || !isset($this->names[$lang])) { + if ($lang === null || !isset($this->names[$lang])) { return array_values($this->names)[0]; } diff --git a/bundle/Entity/Compose/Remote.php b/bundle/Entity/Compose/Remote.php index d3711c3..16bd70a 100644 --- a/bundle/Entity/Compose/Remote.php +++ b/bundle/Entity/Compose/Remote.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity\Compose; +namespace CodeRhapsodie\IbexaMailingBundle\Entity\Compose; use DateTime; use Doctrine\ORM\Mapping as ORM; @@ -21,18 +11,21 @@ trait Remote { /** * @var string + * * @ORM\Column(name="OBJ_remote_id", type="string", length=255, nullable=true) */ private $remoteId; /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="OBJ_remote_last_synchro", type="datetime", nullable=true) */ private $lastSynchro; /** * @var int + * * @ORM\Column(name="OBJ_remote_status", type="smallint", nullable=true) */ private $remoteStatus; @@ -49,12 +42,12 @@ public function setRemoteId(string $remoteId): self return $this; } - public function getLastSynchro(): ?DateTime + public function getLastSynchro(): ?\DateTime { return $this->lastSynchro; } - public function setLastSynchro(DateTime $lastSynchro): self + public function setLastSynchro(\DateTime $lastSynchro): self { $this->lastSynchro = $lastSynchro; diff --git a/bundle/Entity/ConfirmationToken.php b/bundle/Entity/ConfirmationToken.php index da6f35a..02f2eed 100644 --- a/bundle/Entity/ConfirmationToken.php +++ b/bundle/Entity/ConfirmationToken.php @@ -1,26 +1,15 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Table(name="novaezmailing_confirmation_token") + * @ORM\Table(name="mailing_confirmation_token") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\ConfirmationToken") + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\ConfirmationTokenRepository") */ class ConfirmationToken { @@ -34,21 +23,24 @@ class ConfirmationToken * @var string * * @ORM\Id + * * @ORM\GeneratedValue(strategy="UUID") + * * @ORM\Column(name="CT_id", type="guid", unique=true) */ private $id; /** * @var array + * * @ORM\Column(name="CT_payload", type="array", nullable=false) */ private $payload; public function __construct() { - $this->created = new DateTime(); - $this->updated = new DateTime(); + $this->created = new \DateTime(); + $this->updated = new \DateTime(); } public function getId(): ?string diff --git a/bundle/Entity/Mailing.php b/bundle/Entity/Mailing.php index c057b15..2d09d01 100644 --- a/bundle/Entity/Mailing.php +++ b/bundle/Entity/Mailing.php @@ -1,32 +1,23 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; use Carbon\Carbon; -use DateTime; +use CodeRhapsodie\IbexaMailingBundle\Core\Utils\Clock; +use CodeRhapsodie\IbexaMailingBundle\Validator\Constraints as IbexaMailing; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use Novactive\Bundle\eZMailingBundle\Core\Utils\Clock; -use Novactive\Bundle\eZMailingBundle\Validator\Constraints as NovaEzMailingAssert; use Symfony\Component\Validator\Constraints as Assert; /** - * @ORM\Table(name="novaezmailing_mailing") + * @ORM\Table(name="mailing_mailing") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\Mailing") - * @ORM\EntityListeners({"Novactive\Bundle\eZMailingBundle\Listener\EntityContentLink"}) + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository") + * + * @ORM\EntityListeners({"CodeRhapsodie\IbexaMailingBundle\Listener\EntityContentLink"}) */ class Mailing implements eZ\ContentInterface { @@ -84,99 +75,126 @@ class Mailing implements eZ\ContentInterface /** * @var int + * * @ORM\Column(name="MAIL_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string + * * @Assert\NotBlank() + * * @ORM\Column(name="MAIL_status", type="string", nullable=false) */ private $status; /** * @var bool + * * @ORM\Column(name="MAIL_recurring", type="boolean", nullable=false) */ private $recurring; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=0,max=24) + * + * @IbexaMailing\ArrayRange(min=0,max=24) + * * @ORM\Column(name="MAIL_hours_of_day", type="array", nullable=false) */ private $hoursOfDay; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=7) + * + * @IbexaMailing\ArrayRange(min=1,max=7) + * * @ORM\Column(name="MAIL_days_of_week", type="array", nullable=true) */ private $daysOfWeek; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=31) + * + * @IbexaMailing\ArrayRange(min=1,max=31) + * * @ORM\Column(name="MAIL_days_of_month", type="array", nullable=true) */ private $daysOfMonth; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=365) + * + * @IbexaMailing\ArrayRange(min=1,max=365) + * * @ORM\Column(name="MAIL_days_of_year", type="array", nullable=true) */ private $daysOfYear; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=5) + * + * @IbexaMailing\ArrayRange(min=1,max=5) + * * @ORM\Column(name="MAIL_weeks_of_month", type="array", nullable=true) */ private $weeksOfMonth; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=12) + * + * @IbexaMailing\ArrayRange(min=1,max=12) + * * @ORM\Column(name="MAIL_months_of_year", type="array", nullable=true) */ private $monthsOfYear; /** * @var array - * @NovaEzMailingAssert\ArrayRange(min=1,max=53) + * + * @IbexaMailing\ArrayRange(min=1,max=53) + * * @ORM\Column(name="MAIL_weeks_of_year", type="array", nullable=true) */ private $weeksOfYear; /** * @var Campaign - * @ORM\ManyToOne(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Campaign", inversedBy="mailings") + * + * @ORM\ManyToOne(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Campaign", inversedBy="mailings") + * * @ORM\JoinColumn(name="CAMP_id", referencedColumnName="CAMP_id") */ private $campaign; /** - * @var Broadcast[] - * @ORM\OneToMany(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Broadcast", mappedBy="mailing", + * @var ArrayCollection + * + * @ORM\OneToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast", mappedBy="mailing", * cascade={"persist","remove"}, * fetch="EXTRA_LAZY") */ - private $broadcasts; + private Collection $broadcasts; /** * @var string + * * @ORM\Column(name="MAIL_subject", type="string", length=255, nullable=false) + * * @Assert\NotBlank() */ private $subject; /** * @var string + * * @Assert\NotBlank() + * * @ORM\Column(name="MAIL_siteaccess", type="string", nullable=false) */ private $siteAccess; @@ -184,9 +202,8 @@ class Mailing implements eZ\ContentInterface public function __construct() { $this->recurring = false; - $this->statHits = new ArrayCollection(); $this->broadcasts = new ArrayCollection(); - $this->created = new DateTime(); + $this->created = new \DateTime(); $this->hoursOfDay = []; $this->daysOfWeek = []; $this->daysOfMonth = []; @@ -220,19 +237,18 @@ public function setStatus(string $status): self return $this; } - public function getLastSent(): ?DateTime + public function getLastSent(): ?\DateTime { - if (0 == $this->broadcasts->count()) { + if ($this->broadcasts->isEmpty()) { return null; } - if (1 == $this->broadcasts->count() && 0 === $this->broadcasts[0]->getEmailSentCount()) { + if ($this->broadcasts->count() === 1 && $this->broadcasts->first()->getEmailSentCount() === 0) { return null; } - $lastSent = $this->broadcasts[0]->getStarted(); + $lastSent = $this->broadcasts->first()->getStarted(); foreach ($this->broadcasts as $broadcast) { - /** @var Broadcast $broadcast */ - if (0 === $broadcast->getEmailSentCount()) { + if ($broadcast->getEmailSentCount() === 0) { // it was a test continue; } @@ -352,7 +368,7 @@ public function setCampaign(?Campaign $campaign): self return $this; } - public function nextTick(): ?DateTime + public function nextTick(): ?\DateTime { try { $clock = new Clock(Carbon::now()); @@ -366,38 +382,38 @@ public function nextTick(): ?DateTime public function hasBeenSent(): bool { return - (false === $this->isRecurring() && self::SENT === $this->status) || - (true === $this->isRecurring() && null !== $this->getLastSent()); + ($this->isRecurring() === false && $this->status === self::SENT) + || ($this->isRecurring() === true && $this->getLastSent() !== null); } public function isPending(): bool { - return self::PENDING === $this->status; + return $this->status === self::PENDING; } public function isDraft(): bool { - return self::DRAFT === $this->status; + return $this->status === self::DRAFT; } public function isArchived(): bool { - return self::ARCHIVED === $this->status; + return $this->status === self::ARCHIVED; } public function isAborted(): bool { - return self::ABORTED === $this->status; + return $this->status === self::ABORTED; } public function isProcessing(): bool { - return self::PROCESSING === $this->status; + return $this->status === self::PROCESSING; } public function isTested(): bool { - return self::TESTED === $this->status; + return $this->status === self::TESTED; } public function getBroadcasts() @@ -405,7 +421,7 @@ public function getBroadcasts() return $this->broadcasts; } - public function setBroadcasts(array $broadcasts): self + public function setBroadcasts(Collection $broadcasts): self { $this->broadcasts = $broadcasts; @@ -417,9 +433,11 @@ public function addBroadcast(Broadcast $broadcast): self if ($this->broadcasts->contains($broadcast)) { return $this; } - $this->broadcasts->add($broadcast); + $broadcast->setMailing($this); + $this->broadcasts->add($broadcast); + return $this; } diff --git a/bundle/Entity/MailingList.php b/bundle/Entity/MailingList.php index 984f91b..08e91d0 100644 --- a/bundle/Entity/MailingList.php +++ b/bundle/Entity/MailingList.php @@ -1,82 +1,85 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use RuntimeException; /** - * @ORM\Table(name="novaezmailing_mailing_list") + * @ORM\Table(name="mailing_mailing_list") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\MailingList") + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\MailingListRepository") */ class MailingList { - use Compose\Remote; use Compose\Metadata; use Compose\Names; + use Compose\Remote; /** * @var int + * * @ORM\Column(name="ML_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** - * @var Registration[] + * @var ArrayCollection + * * @ORM\OrderBy({"created" = "ASC"}) - * @ORM\OneToMany(targetEntity="\Novactive\Bundle\eZMailingBundle\Entity\Registration", mappedBy="mailingList", + * + * @ORM\OneToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Registration", mappedBy="mailingList", * cascade={"persist","remove"}, * orphanRemoval=true, * fetch="EXTRA_LAZY" * ) */ - private $registrations; + private Collection $registrations; /** * @var array + * * @ORM\Column(name="ML_siteaccess_limit", type="array", nullable=true) */ private $siteaccessLimit; /** * @var bool + * * @ORM\Column(name="ML_approbation", type="boolean", nullable=false) */ private $withApproval; /** - * @var Campaign[] - * @ORM\ManyToMany(targetEntity="\Novactive\Bundle\eZMailingBundle\Entity\Campaign", mappedBy="mailingLists", + * @var ArrayCollection + * + * @ORM\ManyToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Campaign", mappedBy="mailingLists", * cascade={"persist"}, * orphanRemoval=true, * fetch="EXTRA_LAZY") */ - private $campaigns; + private Collection $campaigns; public function __construct() { $this->registrations = new ArrayCollection(); - $this->created = new DateTime(); + $this->campaigns = new ArrayCollection(); + $this->created = new \DateTime(); $this->withApproval = false; } + public function __toString(): string + { + return $this->getName() ?? ''; + } + public function getId(): int { return (int) $this->id; @@ -90,18 +93,21 @@ public function setId(int $id): self } /** - * @return ArrayCollection|Registration[] + * @return ArrayCollection */ - public function getRegistrations() + public function getRegistrations(): Collection { return $this->registrations; } - public function setRegistrations(array $registrations): self + /** + * @param Collection $registrations + */ + public function setRegistrations(Collection $registrations): self { - foreach ($registrations as $registration) { + foreach ($registrations->toArray() as $registration) { if (!$registration instanceof Registration) { - throw new RuntimeException(sprintf('Provided Registration is not a %s', Registration::class)); + throw new \RuntimeException(sprintf('Provided RegistrationRepository is not a %s', Registration::class)); } } $this->registrations = $registrations; @@ -121,11 +127,17 @@ public function setWithApproval(bool $withApproval): self return $this; } + /** + * @return array|null + */ public function getSiteaccessLimit(): ?array { return $this->siteaccessLimit; } + /** + * @param array $siteaccessLimit + */ public function setSiteaccessLimit(array $siteaccessLimit): self { $this->siteaccessLimit = $siteaccessLimit; @@ -134,15 +146,10 @@ public function setSiteaccessLimit(array $siteaccessLimit): self } /** - * @return Campaign[]|ArrayCollection + * @return ArrayCollection */ - public function getCampaigns() + public function getCampaigns(): Collection { return $this->campaigns; } - - public function __toString(): string - { - return $this->getName() ?? ''; - } } diff --git a/bundle/Entity/Registration.php b/bundle/Entity/Registration.php index c1e57b8..66f1e85 100644 --- a/bundle/Entity/Registration.php +++ b/bundle/Entity/Registration.php @@ -1,30 +1,21 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Table(name="novaezmailing_registrations", + * @ORM\Table(name="mailing_registrations", * uniqueConstraints={ @ORM\UniqueConstraint(name="unique_registration",columns={"ML_id","USER_id"})}, * indexes={ + * * @ORM\Index(name="search_idx_approved", columns={"REG_approved"}) * } * ) - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\Registration") + * + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\RegistrationRepository") */ class Registration { @@ -32,40 +23,48 @@ class Registration /** * @var int + * * @ORM\Column(name="REG_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var MailingList - * @ORM\ManyToOne(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\MailingList", inversedBy="registrations") + * + * @ORM\ManyToOne(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\MailingList", inversedBy="registrations") + * * @ORM\JoinColumn(name="ML_id", referencedColumnName="ML_id", nullable=false) */ private $mailingList; /** * @var User - * @ORM\ManyToOne(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\User", inversedBy="registrations") + * + * @ORM\ManyToOne(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\User", inversedBy="registrations") + * * @ORM\JoinColumn(name="USER_id", referencedColumnName="USER_id", nullable=false) */ private $user; /** * @var bool + * * @ORM\Column(name="REG_approved", type="boolean", nullable=false) */ private $approved; /** - * Registration constructor. + * RegistrationRepository constructor. */ public function __construct() { $this->approved = false; - $this->created = new DateTime(); - $this->updated = new DateTime(); + $this->created = new \DateTime(); + $this->updated = new \DateTime(); } public function getId(): int @@ -73,9 +72,6 @@ public function getId(): int return (int) $this->id; } - /** - * @return Registration - */ public function setId(int $id): self { $this->id = $id; @@ -83,37 +79,23 @@ public function setId(int $id): self return $this; } - /** - * @return mixed - */ public function getMailingList(): MailingList { return $this->mailingList; } - /** - * @param MailingList $mailingList - * - * @return Registration - */ - public function setMailingList($mailingList): self + public function setMailingList(MailingList $mailingList): self { $this->mailingList = $mailingList; return $this; } - /** - * @return mixed - */ public function getUser(): User { return $this->user; } - /** - * @return Registration - */ public function setUser(User $user): self { $this->user = $user; @@ -126,9 +108,6 @@ public function isApproved(): bool return $this->approved; } - /** - * @return Registration - */ public function setApproved(bool $approved): self { $this->approved = $approved; diff --git a/bundle/Entity/StatHit.php b/bundle/Entity/StatHit.php index b8aa1f5..ed8877b 100644 --- a/bundle/Entity/StatHit.php +++ b/bundle/Entity/StatHit.php @@ -1,26 +1,15 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Table(name="novaezmailing_stats_hit") + * @ORM\Table(name="mailing_stats_hit") * - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\StatHit") + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\StatHitRepository") */ class StatHit { @@ -30,7 +19,9 @@ class StatHit * @var int * * @ORM\Column(name="STHIT_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private $id; @@ -65,14 +56,16 @@ class StatHit /** * @var Broadcast - * @ORM\ManyToOne(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Broadcast", inversedBy="statHits") + * + * @ORM\ManyToOne(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast", inversedBy="statHits") + * * @ORM\JoinColumn(name="BDCST_id", referencedColumnName="BDCST_id") */ private $broadcast; public function __construct() { - $this->created = new DateTime(); + $this->created = new \DateTime(); } public function getId(): int diff --git a/bundle/Entity/User.php b/bundle/Entity/User.php index 815d316..fc3ce94 100644 --- a/bundle/Entity/User.php +++ b/bundle/Entity/User.php @@ -1,35 +1,28 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity; +namespace CodeRhapsodie\IbexaMailingBundle\Entity; -use DateTime; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; /** - * @ORM\Table(name="novaezmailing_user", + * @ORM\Table(name="mailing_user", * uniqueConstraints={ @ORM\UniqueConstraint(name="unique_email",columns={"USER_email"})}, * indexes={ + * * @ORM\Index(name="search_idx_restricted", columns={"USER_restricted"}), * @ORM\Index(name="search_idx_status", columns={"USER_status"}) * } * ) - * @ORM\Entity(repositoryClass="Novactive\Bundle\eZMailingBundle\Repository\User") + * + * @ORM\Entity(repositoryClass="CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository") + * * @UniqueEntity( * fields={"email"}, * errorPath="email", @@ -72,7 +65,7 @@ class User public const BLACKLISTED = 'blacklisted'; /** - * Was removed + * Was removed. */ public const REMOVED = 'removed'; @@ -100,126 +93,145 @@ class User self::BLACKLISTED => 'info', ]; - public function __construct() - { - $this->registrations = new ArrayCollection(); - $this->created = new DateTime(); - $this->restricted = false; - $this->updated = new DateTime(); - } - /** - * @var int * @ORM\Column(name="USER_id", type="bigint", nullable=false) + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private int $id; /** * @var string + * * @ORM\Column(name="USER_email", type="string", length=255, nullable=false) + * * @Assert\NotBlank(message="Email is mandatory") */ private $email; /** * @var string + * * @ORM\Column(name="USER_first_name", type="string", length=255, nullable=true) */ private $firstName; /** * @var string + * * @ORM\Column(name="USER_last_name", type="string", length=255, nullable=true) */ private $lastName; /** * @var string + * * @ORM\Column(name="USER_gender", type="string", length=255, nullable=true) */ private $gender; /** - * @var DateTime + * @var \DateTime + * * @ORM\Column(name="USER_birth_date", type="date", nullable=true) */ private $birthDate; /** * @var string + * * @ORM\Column(name="USER_phone", type="string", length=255, nullable=true) */ private $phone; /** * @var string + * * @ORM\Column(name="USER_zipcode", type="string", length=255, nullable=true) */ private $zipcode; /** * @var string + * * @ORM\Column(name="USER_city", type="string", length=255, nullable=true) */ private $city; /** * @var string + * * @ORM\Column(name="USER_state", type="string", length=255, nullable=true) */ private $state; /** * @var string + * * @ORM\Column(name="USER_country", type="string", length=255, nullable=true) */ private $country; /** * @var string + * * @ORM\Column(name="USER_job_title", type="string", length=255, nullable=true) */ private $jobTitle; /** * @var string + * * @ORM\Column(name="USER_company", type="string", length=255, nullable=true) */ private $company; /** * @var string + * * @ORM\Column(name="USER_origin", type="string", length=255, nullable=false) */ private $origin; /** * @var string + * * @ORM\Column(name="USER_status", type="string", nullable=false) */ private $status; /** * @var bool + * * @ORM\Column(name="USER_restricted", type="boolean", nullable=false) */ private $restricted; /** - * @var Registration[] + * @var ArrayCollection + * * @ORM\OrderBy({"created" = "ASC"}) - * @ORM\OneToMany(targetEntity="Novactive\Bundle\eZMailingBundle\Entity\Registration", mappedBy="user", + * + * @ORM\OneToMany(targetEntity="CodeRhapsodie\IbexaMailingBundle\Entity\Registration", mappedBy="user", * cascade={"persist","remove"}, * orphanRemoval=true * ) */ - private $registrations; + private Collection $registrations; + + public function __construct() + { + $this->registrations = new ArrayCollection(); + $this->created = new \DateTime(); + $this->restricted = false; + $this->updated = new \DateTime(); + } public function getId(): int { - return (int) $this->id; + return $this->id; } public function setId(int $id): self @@ -277,12 +289,12 @@ public function setGender(string $gender): self return $this; } - public function getBirthDate(): ?DateTime + public function getBirthDate(): ?\DateTime { return $this->birthDate; } - public function setBirthDate(?DateTime $birthDate): self + public function setBirthDate(?\DateTime $birthDate): self { $this->birthDate = $birthDate; @@ -415,17 +427,17 @@ public function setRestricted(bool $restricted): self } /** - * @return ArrayCollection|Registration[] + * @return Collection */ - public function getRegistrations() + public function getRegistrations(): Collection { return $this->registrations; } /** - * @return ArrayCollection|Registration[] + * @return Collection */ - public function getPendingRegistrations() + public function getPendingRegistrations(): Collection { $criteria = Criteria::create(); $criteria->where(Criteria::expr()->eq('approved', true)); @@ -435,8 +447,6 @@ public function getPendingRegistrations() /** * @param Registration[] $registrations - * - * @return MailingList */ public function setRegistrations(array $registrations): self { @@ -452,18 +462,16 @@ public function addRegistration(Registration $registration): self if ($this->registrations->contains($registration)) { return $this; } - - if ( - $this->registrations->exists( - function ($key, Registration $element) use ($registration) { - //tricks phpmd - - return $element->getMailingList()->getId() === $registration->getMailingList()->getId(); - } - ) + if ($this->registrations->exists( + function ($key, Registration $element) use ($registration) { + // tricks phpmd + return $element->getMailingList()->getId() === $registration->getMailingList()->getId(); + } + ) ) { return $this; } + $registration->setUser($this); $this->registrations->add($registration); @@ -479,26 +487,26 @@ public function removeRegistration(Registration $registration): self public function isConfirmed(): bool { - return self::CONFIRMED === $this->status; + return $this->status === self::CONFIRMED; } public function isPending(): bool { - return self::PENDING === $this->status; + return $this->status === self::PENDING; } public function isBlacklisted(): bool { - return self::BLACKLISTED === $this->status; + return $this->status === self::BLACKLISTED; } public function isSoftBounce(): bool { - return self::SOFT_BOUNCE === $this->status; + return $this->status === self::SOFT_BOUNCE; } public function isHardBounce(): bool { - return self::HARD_BOUNCE === $this->status; + return $this->status === self::HARD_BOUNCE; } } diff --git a/bundle/Entity/eZ/Content.php b/bundle/Entity/eZ/Content.php index f7f34f9..a3f4cad 100644 --- a/bundle/Entity/eZ/Content.php +++ b/bundle/Entity/eZ/Content.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity\eZ; +namespace CodeRhapsodie\IbexaMailingBundle\Entity\eZ; use Doctrine\ORM\Mapping as ORM; use Ibexa\Contracts\Core\Repository\Values\Content\Content as eZContent; @@ -22,6 +12,7 @@ trait Content { /** * @var int + * * @ORM\Column(name="EZ_locationId", type="integer", nullable=true) */ private $locationId; diff --git a/bundle/Entity/eZ/ContentInterface.php b/bundle/Entity/eZ/ContentInterface.php index 555fcc6..a91871b 100644 --- a/bundle/Entity/eZ/ContentInterface.php +++ b/bundle/Entity/eZ/ContentInterface.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Entity\eZ; +namespace CodeRhapsodie\IbexaMailingBundle\Entity\eZ; use Ibexa\Contracts\Core\Repository\Values\Content\Content as eZContent; use Ibexa\Contracts\Core\Repository\Values\Content\Location as eZLocation; @@ -21,13 +11,13 @@ interface ContentInterface { public function getLocationId(): ?int; - public function setLocationId(int $locationId): ContentInterface; + public function setLocationId(int $locationId): self; public function getContent(): ?eZContent; - public function setContent(eZContent $content): ContentInterface; + public function setContent(eZContent $content): self; public function getLocation(): ?eZLocation; - public function setLocation(eZLocation $location): ContentInterface; + public function setLocation(eZLocation $location): self; } diff --git a/bundle/Form/CampaignType.php b/bundle/Form/CampaignType.php index f0faca3..a2c696a 100644 --- a/bundle/Form/CampaignType.php +++ b/bundle/Form/CampaignType.php @@ -1,22 +1,12 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; use Ibexa\AdminUi\Siteaccess\SiteaccessResolver; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -39,6 +29,9 @@ public function __construct(SiteaccessResolver $siteAccessResolver) $this->siteAccessResolver = $siteAccessResolver; } + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $siteaccesses = array_combine( @@ -63,7 +56,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add( 'returnPathEmail', EmailType::class, - ['required' => true, 'label' => 'campaign.form.return_path_email'] + ['required' => false, 'label' => 'campaign.form.return_path_email'] ) ->add('locationId', HiddenType::class) ->add( @@ -94,7 +87,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setDefaults( [ 'data_class' => Campaign::class, - 'translation_domain' => 'ezmailing', + 'translation_domain' => 'ibexamailing', ] ); } diff --git a/bundle/Form/ImportType.php b/bundle/Form/ImportType.php index 3b32747..c554d68 100644 --- a/bundle/Form/ImportType.php +++ b/bundle/Form/ImportType.php @@ -1,18 +1,10 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ +declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; -use Novactive\Bundle\eZMailingBundle\Core\DataHandler\UserImport; +use CodeRhapsodie\IbexaMailingBundle\Core\DataHandler\UserImport; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\FormBuilderInterface; @@ -20,6 +12,9 @@ class ImportType extends AbstractType { + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('file', FileType::class, [ @@ -33,7 +28,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setDefaults( [ 'data_class' => UserImport::class, - 'translation_domain' => 'ezmailing', + 'translation_domain' => 'ibexamailing', ] ); } diff --git a/bundle/Form/MailingListType.php b/bundle/Form/MailingListType.php index a512567..0eb9aee 100644 --- a/bundle/Form/MailingListType.php +++ b/bundle/Form/MailingListType.php @@ -1,21 +1,11 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; use Ibexa\AdminUi\Siteaccess\SiteaccessResolver; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -36,6 +26,9 @@ public function __construct(SiteaccessResolver $siteAccessResolver) $this->siteAccessResolver = $siteAccessResolver; } + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $siteaccess = array_combine( @@ -75,7 +68,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setDefaults( [ 'data_class' => MailingList::class, - 'translation_domain' => 'ezmailing', + 'translation_domain' => 'ibexamailing', ] ); } diff --git a/bundle/Form/MailingType.php b/bundle/Form/MailingType.php index 82577c5..4894422 100644 --- a/bundle/Form/MailingType.php +++ b/bundle/Form/MailingType.php @@ -1,23 +1,13 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Validator\Constraints\Location as LocationConstraint; +use CodeRhapsodie\IbexaMailingBundle\Validator\Constraints\Names as NamesConstraint; use Ibexa\AdminUi\Siteaccess\SiteaccessResolver; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Validator\Constraints\Location as LocationConstraint; -use Novactive\Bundle\eZMailingBundle\Validator\Constraints\Names as NamesConstraint; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; @@ -42,13 +32,16 @@ public function __construct(SiteaccessResolver $siteAccessResolver) $this->siteAccessResolver = $siteAccessResolver; } + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $fromArray = function ($array) { return implode(',', $array); }; $fromString = function ($string) { - return array_unique(null !== $string ? explode(',', $string) : []); + return array_unique($string !== null ? explode(',', $string) : []); }; $siteaccesses = array_combine( @@ -124,7 +117,7 @@ function (FormEvent $event) use ($siteaccesses) { ChoiceType::class, [ 'label' => 'mailing.buildform.which_siteaccess', - 'choices' => count($siteaccessLimit) > 0 ? $siteaccessLimit : $siteaccesses, + 'choices' => \count($siteaccessLimit) > 0 ? $siteaccessLimit : $siteaccesses, 'expanded' => true, 'multiple' => false, 'required' => true, @@ -139,7 +132,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setDefaults( [ 'data_class' => Mailing::class, - 'translation_domain' => 'ezmailing', + 'translation_domain' => 'ibexamailing', ] ); } diff --git a/bundle/Form/RegistrationType.php b/bundle/Form/RegistrationType.php index 52c9ff7..57086e5 100644 --- a/bundle/Form/RegistrationType.php +++ b/bundle/Form/RegistrationType.php @@ -1,24 +1,14 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Campaign as CampaignVoter; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Mailing as MailingVoter; use Doctrine\ORM\EntityManagerInterface; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\MailingList; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Campaign as CampaignVoter; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Mailing as MailingVoter; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -46,6 +36,9 @@ public function __construct( $this->entityManager = $entityManager; } + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('user', UserType::class); diff --git a/bundle/Form/UserType.php b/bundle/Form/UserType.php index 78d6fa9..4b7ae5f 100644 --- a/bundle/Form/UserType.php +++ b/bundle/Form/UserType.php @@ -1,20 +1,10 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Form; +namespace CodeRhapsodie\IbexaMailingBundle\Form; -use Novactive\Bundle\eZMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\FormBuilderInterface; @@ -22,6 +12,9 @@ class UserType extends AbstractType { + /** + * {@inheritDoc} + */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder diff --git a/bundle/IbexaMailingBundle.php b/bundle/IbexaMailingBundle.php new file mode 100644 index 0000000..7213a0f --- /dev/null +++ b/bundle/IbexaMailingBundle.php @@ -0,0 +1,34 @@ +extension === null) { + $extension = $this->createContainerExtension(); + if ($extension !== null) { + if (!$extension instanceof ExtensionInterface) { + throw new \LogicException(sprintf('Extension %s must implement '.ExtensionInterface::class.'.', $extension::class)); + } + $this->extension = $extension; + } else { + $this->extension = false; + } + } + if ($this->extension) { + return $this->extension; + } + + return null; + } +} diff --git a/bundle/Listener/EntityContentLink.php b/bundle/Listener/EntityContentLink.php index 3fd6b7d..7ace35c 100644 --- a/bundle/Listener/EntityContentLink.php +++ b/bundle/Listener/EntityContentLink.php @@ -1,24 +1,15 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Listener; +namespace CodeRhapsodie\IbexaMailingBundle\Listener; -use Doctrine\ORM\Event\LifecycleEventArgs; +use CodeRhapsodie\IbexaMailingBundle\Entity\eZ\ContentInterface; +use Doctrine\ORM\Event\PostLoadEventArgs; use Doctrine\ORM\Mapping\PostLoad; use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException; +use Ibexa\Contracts\Core\Repository\LocationService; use Ibexa\Contracts\Core\Repository\Repository; -use Novactive\Bundle\eZMailingBundle\Entity\eZ\ContentInterface; /** * Class ContentLink @@ -26,26 +17,23 @@ */ class EntityContentLink { - /** - * @var Repository - */ - private $repository; - - public function __construct(Repository $repository) + public function __construct(private readonly Repository $repository, private readonly LocationService $locationService) { - $this->repository = $repository; } - /** @PostLoad */ - public function postLoadHandler(ContentInterface $entity, LifecycleEventArgs $event): void + /** + * @PostLoad + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function postLoadHandler(ContentInterface $entity, PostLoadEventArgs $event): void { - if (null !== $entity->getLocationId()) { + if ($entity->getLocationId() !== null) { try { $this->repository->sudo(function () use ($entity) { - $location = $this->repository->getLocationService()->loadLocation($entity->getLocationId()); - $content = $this->repository->getContentService()->loadContentByContentInfo($location->contentInfo); + $location = $this->locationService->loadLocation($entity->getLocationId()); $entity->setLocation($location); - $entity->setContent($content); + $entity->setContent($location->getContent()); }); } catch (NotFoundException) { } diff --git a/bundle/Listener/LocationViewGroupTab.php b/bundle/Listener/LocationViewGroupTab.php index 3a6f4cf..f8bcd63 100644 --- a/bundle/Listener/LocationViewGroupTab.php +++ b/bundle/Listener/LocationViewGroupTab.php @@ -1,27 +1,17 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Listener; +namespace CodeRhapsodie\IbexaMailingBundle\Listener; +use CodeRhapsodie\IbexaMailingBundle\Core\Tab\Campaigns as CampaignsTab; +use CodeRhapsodie\IbexaMailingBundle\Core\Tab\Mailings as MailingsTab; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; use Doctrine\ORM\EntityManagerInterface; use Ibexa\AdminUi\Tab\Event\TabGroupEvent; use Ibexa\AdminUi\Tab\TabRegistry; use Ibexa\Contracts\Core\Repository\Values\Content\Location; -use Novactive\Bundle\eZMailingBundle\Core\Tab\Campaigns as CampaignsTab; -use Novactive\Bundle\eZMailingBundle\Core\Tab\Mailings as MailingsTab; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; class LocationViewGroupTab { @@ -60,7 +50,7 @@ public function __construct( public function onTabGroupPreRender(TabGroupEvent $event): void { $tabGroup = $event->getData(); - if ('location-view' !== $tabGroup->getIdentifier()) { + if ($tabGroup->getIdentifier() !== 'location-view') { return; } diff --git a/bundle/Listener/MailingWorkflow.php b/bundle/Listener/MailingWorkflow.php index 4eb65b1..b1aab5d 100644 --- a/bundle/Listener/MailingWorkflow.php +++ b/bundle/Listener/MailingWorkflow.php @@ -1,18 +1,8 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Listener; +namespace CodeRhapsodie\IbexaMailingBundle\Listener; use Psr\Log\LoggerInterface; use Symfony\Component\Workflow\Event\Event; @@ -33,7 +23,7 @@ public function onWorkflowMailingLeave(Event $event): void { $this->logger->notice( sprintf( - 'Mailing %s (id: "%s") performed transaction "%s" from "%s" to "%s"', + 'MailingRepository %s (id: "%s") performed transaction "%s" from "%s" to "%s"', $event->getSubject()->getName(), $event->getSubject()->getId(), $event->getTransition()->getName(), diff --git a/bundle/Listener/PreContentView.php b/bundle/Listener/PreContentView.php index 91b0bfa..60d81cd 100644 --- a/bundle/Listener/PreContentView.php +++ b/bundle/Listener/PreContentView.php @@ -1,52 +1,24 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Listener; +namespace CodeRhapsodie\IbexaMailingBundle\Listener; -use Doctrine\ORM\EntityManagerInterface; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Mailing as MailingVoter; use Ibexa\Core\MVC\Symfony\Event\PreContentViewEvent; use Ibexa\Core\MVC\Symfony\View\ContentView; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Mailing as MailingVoter; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; class PreContentView { - /** - * @var EntityManagerInterface - */ - private $entityManager; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var AuthorizationCheckerInterface - */ - private $authorizationChecker; - public function __construct( - EntityManagerInterface $entityManager, - RequestStack $requestStack, - AuthorizationCheckerInterface $authorizationChecker + private readonly RequestStack $requestStack, + private readonly AuthorizationCheckerInterface $authorizationChecker, + private readonly MailingRepository $mailingRepository ) { - $this->entityManager = $entityManager; - $this->requestStack = $requestStack; - $this->authorizationChecker = $authorizationChecker; } public function onPreContentView(PreContentViewEvent $event): void @@ -56,12 +28,12 @@ public function onPreContentView(PreContentViewEvent $event): void return; } - if ('novaezmailingfull' !== $contentView->getViewType()) { + if ($contentView->getViewType() !== 'ibexamailingfull') { return; } - $masterRequest = $this->requestStack->getMasterRequest(); - if (null === $masterRequest) { + $masterRequest = $this->requestStack->getMainRequest(); + if ($masterRequest === null) { return; } @@ -69,8 +41,10 @@ public function onPreContentView(PreContentViewEvent $event): void return; } - $mailing = $this->entityManager->getRepository(Mailing::class)->findOneById( - (int) $masterRequest->attributes->get('mailingId') + $mailing = $this->mailingRepository->findOneBy( + [ + 'id' => (int) $masterRequest->attributes->get('mailingId'), + ] ); if (!$mailing instanceof Mailing) { diff --git a/bundle/Listener/TopMenu.php b/bundle/Listener/TopMenu.php index dd727b7..4086299 100644 --- a/bundle/Listener/TopMenu.php +++ b/bundle/Listener/TopMenu.php @@ -1,34 +1,70 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Listener; +namespace CodeRhapsodie\IbexaMailingBundle\Listener; use Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent; -use Ibexa\AdminUi\Menu\MainMenuBuilder; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Routing\RouterInterface; class TopMenu implements EventSubscriberInterface { + public function __construct(private readonly RouterInterface $router) + { + } + public function onMainMenuConfigure(ConfigureMenuEvent $event): void { $menu = $event->getMenu(); - $contentMenu = $menu->getChild(MainMenuBuilder::ITEM_CONTENT); - $contentMenu->addChild( - 'eznovamailing', + $ibexaMailingMenu = $menu->addChild( + 'ibexamailing', + [ + 'label' => 'Ibexa Mailing', + 'extras' => [ + 'icon' => 'mail', + 'routes' => array_filter(array_keys($this->router->getRouteCollection()->all()), function (string $key) { + return str_starts_with($key, 'ibexamailing'); + }), + ], + ] + ); + + $ibexaMailingMenu->addChild( + 'ibexamailing_dashboard', + [ + 'route' => 'ibexamailing_dashboard_index', + 'label' => 'Dashboard', + ] + ); + + $ibexaMailingMenu->addChild( + 'ibexamailing_mailing_list', + [ + 'route' => 'ibexamailing_mailinglist_index', + 'label' => 'Liste de diffusion', + 'extras' => [ + 'routes' => [ + 'ibexamailing_mailinglist_show', + 'ibexamailing_mailinglist_index', + 'ibexamailing_mailinglist_create', + 'ibexamailing_mailinglist_remove', + 'ibexamailing_mailinglist_import', + ], + ], + ] + ); + $ibexaMailingMenu->addChild( + 'ibexamailing_user', [ - 'route' => 'novaezmailing_dashboard_index', - 'label' => 'Nova eZ Mailing', + 'route' => 'ibexamailing_user_index', + 'label' => 'Utilisateurs', + 'extras' => [ + 'routes' => [ + 'ibexamailing_user_remove', + 'ibexamailing_user_show', + ], + ], ] ); } @@ -36,7 +72,7 @@ public function onMainMenuConfigure(ConfigureMenuEvent $event): void public static function getSubscribedEvents() { return [ - ConfigureMenuEvent::MAIN_MENU => ['onMainMenuConfigure', 0], + ConfigureMenuEvent::MAIN_MENU => ['onMainMenuConfigure', -100], ]; } } diff --git a/bundle/Menu/Builder.php b/bundle/Menu/Builder.php index 1924e99..d8636ac 100644 --- a/bundle/Menu/Builder.php +++ b/bundle/Menu/Builder.php @@ -1,89 +1,32 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Menu; +namespace CodeRhapsodie\IbexaMailingBundle\Menu; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; +use CodeRhapsodie\IbexaMailingBundle\Repository\MailingRepository; +use CodeRhapsodie\IbexaMailingBundle\Repository\UserRepository; +use CodeRhapsodie\IbexaMailingBundle\Security\Voter\Campaign as CampaignVoter; use Doctrine\ORM\EntityManagerInterface; use Knp\Menu\FactoryInterface; use Knp\Menu\ItemInterface; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign; -use Novactive\Bundle\eZMailingBundle\Entity\Mailing; -use Novactive\Bundle\eZMailingBundle\Entity\User; -use Novactive\Bundle\eZMailingBundle\Security\Voter\Campaign as CampaignVoter; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Contracts\Translation\TranslatorInterface; class Builder { - private $translator; - - /** - * @var FactoryInterface - */ - private $factory; - - /** - * @var AuthorizationCheckerInterface - */ - private $authorizationChecker; - public function __construct( - FactoryInterface $factory, - AuthorizationCheckerInterface $authorizationChecker, - TranslatorInterface $translator + private readonly FactoryInterface $factory, + private readonly AuthorizationCheckerInterface $authorizationChecker, + private readonly TranslatorInterface $translator, + private readonly UserRepository $userRepository, + private readonly MailingRepository $mailingRepository ) { - $this->factory = $factory; - $this->authorizationChecker = $authorizationChecker; - $this->translator = $translator; - } - - public function createAdminMenu(RequestStack $requestStack): ItemInterface - { - $request = $requestStack->getMainRequest(); - $route = $request?->attributes->get('_route'); - $mailingRoute = 'novaezmailing_mailinglist'; - $userRoute = 'novaezmailing_user'; - - $menu = $this->factory->createItem('root'); - $child = $menu->addChild( - 'mailinglists', - [ - 'route' => "{$mailingRoute}_index", - 'label' => $this->translator->trans('menu.admin_menu.mailing_lists', [], 'ezmailing'), - ] - ); - - if (substr($route, 0, \strlen($mailingRoute)) === $mailingRoute) { - $child->setCurrent(true); - } - - $child = $menu->addChild( - 'users', - [ - 'route' => "{$userRoute}_index", - 'label' => $this->translator->trans('menu.admin_menu.users', [], 'ezmailing'), - ] - ); - if (substr($route, 0, \strlen($userRoute)) === $userRoute) { - $child->setCurrent(true); - } - - return $menu; } - public function createCampaignMenu(RequestStack $requestStack, EntityManagerInterface $entityManager): ItemInterface + public function createCampaignMenu(EntityManagerInterface $entityManager): ItemInterface { $menu = $this->factory->createItem('root'); $repo = $entityManager->getRepository(Campaign::class); @@ -91,8 +34,6 @@ public function createCampaignMenu(RequestStack $requestStack, EntityManagerInte $campaigns = $repo->findAll(); $mailingStatuses = Mailing::STATUSES; - $userRepo = $entityManager->getRepository(User::class); - $mailingRepo = $entityManager->getRepository(Mailing::class); foreach ($campaigns as $campaign) { if (!$this->authorizationChecker->isGranted(CampaignVoter::VIEW, $campaign)) { continue; @@ -104,15 +45,15 @@ public function createCampaignMenu(RequestStack $requestStack, EntityManagerInte ] ); - $count = $userRepo->countByFilters(['campaign' => $campaign]); + $count = $this->userRepository->countByFilters(['campaign' => $campaign]); $child->addChild( "camp_{$campaign->getId()}_subsciptions", [ - 'route' => 'novaezmailing_campaign_subscriptions', + 'route' => 'ibexamailing_campaign_subscriptions', 'routeParameters' => ['campaign' => $campaign->getId()], - 'label' => $this->translator->trans('menu.campaign_menu.subscriptions', [], 'ezmailing'). - " ({$count})", + 'label' => $this->translator->trans('menu.campaign_menu.subscriptions', [], 'ibexamailing') + ." ({$count})", 'attributes' => [ 'class' => 'leaf subscriptions', ], @@ -120,7 +61,7 @@ public function createCampaignMenu(RequestStack $requestStack, EntityManagerInte ); foreach ($mailingStatuses as $status) { - $count = $mailingRepo->countByFilters( + $count = $this->mailingRepository->countByFilters( [ 'campaign' => $campaign, 'status' => $status, @@ -129,7 +70,7 @@ public function createCampaignMenu(RequestStack $requestStack, EntityManagerInte $child->addChild( "mailing_status_{$status}", [ - 'route' => 'novaezmailing_campaign_mailings', + 'route' => 'ibexamailing_campaign_mailings', 'routeParameters' => [ 'campaign' => $campaign->getId(), 'status' => $status, @@ -137,7 +78,7 @@ public function createCampaignMenu(RequestStack $requestStack, EntityManagerInte 'label' => $this->translator->trans( 'generic.mailing_statuses.'.$status, [], - 'ezmailing' + 'ibexamailing' )." ({$count})", 'attributes' => [ 'class' => "leaf {$status}", @@ -154,9 +95,9 @@ public function createSaveCancelMenu(): ItemInterface { $menu = $this->factory->createItem('root'); $menu->addChild( - 'novaezmailing_save', + 'ibexamailing_save', [ - 'label' => $this->translator->trans('menu.savecancel.save', [], 'ezmailing'), + 'label' => $this->translator->trans('menu.savecancel.save', [], 'ibexamailing'), 'extras' => [ 'icon' => 'save', ], @@ -164,9 +105,9 @@ public function createSaveCancelMenu(): ItemInterface ); $menu->addChild( - 'novaezmailing_cancel', + 'ibexamailing_cancel', [ - 'label' => $this->translator->trans('menu.savecancel.cancel', [], 'ezmailing'), + 'label' => $this->translator->trans('menu.savecancel.cancel', [], 'ibexamailing'), 'attributes' => ['class' => 'btn-danger'], 'extras' => [ 'icon' => 'circle-close', diff --git a/bundle/NovaeZMailingBundle.php b/bundle/NovaeZMailingBundle.php deleted file mode 100644 index ad77c81..0000000 --- a/bundle/NovaeZMailingBundle.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - -declare(strict_types=1); - -namespace Novactive\Bundle\eZMailingBundle; - -use LogicException; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use Symfony\Component\HttpKernel\Bundle\Bundle; - -class NovaeZMailingBundle extends Bundle -{ - public function build(ContainerBuilder $container): void - { - parent::build($container); - } - - public function getContainerExtension(): ?ExtensionInterface - { - if (null === $this->extension) { - $extension = $this->createContainerExtension(); - if (null !== $extension) { - if (!$extension instanceof ExtensionInterface) { - throw new LogicException( - sprintf('Extension %s must implement '.ExtensionInterface::class.'.', \get_class($extension)) - ); - } - $this->extension = $extension; - } else { - $this->extension = false; - } - } - if ($this->extension) { - return $this->extension; - } - - return null; - } -} diff --git a/bundle/Repository/Broadcast.php b/bundle/Repository/Broadcast.php deleted file mode 100644 index 46e65b7..0000000 --- a/bundle/Repository/Broadcast.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - -declare(strict_types=1); - -namespace Novactive\Bundle\eZMailingBundle\Repository; - -class Broadcast extends EntityRepository -{ - protected function getAlias(): string - { - return 'broadcast'; - } - - public function findLastBroadcasts(int $limit = 4): array - { - $qb = $this->createQueryBuilderForFilters([]); - $qb->where("{$this->getAlias()}.emailSentCount > 0"); - $qb->setMaxResults($limit); - $qb->orderBy("{$this->getAlias()}.ended", 'DESC'); - - return $qb->getQuery()->getResult(); - } -} diff --git a/bundle/Repository/BroadcastRepository.php b/bundle/Repository/BroadcastRepository.php new file mode 100644 index 0000000..d874870 --- /dev/null +++ b/bundle/Repository/BroadcastRepository.php @@ -0,0 +1,37 @@ + + */ +class BroadcastRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Broadcast::class); + } + + /** + * @return array + */ + public function findLastBroadcasts(int $limit = 4): array + { + $qb = $this->createQueryBuilderForFilters(); + $qb->where("{$this->getAlias()}.emailSentCount > 0"); + $qb->setMaxResults($limit); + $qb->orderBy("{$this->getAlias()}.ended", 'DESC'); + + return $qb->getQuery()->getResult(); + } + + protected function getAlias(): string + { + return 'broadcast'; + } +} diff --git a/bundle/Repository/Campaign.php b/bundle/Repository/Campaign.php deleted file mode 100644 index f7cfe0a..0000000 --- a/bundle/Repository/Campaign.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - -declare(strict_types=1); - -namespace Novactive\Bundle\eZMailingBundle\Repository; - -class Campaign extends EntityRepository -{ - protected function getAlias(): string - { - return 'camp'; - } -} diff --git a/bundle/Repository/CampaignRepository.php b/bundle/Repository/CampaignRepository.php new file mode 100644 index 0000000..1a4288e --- /dev/null +++ b/bundle/Repository/CampaignRepository.php @@ -0,0 +1,24 @@ + + */ +class CampaignRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Campaign::class); + } + + protected function getAlias(): string + { + return 'camp'; + } +} diff --git a/bundle/Repository/ConfirmationToken.php b/bundle/Repository/ConfirmationToken.php deleted file mode 100644 index d163bbb..0000000 --- a/bundle/Repository/ConfirmationToken.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - -declare(strict_types=1); - -namespace Novactive\Bundle\eZMailingBundle\Repository; - -class ConfirmationToken extends EntityRepository -{ - protected function getAlias(): string - { - return 'confirmtok'; - } -} diff --git a/bundle/Repository/ConfirmationTokenRepository.php b/bundle/Repository/ConfirmationTokenRepository.php new file mode 100644 index 0000000..127349a --- /dev/null +++ b/bundle/Repository/ConfirmationTokenRepository.php @@ -0,0 +1,24 @@ + + */ +class ConfirmationTokenRepository extends EntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ConfirmationToken::class); + } + + protected function getAlias(): string + { + return 'confirmtok'; + } +} diff --git a/bundle/Repository/EntityRepository.php b/bundle/Repository/EntityRepository.php index 2f4dcf1..c567563 100644 --- a/bundle/Repository/EntityRepository.php +++ b/bundle/Repository/EntityRepository.php @@ -1,42 +1,44 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; -use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\ORM\EntityRepository as BaseEntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; -abstract class EntityRepository extends BaseEntityRepository +/** + * @template T of object + * + * @extends ServiceEntityRepository + */ +abstract class EntityRepository extends ServiceEntityRepository { - abstract protected function getAlias(): string; - + /** + * {@inheritDoc} + * + * @param array $filters + */ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder { return $this->createQueryBuilder($this->getAlias())->select($this->getAlias())->distinct(); } /** - * @return array|ArrayCollection + * @param array $filters + * + * @return array */ - public function findByFilters(array $filters = []) + public function findByFilters(array $filters = []): array { $qb = $this->createQueryBuilderForFilters($filters); return $qb->getQuery()->getResult(); } + /** + * @param array $filters + */ public function countByFilters(array $filters = []): int { $qb = $this->createQueryBuilderForFilters($filters); @@ -44,4 +46,6 @@ public function countByFilters(array $filters = []): int return (int) $qb->getQuery()->getSingleScalarResult(); } + + abstract protected function getAlias(): string; } diff --git a/bundle/Repository/MailingList.php b/bundle/Repository/MailingListRepository.php similarity index 58% rename from bundle/Repository/MailingList.php rename to bundle/Repository/MailingListRepository.php index 8ee6b76..f6000ae 100644 --- a/bundle/Repository/MailingList.php +++ b/bundle/Repository/MailingListRepository.php @@ -1,28 +1,26 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; -class MailingList extends EntityRepository +/** + * @extends EntityRepository + */ +class MailingListRepository extends EntityRepository { - protected function getAlias(): string + public function __construct(ManagerRegistry $registry) { - return 'ml'; + parent::__construct($registry, MailingList::class); } + /** + * @param array $filters + */ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder { $qb = parent::createQueryBuilderForFilters($filters); @@ -37,4 +35,9 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder return $qb; } + + protected function getAlias(): string + { + return 'ml'; + } } diff --git a/bundle/Repository/Mailing.php b/bundle/Repository/MailingRepository.php similarity index 65% rename from bundle/Repository/Mailing.php rename to bundle/Repository/MailingRepository.php index 8a70c4f..c38fbd7 100644 --- a/bundle/Repository/Mailing.php +++ b/bundle/Repository/MailingRepository.php @@ -1,32 +1,30 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; +use CodeRhapsodie\IbexaMailingBundle\Entity\Mailing; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; -class Mailing extends EntityRepository +/** + * @extends EntityRepository + */ +class MailingRepository extends EntityRepository { - protected function getAlias(): string + public function __construct(ManagerRegistry $registry) { - return 'mail'; + parent::__construct($registry, Mailing::class); } + /** + * @param array $filters + */ public function createQueryBuilderForFilters( array $filters = [], - ?string $orderBy = null, - ?int $limit = null + string $orderBy = null, + int $limit = null ): QueryBuilder { $qb = parent::createQueryBuilderForFilters($filters); if (isset($filters['campaign'])) { @@ -43,6 +41,9 @@ public function createQueryBuilderForFilters( return $qb; } + /** + * @return array + */ public function findLastUpdated(int $limit = 10): array { $qb = $this->createQueryBuilderForFilters([]); @@ -51,4 +52,9 @@ public function findLastUpdated(int $limit = 10): array return $qb->getQuery()->getResult(); } + + protected function getAlias(): string + { + return 'mail'; + } } diff --git a/bundle/Repository/Registration.php b/bundle/Repository/RegistrationRepository.php similarity index 70% rename from bundle/Repository/Registration.php rename to bundle/Repository/RegistrationRepository.php index f4545d3..c908c16 100644 --- a/bundle/Repository/Registration.php +++ b/bundle/Repository/RegistrationRepository.php @@ -1,30 +1,28 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign as CampaignEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\Registration; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign as CampaignEntity; +use Doctrine\Persistence\ManagerRegistry; -class Registration extends EntityRepository +/** + * @extends EntityRepository + */ +class RegistrationRepository extends EntityRepository { - protected function getAlias(): string + public function __construct(ManagerRegistry $registry) { - return 'reg'; + parent::__construct($registry, Registration::class); } + /** + * @param array $filters + */ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder { $qb = parent::createQueryBuilderForFilters($filters); @@ -41,7 +39,7 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder if (isset($filters['mailingLists'])) { $mailingLists = $filters['mailingLists']; } - if (null !== $mailingLists) { + if ($mailingLists !== null) { $qb->andWhere($qb->expr()->in('reg.mailingList', ':mailinglists'))->setParameter( 'mailinglists', $mailingLists @@ -56,4 +54,9 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder return $qb; } + + protected function getAlias(): string + { + return 'reg'; + } } diff --git a/bundle/Repository/StatHit.php b/bundle/Repository/StatHitRepository.php similarity index 77% rename from bundle/Repository/StatHit.php rename to bundle/Repository/StatHitRepository.php index 70810f9..bd10d8d 100644 --- a/bundle/Repository/StatHit.php +++ b/bundle/Repository/StatHitRepository.php @@ -1,36 +1,37 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; +use CodeRhapsodie\IbexaMailingBundle\Entity\Broadcast as BroadcastEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\StatHit; use Doctrine\ORM\QueryBuilder; -use Novactive\Bundle\eZMailingBundle\Entity\Broadcast as BroadcastEntity; +use Doctrine\Persistence\ManagerRegistry; -class StatHit extends EntityRepository +/** + * @extends EntityRepository + */ +class StatHitRepository extends EntityRepository { - protected function getAlias(): string + public function __construct(ManagerRegistry $registry) { - return 'stathit'; + parent::__construct($registry, StatHit::class); } + /** + * @param array $filters + */ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder { $qb = parent::createQueryBuilderForFilters($filters); + $broadcasts = null; + if (isset($filters['broadcasts'])) { $broadcasts = $filters['broadcasts']; } - if (null !== $broadcasts) { + + if ($broadcasts !== null) { $qb->andWhere($qb->expr()->in('stathit.broadcast', ':broadcasts'))->setParameter( 'broadcasts', $broadcasts @@ -42,8 +43,10 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder /** * @param BroadcastEntity[] $broadcasts + * + * @return array */ - public function getBrowserMapCount($broadcasts): array + public function getBrowserMapCount(array $broadcasts): array { $qb = $this->createQueryBuilderForFilters(['broadcasts' => $broadcasts]); $qb->select($qb->expr()->count($this->getAlias().'.id').' as nb', $this->getAlias().'.browserName'); @@ -60,8 +63,10 @@ public function getBrowserMapCount($broadcasts): array /** * @param BroadcastEntity[] $broadcasts + * + * @return array */ - public function getOSMapCount($broadcasts): array + public function getOSMapCount(array $broadcasts): array { $qb = $this->createQueryBuilderForFilters(['broadcasts' => $broadcasts]); $qb->select($qb->expr()->count($this->getAlias().'.id').' as nb', $this->getAlias().'.osName'); @@ -78,8 +83,10 @@ public function getOSMapCount($broadcasts): array /** * @param BroadcastEntity[] $broadcasts + * + * @return array */ - public function getURLMapCount($broadcasts): array + public function getURLMapCount(array $broadcasts): array { $qb = $this->createQueryBuilderForFilters(['broadcasts' => $broadcasts]); $qb->select($qb->expr()->count($this->getAlias().'.id').' as nb', $this->getAlias().'.url'); @@ -98,7 +105,7 @@ public function getURLMapCount($broadcasts): array /** * @param BroadcastEntity[] $broadcasts */ - public function getOpenedCount($broadcasts): int + public function getOpenedCount(array $broadcasts): int { $qb = $this->createQueryBuilderForFilters(['broadcasts' => $broadcasts]); $qb->select($qb->expr()->countDistinct($this->getAlias().'.userKey').' as nb'); @@ -109,8 +116,10 @@ public function getOpenedCount($broadcasts): int /** * @param BroadcastEntity[] $broadcasts + * + * @return array */ - public function getOpenedCountPerDay($broadcasts): array + public function getOpenedCountPerDay(array $broadcasts): array { $qb = $this->createQueryBuilderForFilters(['broadcasts' => $broadcasts]); $qb->select( @@ -129,4 +138,9 @@ public function getOpenedCountPerDay($broadcasts): array return $mappedResults; } + + protected function getAlias(): string + { + return 'stathit'; + } } diff --git a/bundle/Repository/User.php b/bundle/Repository/UserRepository.php similarity index 71% rename from bundle/Repository/User.php rename to bundle/Repository/UserRepository.php index 618f85a..2d2922c 100644 --- a/bundle/Repository/User.php +++ b/bundle/Repository/UserRepository.php @@ -1,31 +1,30 @@ - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZMailingBundle/blob/master/LICENSE MIT Licence - */ - declare(strict_types=1); -namespace Novactive\Bundle\eZMailingBundle\Repository; +namespace CodeRhapsodie\IbexaMailingBundle\Repository; +use CodeRhapsodie\IbexaMailingBundle\Entity\Campaign as CampaignEntity; +use CodeRhapsodie\IbexaMailingBundle\Entity\MailingList; +use CodeRhapsodie\IbexaMailingBundle\Entity\User; +use CodeRhapsodie\IbexaMailingBundle\Entity\User as UserEntity; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; -use Novactive\Bundle\eZMailingBundle\Entity\Campaign as CampaignEntity; -use Novactive\Bundle\eZMailingBundle\Entity\User as UserEntity; +use Doctrine\Persistence\ManagerRegistry; -class User extends EntityRepository +/** + * @extends EntityRepository + */ +class UserRepository extends EntityRepository { - protected function getAlias(): string + public function __construct(ManagerRegistry $registry) { - return 'u'; + parent::__construct($registry, User::class); } + /** + * @param array $filters + */ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder { $qb = parent::createQueryBuilderForFilters($filters); @@ -40,7 +39,7 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder if (isset($filters['mailingLists'])) { $mailingLists = $filters['mailingLists']; } - if (null !== $mailingLists) { + if ($mailingLists !== null) { $joinExpr = $qb->expr()->andX( $qb->expr()->in('reg.mailingList', ':mailingLists') ); @@ -72,7 +71,7 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder $qb->expr()->like('u.firstName', ':query'), $qb->expr()->like('u.lastName', ':query') ) - )->setParameter('query', '%' . $query . '%'); + )->setParameter('query', '%'.$query.'%'); } $qb->orderBy('u.created', 'DESC'); @@ -81,11 +80,11 @@ public function createQueryBuilderForFilters(array $filters = []): QueryBuilder } /** - * @param $mailingLists + * @param MailingList[] $mailingLists * - * @return array|\Doctrine\Common\Collections\ArrayCollection + * @return array */ - public function findValidRecipients($mailingLists) + public function findValidRecipients(array $mailingLists): array { return $this->findByFilters( [ @@ -96,7 +95,10 @@ public function findValidRecipients($mailingLists) ); } - public function countValidRecipients($mailingLists): int + /** + * @param MailingList[] $mailingLists + */ + public function countValidRecipients(array $mailingLists): int { return $this->countByFilters( [ @@ -107,6 +109,9 @@ public function countValidRecipients($mailingLists): int ); } + /** + * @return array + */ public function findLastUpdated(int $limit = 10): array { $qb = $this->createQueryBuilderForFilters([]); @@ -121,9 +126,14 @@ public function existByEmail(string $email): bool $qb = $this->createQueryBuilder('u'); return $qb->select('count(u.email)') - ->where($qb->expr()->eq('u.email', ":email")) - ->setParameter('email', $email) - ->getQuery() - ->getSingleScalarResult() > 0; + ->where($qb->expr()->eq('u.email', ':email')) + ->setParameter('email', $email) + ->getQuery() + ->getSingleScalarResult() > 0; + } + + protected function getAlias(): string + { + return 'u'; } } diff --git a/bundle/Resources/config/default_settings.yml b/bundle/Resources/config/default_settings.yml index f258160..c38f8fb 100644 --- a/bundle/Resources/config/default_settings.yml +++ b/bundle/Resources/config/default_settings.yml @@ -1,7 +1,7 @@ parameters: - nova_ezmailing.default.simple_mailer: ~ - nova_ezmailing.default.mailing_mailer: ~ - nova_ezmailing.default.email_subject_prefix: ~ - nova_ezmailing.default.email_from_address: ~ - nova_ezmailing.default.email_from_name: ~ - nova_ezmailing.default.email_return_path: ~ + ibexamailing.default.simple_mailer: ~ + ibexamailing.default.mailing_mailer: ~ + ibexamailing.default.email_subject_prefix: ~ + ibexamailing.default.email_from_address: ~ + ibexamailing.default.email_from_name: ~ + ibexamailing.default.email_return_path: ~ diff --git a/bundle/Resources/config/ezadminui.yml b/bundle/Resources/config/ezadminui.yml index 71e62c2..1db8159 100644 --- a/bundle/Resources/config/ezadminui.yml +++ b/bundle/Resources/config/ezadminui.yml @@ -1,28 +1,28 @@ services: - nova_ezmailing.ezadminui.component.stylesheets: + ibexamailing.ezadminui.component.stylesheets: parent: Ibexa\AdminUi\Component\TwigComponent public: false arguments: - $template: "@@NovaeZMailing/ezadminui/stylesheets.html.twig" + $template: "@@IbexaMailing/ezadminui/stylesheets.html.twig" tags: - { name: ibexa.admin_ui.component, group: 'stylesheet-head' } - nova_ezmailing.ezadminui.component.javascripts: + ibexamailing.ezadminui.component.javascripts: parent: Ibexa\AdminUi\Component\TwigComponent public: false arguments: - $template: "@@NovaeZMailing/ezadminui/javascripts.html.twig" + $template: "@@IbexaMailing/ezadminui/javascripts.html.twig" tags: - { name: ibexa.admin_ui.component, group: 'script-body' } - Novactive\Bundle\eZMailingBundle\Listener\LocationViewGroupTab: + CodeRhapsodie\IbexaMailingBundle\Listener\LocationViewGroupTab: autowire: true tags: - { name: kernel.event_listener, event: "ezplatform.tab.group.pre_render", method: "onTabGroupPreRender" } - Novactive\Bundle\eZMailingBundle\Core\Tab\Campaigns: + CodeRhapsodie\IbexaMailingBundle\Core\Tab\Campaigns: parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab - Novactive\Bundle\eZMailingBundle\Core\Tab\Mailings: + CodeRhapsodie\IbexaMailingBundle\Core\Tab\Mailings: parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab diff --git a/bundle/Resources/config/logger.yml b/bundle/Resources/config/logger.yml index 3d4a4bb..5fb66ed 100644 --- a/bundle/Resources/config/logger.yml +++ b/bundle/Resources/config/logger.yml @@ -1,14 +1,14 @@ --- # Monolog configuration -channels: ['novaezmailing'] +channels: [ 'ibexamailing' ] handlers: - novaezmailing: + ibexamailing: # log when email, push or sms are sent level: debug type: stream - path: '%kernel.logs_dir%/novaezmailing.log' - channels: ['novaezmailing'] - novaezmailingconsole: + path: '%kernel.logs_dir%/ibexamailing.log' + channels: [ 'ibexamailing' ] + ibexamailingconsole: type: console process_psr_3_messages: false - channels: ['novaezmailing'] + channels: [ 'ibexamailing' ] diff --git a/bundle/Resources/config/routing.yml b/bundle/Resources/config/routing.yml index fb4745d..3771389 100644 --- a/bundle/Resources/config/routing.yml +++ b/bundle/Resources/config/routing.yml @@ -1,13 +1,13 @@ -_novaezmailing_bundle: - resource: "@NovaeZMailingBundle/Controller" +_ibexamailing_bundle: + resource: "@IbexaMailingBundle/Controller" type: annotation - prefix: /novaezmailing + prefix: /ibexamailing -_novaezmailing_ez_content_view: - path: /novamailing/view/{locationId}/{contentId}/{mailingId} +_ibexamailing_ez_content_view: + path: /ibexamailing/view/{locationId}/{contentId}/{mailingId} defaults: _controller: ibexa_content:viewAction - viewType: novaezmailingfull + viewType: ibexamailingfull layout: true mailingId: null options: diff --git a/bundle/Resources/config/services.yml b/bundle/Resources/config/services.yml index 36ec09e..32cf3c9 100644 --- a/bundle/Resources/config/services.yml +++ b/bundle/Resources/config/services.yml @@ -6,105 +6,107 @@ services: autoconfigure: true public: false bind: - $logger: "@monolog.logger.novaezmailing" + $logger: "@monolog.logger.ibexamailing" string $kernelEnv: "%kernel.environment%" - Novactive\Bundle\eZMailingBundle\Command\: + CodeRhapsodie\IbexaMailingBundle\Command\: resource: '../../Command' tags: ["console.command"] - Novactive\Bundle\eZMailingBundle\Form\: + CodeRhapsodie\IbexaMailingBundle\Form\: resource: '../../Form' tags: [ "form.type" ] - Novactive\Bundle\eZMailingBundle\Security\Voter\: + CodeRhapsodie\IbexaMailingBundle\Security\Voter\: resource: '../../Security/Voter' tags: [ "security.voter" ] - Novactive\Bundle\eZMailingBundle\Controller\: + CodeRhapsodie\IbexaMailingBundle\Controller\: resource: '../../Controller' tags: [ 'controller.service_arguments' ] - Novactive\Bundle\eZMailingBundle\Listener\: + CodeRhapsodie\IbexaMailingBundle\Listener\: resource: '../../Listener' - Novactive\Bundle\eZMailingBundle\Core\Provider\: + CodeRhapsodie\IbexaMailingBundle\Core\Provider\: resource: '../../Core/Provider' - Novactive\Bundle\eZMailingBundle\Core\Registrar: ~ + CodeRhapsodie\IbexaMailingBundle\Core\Registrar: ~ - Novactive\Bundle\eZMailingBundle\Core\Processor\: + CodeRhapsodie\IbexaMailingBundle\Core\Processor\: resource: '../../Core/Processor' - Novactive\Bundle\eZMailingBundle\Core\Import\: + CodeRhapsodie\IbexaMailingBundle\Core\Import\: resource: '../../Core/Import' + CodeRhapsodie\IbexaMailingBundle\Repository\: + autowire: true + autoconfigure: true + resource: '../../Repository' - Novactive\Bundle\eZMailingBundle\Core\Processor\TestMailingProcessorInterface: '@Novactive\Bundle\eZMailingBundle\Core\Processor\TestMailing' - Novactive\Bundle\eZMailingBundle\Core\Processor\SendMailingProcessorInterface: '@Novactive\Bundle\eZMailingBundle\Core\Processor\SendMailing' + CodeRhapsodie\IbexaMailingBundle\Core\Processor\TestMailingProcessorInterface: '@CodeRhapsodie\IbexaMailingBundle\Core\Processor\TestMailing' + CodeRhapsodie\IbexaMailingBundle\Core\Processor\SendMailingProcessorInterface: '@CodeRhapsodie\IbexaMailingBundle\Core\Processor\SendMailing' - Novactive\Bundle\eZMailingBundle\Core\Modifier\: + CodeRhapsodie\IbexaMailingBundle\Core\Modifier\: resource: '../../Core/Modifier' - tags: [ novaezmailing.content.modifier ] + tags: [ ibexamailing.content.modifier ] - Novactive\Bundle\eZMailingBundle\Core\Provider\MailingContent: - arguments: [ !tagged novaezmailing.content.modifier ] + CodeRhapsodie\IbexaMailingBundle\Core\Provider\MailingContent: + arguments: [ !tagged ibexamailing.content.modifier ] - Novactive\Bundle\eZMailingBundle\Menu\Builder: + CodeRhapsodie\IbexaMailingBundle\Menu\Builder: arguments: ["@knp_menu.factory"] - novaezmailing.menu.main: - class: Knp\Menu\MenuItem - factory: ['@Novactive\Bundle\eZMailingBundle\Menu\Builder','createAdminMenu'] - arguments: ["@request_stack"] - tags: - - { name: knp_menu.menu, alias: novaezmailing.menu.admin } - - novaezmailing.menu.campaigns: + ibexamailing.menu.campaigns: class: Knp\Menu\MenuItem - factory: ['@Novactive\Bundle\eZMailingBundle\Menu\Builder','createCampaignMenu'] - arguments: ["@request_stack"] + factory: [ '@CodeRhapsodie\IbexaMailingBundle\Menu\Builder','createCampaignMenu' ] tags: - - { name: knp_menu.menu, alias: novaezmailing.menu.campaigns } + - { name: knp_menu.menu, alias: ibexamailing.menu.campaigns } - novaezmailing.menu.save_cancel: + ibexamailing.menu.save_cancel: class: Knp\Menu\MenuItem - factory: ['@Novactive\Bundle\eZMailingBundle\Menu\Builder','createSaveCancelMenu'] + factory: [ '@CodeRhapsodie\IbexaMailingBundle\Menu\Builder','createSaveCancelMenu' ] tags: - - { name: knp_menu.menu, alias: novaezmailing.menu.save_cancel } + - { name: knp_menu.menu, alias: ibexamailing.menu.save_cancel } - Novactive\Bundle\eZMailingBundle\Core\AjaxGuard: ~ + CodeRhapsodie\IbexaMailingBundle\Core\AjaxGuard: ~ - Novactive\Bundle\eZMailingBundle\Listener\EntityContentLink: + CodeRhapsodie\IbexaMailingBundle\Listener\EntityContentLink: tags: - { name: doctrine.orm.entity_listener } - Novactive\Bundle\eZMailingBundle\Listener\MailingWorkflow: + CodeRhapsodie\IbexaMailingBundle\Listener\MailingWorkflow: tags: - { name: kernel.event_listener, event: workflow.mailing.leave } - Novactive\Bundle\eZMailingBundle\Listener\PreContentView: + CodeRhapsodie\IbexaMailingBundle\Listener\PreContentView: tags: - { name: kernel.event_listener, event: ezpublish.pre_content_view, method: onPreContentView } - Novactive\Bundle\eZMailingBundle\Core\Mailer\Simple: + CodeRhapsodie\IbexaMailingBundle\Core\Mailer\Simple: autowire: true arguments: - $simpleMailer: '%nova_ezmailing.default.simple_mailer%' + $simpleMailer: '%ibexamailing.default.simple_mailer%' - Novactive\Bundle\eZMailingBundle\Core\Mailer\Mailing: + CodeRhapsodie\IbexaMailingBundle\Core\Mailer\Mailing: autowire: true arguments: - $mailing: '%nova_ezmailing.default.mailing_mailer%' + $mailing: '%ibexamailing.default.mailing_mailer%' # Twig - Novactive\Bundle\eZMailingBundle\Twig\Extension: + CodeRhapsodie\IbexaMailingBundle\Twig\Extension: tags: ['twig.extension'] # Doctrine - Novactive\Bundle\eZMailingBundle\DataFixtures\: + CodeRhapsodie\IbexaMailingBundle\DataFixtures\: resource: '../../DataFixtures' tags: ['doctrine.fixture.orm'] - Novactive\Bundle\eZMailingBundle\Core\IOService: + CodeRhapsodie\IbexaMailingBundle\Core\IOService: arguments: [ '@ibexa.core.io.service' ] + + CodeRhapsodie\IbexaMailingBundle\Core\Mailer\MailingProcess: + autowire: true + arguments: + $projectDir: '%kernel.project_dir%' + diff --git a/bundle/Resources/config/views.yml b/bundle/Resources/config/views.yml index dc9ecf4..4b76049 100644 --- a/bundle/Resources/config/views.yml +++ b/bundle/Resources/config/views.yml @@ -1,8 +1,8 @@ system: default: content_view: - novaezmailingfull: + ibexamailingfull: generic: - template: "@NovaeZMailing/eZViews/novaezmailingfull/generic.html.twig" + template: "@IbexaMailing/eZViews/ibexamailingfull/generic.html.twig" match: Identifier\ContentType: ['-'] diff --git a/bundle/Resources/config/workflow.yml b/bundle/Resources/config/workflow.yml index 18acdb7..461ee0e 100644 --- a/bundle/Resources/config/workflow.yml +++ b/bundle/Resources/config/workflow.yml @@ -5,7 +5,7 @@ workflows: type: 'method' property: 'status' supports: - - Novactive\Bundle\eZMailingBundle\Entity\Mailing + - CodeRhapsodie\IbexaMailingBundle\Entity\Mailing places: - draft - tested diff --git a/bundle/Resources/doc/INSTALL.md b/bundle/Resources/doc/INSTALL.md index 9160674..ffa6eb6 100644 --- a/bundle/Resources/doc/INSTALL.md +++ b/bundle/Resources/doc/INSTALL.md @@ -2,7 +2,7 @@ ## Installation steps -Run `composer require novactive/ezmailingbundle` to install the bundle and its dependencies: +Run `composer require code-rhapsodie/ibexamailingbundle` to install the bundle and its dependencies: ### Register the bundle @@ -15,10 +15,9 @@ public function registerBundles() { ... $bundles = array( - new FrameworkBundle(), ... - // NovaeZMailingBundle - new Novactive\Bundle\eZMailingBundle\NovaeZMailingBundle(), + // IbexaMailingBundle + new CodeRhapsodie\IbexaMailingBundle\IbexaMailingBundle(), ); ... } @@ -27,20 +26,20 @@ public function registerBundles() ### Add routes ```yaml -_novaezmailing_routes: - resource: '@NovaeZMailingBundle/Resources/config/routing.yml' +_ibexamailing_routes: + resource: '@IbexaMailingBundle/Resources/config/routing.yml' ``` ### Add configuration -You need to declare a template for the view `novaezmailingfull` +You need to declare a template for the view `ibexamailingfull` ```yaml ezpublish: system: default: content_view: - novaezmailingfull: + ibexamailingfull: folder: template: yourtemplatepath match: @@ -53,52 +52,45 @@ ezpublish: You also need 2 mailers, 1 in charge to send the Mailings, the other to send the service emails. ```yaml -nova_ezmailing: +ibexamailing: system: default: simple_mailer: "swiftmailer.mailer.local_mailer" mailing_mailer: "swiftmailer.mailer.remote_mailer" # Default email values - email_subject_prefix: "[NovaeZMailing]" - email_from_address: "no-reply@novactive.com" - email_from_name: "Novactive" - email_return_path: "return-path@novactive.com" + email_subject_prefix: "[IbexaMailing]" + email_from_address: "no-reply@code-rhapsodie.fr" + email_from_name: "IbexaMailing" + email_return_path: "return-path@code-rhapsodie.fr" ``` Example in dev mode ```yaml -swiftmailer: - default_mailer: myfirst_mailer - mailers: - myfirst_mailer: - transport: 'smtp' - host: 127.0.0.1 - port: 1025 - spool: { type: memory } - mysecond_mailer: - transport: 'smtp' - host: 127.0.0.1 - port: 1025 - spool: { type: memory } - -nova_ezmailing: +framework: + mailer: + transports: + main: '%env(MAILER_DSN)%' + + +ibexamailing: system: default: - simple_mailer: "swiftmailer.mailer.myfirst_mailer" - mailing_mailer: "swiftmailer.mailer.mysecond_mailer" + simple_mailer: "main" + mailing_mailer: "main" ``` - ### Add the tables ```bash -bin/console novaezmailing:install +bin/console ibexamailing:install ``` ### Specify the Default Mailing List Id -To be able to implement the subscription form by doing subrequest to `novaezmailing_registration_default_create` route the default Mailing List Id should be specified in the configuration file. -It should be added to the `default` section under the `nova_ezmailing` namespace. + +To be able to implement the subscription form by doing subrequest to `ibexamailing_registration_default_create` route +the default Mailing List Id should be specified in the configuration file. +It should be added to the `default` section under the `ibexamailing` namespace. If you need to the other mailing list id value for some particular site access it should be added to the corresponding section in the configuration file. diff --git a/bundle/Resources/doc/USAGE.md b/bundle/Resources/doc/USAGE.md index 851cded..201d420 100644 --- a/bundle/Resources/doc/USAGE.md +++ b/bundle/Resources/doc/USAGE.md @@ -1,17 +1,17 @@ # Usage -This **NovaEzMailing** Bundle is the upgraded version of **CJW Newsletter** and **Ez Mailing** bundles. +This **IbexaMailing** Bundle is the upgraded version of **CJW Newsletter** and **Ez Mailing** bundles. After the bundle is installed within _Ez Platform_ which already contains one of those old bundles the database can be migrated to the new Bundle. 1. If the old bundle is **CJW Newletter** run the following commands inside _ezplatform_ folder: - - php bin/console novaezmailing:migrate:cjwnl --export - - php bin/console novaezmailing:migrate:cjwnl --import + - php bin/console ibexamailing:migrate:cjwnl --export + - php bin/console ibexamailing:migrate:cjwnl --import 2. If the old bundle is **Ez Mailing** run the following commands inside _ezplatform_ folder: - - php bin/console novaezmailing:migrate:ezmailing --export - - php bin/console novaezmailing:migrate:ezmailing --import + - php bin/console ibexamailing:migrate:ibexamailing --export + - php bin/console ibexamailing:migrate:ibexamailing --import The first one exports the data from the old database to json files. The second one imports the data from json files to the new database. @@ -34,9 +34,10 @@ What the migration script does: - We take and save only those subscriptions for the users which are related to existing mailing lists. - We don't migrate amy mailings here because there is not enough data for that. +There is also the option for both cases to truncate the current **IbexaMailing** **Bundle** tables in the database: -There is also the option for both cases to truncate the current **NovaEzMailing** **Bundle** tables in the database: -- php bin/console novaezmailing:migrate:cjwnl --clean +- php bin/console ibexamailing:migrate:cjwnl --clean or -- php bin/console novaezmailing:migrate:ezmailing --clean \ No newline at end of file + +- php bin/console ibexamailing:migrate:ibexamailing --clean \ No newline at end of file diff --git a/bundle/Resources/encore/ibexa.config.js b/bundle/Resources/encore/ibexa.config.js index 362bded..9db9489 100644 --- a/bundle/Resources/encore/ibexa.config.js +++ b/bundle/Resources/encore/ibexa.config.js @@ -9,13 +9,12 @@ if (fs.existsSync(subItemsModule)) { module.exports = (Encore) => { Encore .autoProvidejQuery() - .addEntry('nova_ezmailing', [ - path.resolve(__dirname, '../public/admin/css/ezmailing.scss'), - path.resolve(__dirname, '../public/admin/css/tree.scss'), + .addEntry('ibexamailing', [ + path.resolve(__dirname, '../public/admin/css/ibexamailing.scss'), path.resolve(__dirname, '../public/admin/js/jquery.autocomplete.min.js'), path.resolve(__dirname, '../public/admin/js/jquery.peity.min.js'), path.resolve(__dirname, '../public/admin/js/Chart.min.js'), - path.resolve(__dirname, '../public/admin/js/ezmailing.js'), + path.resolve(__dirname, '../public/admin/js/ibexamailing.js'), subItemsModule ]); }; diff --git a/bundle/Resources/public/admin/css/ezmailing.scss b/bundle/Resources/public/admin/css/ezmailing.scss deleted file mode 100644 index 5a76686..0000000 --- a/bundle/Resources/public/admin/css/ezmailing.scss +++ /dev/null @@ -1,207 +0,0 @@ -$eZDarkBackground: #555555; -$eZMediumBackground: #E5E3E3; -$eZLightBackground: #F5F5F5; - -.novaezmailing-app { - - h1, h2, h3 { - color: rgba(51, 51, 51, .9); - } - - a[data-toggle="popover"] { - cursor: pointer; - } - - header { - .navbar.ez-page-title { - padding-top: 0 !important; - padding-bottom: 0 !important; - display:flex; - } - .ez-header-container { - background: $eZMediumBackground; - } - border-bottom: 2px solid $eZMediumBackground; - input[type="search"] { - background: #fff; - color: #000; - } - } - .sidebar { - padding-top: 5px; - li.current { - a { - font-weight: bold; - color: #F05A22; - } - } - } - .innercontent { - padding-left: 0; - padding-right: 0; - .novaezmailing-tabs-content { - padding: 10px; - border: 2px solid #E5E3E3; - border-top: none; - max-height: 400px; - height: 400px; - overflow: auto; - } - .novaezmailing-ez-content-view { - - .container { - width: 100% !important; - max-width: 100% !important; - padding: 0; - } - .ez-raw-content-title, .ez-fieldgroup-name { - display: none !important; - } - - .ez-fieldgroup .ez-content-field { - padding: 0; - } - } - - .novaezmailing-registration-approbation { - button:not([disabled]) { - cursor: pointer; - } - } - - } - .novaezmailing-broadcast-charts-group { - clear: both; - } - - .ez-context-menu { - padding-top: 30px; - } - - form { - .form-check { - .form-check-label { - display: inline-block; - } - } - - .form-group { - .d-block { - display: inline !important; - } - } - fieldset.form-group legend { - font-weight: 700; - font-size: 14px; - color: #555; - margin-bottom: 0; - margin-top: 20px; - } - - } - .item-tabs-content { - padding-bottom: 35px; - } - .novaezmailing-button-actions { - padding: 5px; - a, button { - svg { - fill: #fff; - } - span { - color: #fff; - margin-top: 7px; - padding-left: 5px; - display: block; - float: right; - } - } - } - - .edit-button svg { - fill: #f15a10; - width: 20px; - height: 20px; - } - - table.excel-example { - th, td { - padding: 0; - } - font-size: 10px; - - } - footer { - p { - padding-top: 25px; - font-size: 0.75em; - color: #ddd; - text-align: center; - width: 100%; - } - } -} - -.novaezmailing-ez-mailings-view { - .edit-button svg { - fill: #f15a10; - width: 20px; - height: 20px; - } - - .edit-button.disabled svg { - fill: #ccc; - } -} - -.autocomplete-suggestions { - border: 1px solid #999; - background: #FFF; - overflow: auto; - .autocomplete-suggestion { - padding: 2px 5px; - white-space: nowrap; - overflow: hidden; - cursor: pointer; - } - .autocomplete-selected { - background: #F0F0F0; - } - .autocomplete-suggestions strong { - font-weight: normal; - color: #3399FF; - } - .autocomplete-group { - padding: 2px 5px; - } - .autocomplete-group strong { - display: block; - border-bottom: 1px solid #000; - } -} - -.tab-pane { - .novaezmailing-broadcast-charts-group .graph-broadcast { - width: 600px; - height: 300px; - float: left; - margin: 20px 10px 10px 10px; - } -} - -.campaigns > ul > li > label:hover { - font-weight: bold; -} - -.text-bg-dark-blue { - color: white !important; - background-color: #00008B !important; -} - -.start-75 { - left: 75% !important; -} - -.top-20 { - top: 20% !important; -} \ No newline at end of file diff --git a/bundle/Resources/public/admin/css/ibexamailing.scss b/bundle/Resources/public/admin/css/ibexamailing.scss new file mode 100644 index 0000000..c2b58f3 --- /dev/null +++ b/bundle/Resources/public/admin/css/ibexamailing.scss @@ -0,0 +1,126 @@ +$eZDarkBackground: #555555; +$eZMediumBackground: #E5E3E3; +$eZLightBackground: #F5F5F5; + +.ibexamailing-ez-mailings-view { + .edit-button svg { + width: 20px; + height: 20px; + } + + .edit-button.disabled svg { + fill: #ccc; + } +} +.edit-button { + text-decoration: none ; +} +.edit-button:hover { + text-decoration: none ; +} +.ibexa-btn--tertiary.ibexa-btn:focus { + border-color:none; +} +.toggle-button-menu { + justify-content: flex-start; +} +.ibexa-btn:focus { + box-shadow: none; +} +.c-list-item__row { + cursor: pointer; +} +.bage-status{ + padding: 10px !important; + border-radius: 5px !important; +} +.text-bg-success { + color: white !important; + background-color: #56c356 !important; +} +.text-bg-warning { + color: white !important; + background-color: #f99275 !important; +} +.text-bg-info { + color: white !important; + background-color: #188090 !important; +} + +.pagination { + justify-content: center !important; +} + +.autocomplete-suggestions { + border: 1px solid #999; + background: #FFF; + overflow: auto; + + .autocomplete-suggestion { + padding: 2px 5px; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + } + + .autocomplete-selected { + background: #F0F0F0; + } + + .autocomplete-suggestions strong { + font-weight: normal; + color: #3399FF; + } + + .autocomplete-group { + padding: 2px 5px; + } + + .autocomplete-group strong { + display: block; + border-bottom: 1px solid #000; + } +} +.label-subject { + margin-bottom: 30px; +} +.leaf a { + align-items: center; + color: #131c26; + display: flex; + flex: 1; + font-size: .875rem; + line-height: 1.3125rem; + min-height: 1.3125rem; + overflow: hidden; + padding: 0.3125rem 0.875rem 0.3125rem 0; + position: relative; + text-decoration: none; + white-space: nowrap; +} + +.tab-pane { + .ibexamailing-broadcast-charts-group .graph-broadcast { + width: 600px; + height: 300px; + float: left; + margin: 20px 10px 10px 10px; + } +} + +.campaigns > ul > li > label:hover { + font-weight: bold; +} + +.text-bg-dark-blue { + color: white !important; + background-color: #00008B !important; +} + +.start-75 { + left: 75% !important; +} + +.top-20 { + top: 20% !important; +} \ No newline at end of file diff --git a/bundle/Resources/public/admin/css/tree.scss b/bundle/Resources/public/admin/css/tree.scss deleted file mode 100755 index f9bad7d..0000000 --- a/bundle/Resources/public/admin/css/tree.scss +++ /dev/null @@ -1,134 +0,0 @@ -.novaezmailing-app .sidebar .campaigns { - /* CSS Tree menu styles */ - ul { - padding: 0 0 0 30px; - width: auto; - - li { - position: relative; - margin-left: -15px; - list-style: none; - background: url(/bundles/novaezmailing/admin/images/16x16/toggle-small-expand.png) -3px 3px no-repeat; - - input { - position: absolute; - left: -3px; - margin-left: 0; - opacity: 0; - z-index: 2; - cursor: pointer; - height: 1em; - width: 1em; - top: 3px; - } - - input + ul { - margin: -27px 0 0 -44px; - height: 21px; - } - - input + ul > li { - display: none; - margin-left: -14px !important; - padding-left: 1px; - } - - label { - background-repeat: no-repeat; - background-position: 15px 4px; - cursor: pointer; - display: block; - padding-left: 37px; - } - - input:checked + ul { - margin: -32px 0 0 -44px; - padding: 1.563em 0 0 80px; - height: auto; - } - - input:checked + ul > li { - display: block; - margin: 0 0 0.125em; - } - - input:checked + ul > li:last-child { - margin: 0 0 0.063em; - } - } - - li.expand { - background: url(/bundles/novaezmailing/admin/images/16x16/toggle-small.png) -3px 3px no-repeat; - } - - li.leaf { - margin-left: -13px !important; - a { - background-position: 0 3px; - background-repeat: no-repeat; - padding-left: 21px; - text-decoration: none; - display: block; - } - } - - li label { - background-image: url(/bundles/novaezmailing/admin/images/16x16/campaign.png); - } - li.aborted a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/aborted.png); - } - li.archived a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/archived.png); - } - li.sent a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/sent.png); - } - li.processing a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/processing.png); - } - li.pending a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/pending.png); - } - li.draft a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/draft.png); - } - li.tested a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/tested.png); - } - li.subscriptions a { - background-image: url(/bundles/novaezmailing/admin/images/16x16/subscriptions.png); - } - } - - ul.kcode { - li label { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/campaign.png); - } - li.aborted a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/aborted.png); - } - li.archived a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/archived.png); - } - li.sent a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/sent.png); - } - li.processing a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/processing.png); - } - li.pending a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/pending.png); - } - li.draft a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/draft.png); - } - li.tested a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/tested.png); - } - li.subscriptions a { - background-image: url(/bundles/novaezmailing/admin/images/kcode/16x16/subscriptions.png); - } - } - -} diff --git a/bundle/Resources/public/admin/images/16x16/aborted.png b/bundle/Resources/public/admin/images/16x16/aborted.png deleted file mode 100644 index 6053e530f07012ceda7a33a0cfc9592aa6264c19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 709 zcmV;$0y_PPP)o zN&_$FDvFdC4PgAJUlo$uG>0Qy$<@Faza%WndKgW{LSEgc$fdN4Xa^ilce?QLvxCjw9JddgIgav&0t&f0Vu=uf@!e7sz_Qw1Yt$+A z{AICRgB%KC$zo#quF9GO)y_A3p7!M|asoQh`Ch5XSE+-YB=fbTc4H~h2 z%f@!~DYr%%EN2?vIRmN0AOz(!Xgo5XR`4UpR^^H0xN-ailgaRP-7O|M{&LfJeD!_t r2E)H2Or~$~m&l4teoX&^p8^a3wRO&udI;R|00000NkvXXu0mjf%#}t0 diff --git a/bundle/Resources/public/admin/images/16x16/aborted.svg b/bundle/Resources/public/admin/images/16x16/aborted.svg new file mode 100644 index 0000000..929baa2 --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/aborted.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/archived.png b/bundle/Resources/public/admin/images/16x16/archived.png deleted file mode 100644 index 268e269bba5eef66472b032dfb8d87a1b2036f07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 560 zcmV-00?+-4P)D2hfdcvevqiD-JKG1`-l!w2;PW;|A*+4RM;7 z9LDT?MglR+ibj_kwKLeteyO%z&sDw2LOGRo#QA9d97pvFimiJxN&Mt!LV;cai@Qwzt5o)^mIgEf;%X}2sQ-V;o06> z#O&6?_=mBqz6L(I3*iYu0v~a@#hBGm0*K1x_$>l{l2IS;p1h*9-B|(9%`t|tOmMrs y`Z3Pbs>1>@?VBYm4<%~$e-@)w-Inu%00RK`RHa_|mzNs=0000 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/campaign.png b/bundle/Resources/public/admin/images/16x16/campaign.png deleted file mode 100644 index 886ee81bea5ed4583e4056ac10dfb1008ac33319..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh*)icxGNo zet9uiy|1s8XI^nhVqS8pr;Du;&;-5A%oHm}Gh-Jc3r90U14jcxLsw%96Eky1a|$o&6x?nx#i>^x=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6+B;Hy6$1lPy{C&~ zNX4xs!QLJrffE1D?JRfOc#JJ@!v#)p$!#3f0jmoH1Fgf~E%s1~+M>0}Rp8n(SC7C) z$Cz{%GG#A+xH#&|rW`dV582{LXFYRVL7vcZE!=}jE!)*H0)Fs>}L;`GHTela!xu$XQ zK6A>{PEo(Rc0#SG%>HSO6VF$^s9$@z{FYmIW}DTw@0!-vb*8iiMIB^ieImiz=(UC4 z@9~|3R(ochXTKlJ8S`$wTXLOP{1+?w7*4a;dS0;ku7UWdfB}zXj^WV3H#+w^8V4PHumC;MQ}^m*;+WbXv6T zR=@jUw_R4dY5^tWnB1|Z;{~+eqXpvy=eN>(|Oz{Z|G!|nKPaf?+}{* zddl-R=S`k7%;Q>;l<2Zw?@M<2cioJ|B{q$lc10;nZZP=6x^2CpYTc3hJ&9?0w|D>2 zYm#LbW1ZrEbI+lx>|4qhVg)`c?)?0uprOCp^|V`g(tkahRF>{`c_tnPx39i}*2})l P02R-ku6{1-oD!M<43$9q diff --git a/bundle/Resources/public/admin/images/16x16/campaign.svg b/bundle/Resources/public/admin/images/16x16/campaign.svg new file mode 100644 index 0000000..b26ef60 --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/campaign.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/draft.png b/bundle/Resources/public/admin/images/16x16/draft.png deleted file mode 100644 index 3319a469b9d8793e30ae8897d536495392b9a86e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh*)icxGNo zet9uiy|1s8XI^nhVqS8pr;Du;&;-5A%oHnUXG>EHM+-AU19LM&Lsw%93sW;kXH!FC zV^c#@7Z*pEUYGpj(%jU%5}4i;gkE!;dO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrc z(>$o&6x?nx#i>^x=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6dPCWdcMJ@Szz}c@ zskk*~@_IjJM}cGMWzYWDGEVp)(!s{aCNznynUT4z;ZOi0r;14TVZ{v+L6;r~EU4gp zz`9~(!#nx3ZFe89i{UJpboOoTx8KjU8}F{T{&rvV^G^?KS$;$>;7e}ktjbw?_WEq! z8ESdfbLTiqJgcp&WpXXLhrfyyLLS3j3^P6 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/mailinglist.png b/bundle/Resources/public/admin/images/16x16/mailinglist.png deleted file mode 100644 index a7f0bed89cb9fca9ad97b5ac4b314070b83ff84f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1579 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh*)icxGNo zet9uiy|1s8XI^nhVqS8pr;Du;&;-5A%oHnEH&+)+7bi1A14~OoLsw%*0~cdg6AJ?; zXGaTTH&;iPUYGpj(%jU%5}4i;gkE!;dO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrc z(>$o&6x?nx#i>^x=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6`jC>_Jq8A*`JOJ0 zAr-e;f}=e|0ww;Pn<-gdI=$@WBFPyOLZ*m>eM=CFUGhP-Lr-6kL-CR`|I=s}PB&K; zK^9il#1Ju+tKFQLsR3mh-yZy+$R(s?dObF}y!80onZ>`(pQ+$%s{8S5{(t-DHUHnr zT&sO=kkz%Haps-W89R5Mxcu5cFn^cP7IEE0a*1h8&I$WG4sB5m*k7b+5xz`>IZa~^ zuWNVGGS%&q7RP&WIu^7jc!&r6VhP$6aESTNtCusQ_M1hBtXv|@QB?hTwaZVd%bQZP zvQKW*j8@yUZO)8sspka!b8aR745-}rsyp}7*J<7jvJA)SgeSFF6g<)v(E6?Y^}|d* z7M^o`>mu7^1T~E63_i(mgt7DopZy%f(di2CC zCb6#$Q%_vDqn-LS@(8}HrQp}Iv2&TVjP`b*j z#QdhN>qU3)3%NB%*X|NZ$$WUcgZJE?KJCOW%ilDdE7-cY-oB&9W5zj+u1P0jpD(!k zV)3qq&;0hvGiM#y-y+<-PGN^h$-FD+Nn7myI|a&I_gZ4K<61=PmbXjoXSbbd*_0sD z5y0lVJ(>IGnIz}4S^37F`DR)^aC~pT!!EI4Ax}?Ll=|;~vlC~y=q(9IJ+nVaXjZ

NT3x!+`RB5%#Jp{VfBbl^$ViC?Y->36!=$N8v^8VLziU@dh1J=Ki;K4S ze!h6)mipzAoArW^T2vD6Tra%8{+e{Oy;oS(!qaaTyY??zWzco0KrZNU=kzMal=doz wd$J$wi}Dm^S^F)K{HOa$(B)%&;Xe)o2EHKg@9!3AT7ZggPgg&ebxsLQ03YO4$N&HU diff --git a/bundle/Resources/public/admin/images/16x16/mailinglist.svg b/bundle/Resources/public/admin/images/16x16/mailinglist.svg new file mode 100644 index 0000000..78e81cc --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/mailinglist.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/pending.png b/bundle/Resources/public/admin/images/16x16/pending.png deleted file mode 100644 index 1b3d933ec95cb57a03160c5a83cf87888371893f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmV;>0x$iEP)u%e+BR~}Db?Lxri0Lp0#mnFWIskW{Th$cV7-{3Pm+$(T;kruMV3`qAw zg80Z}1Duv*0?>xIoSeqWW%Y2E0kc*z1E3K=q(V;VR*8)bd{Rk14jM7%f+$1r5#5<#>h((<)i~_4fxEMw3aOB6dQq5VYbNUKrNae z8{hDCjLvEc*rDiEQiy0`Ei6EyJ^7=6DPb>2$~pSQ;K z;Ui6Iv7r8*RT~YRXow8z4@H^ruDN(Cybnl^0fPhR)xVueq+%yV5lOt{78j}fFOoK% zg?{=8^w2Tfr}uhZk0joJ&Ed;!wtn-Z@n6NC0t^6+_RdM=XhQ=40000 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/processing.png b/bundle/Resources/public/admin/images/16x16/processing.png deleted file mode 100644 index b95136c9cfe58d602f606db8ad61afdec68e6a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmV-!1CjiRP)Wsim$6 za?M$27a1%JDxtbCD6;6nizyM(dnI<98pM-SNjfGHBSzTmk7zR2-2sI_$r@0C@ zr&B}ARGdHCzMbClsTD!*$KgHayuasppO01Et%49qk~FQVDhvh#!r?F{0b@+qn7CgP zvi;s`QNocf8)(&w{qpiMg25p2?RHIzvk0OjKS;k8KK~|Y*uH(+F{?G@L?95Dq97h0 z7l&R&fzaZ-w6qjXO|@ebOf$7B^Ab)1emv&QTy}}l~oy& zR)CZQ+9KFwO2oW>0S3JupIt6^hrO>})Yat-dq!T3jZC4eb2lFLB%xn^KtWNQahcP6 zAdB%76clLfOioQgZ_q;x0nU#~Wmnhx-k8YvZ|RoIlQLDy+gFSytO_By4RYThNV+h@ zJ*um#VX;_{u`>gVKD{my@!8$=2ajTNINXG%{w4$|DOfCy?8?R4{+IZo_h5S6NAd=2 zBFUx8SGw&qcU28zVMax1hYioq-p5>^nJ|(xTq2}wIKCDkW6LQtE4Ao!;iX(weyv9s z1Hk|v8y#cG$;mL962OUg-cufxHn+5A;vgBF9#Mj=`E-X_bXP($mse+Kx2% z#>YWJhK?RLi#{0QfCyR!BcP8W;zX|KH%bjc^JtYtb-&;5B)%VTI2=%%%1q04J9NZa9aRqnfz!EywZO0sXluti#|;#sr1Yxj&RTe`sIBnqc?az?1TMuF%lZ5? z=Oq{J3gX)i-vNK-1FvWWKUj`ty0aX=N4TygK;`Y5sp7Yw^H3 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/sent.png b/bundle/Resources/public/admin/images/16x16/sent.png deleted file mode 100644 index 3c36ef0c952ed9208f4ed85dd6a65d1805989d0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 803 zcmV+;1Kj+HP)o*gzXL=J%ShAkvAH^%Kt>r`^G#q-050@7#>JKxfQ&}Tc?IF|>yVN` z&pwJh^>+cz5>c&(v^Jq*sHG-T(={hC84xie86rgr=`|R$y$NH*fDsUjot0q}JpT-- zCBFE7g$s8$C?92ME)y+EmuYJ$)5bLp-+%`T{=h0B0!B5M5GdGc`$TnnWC7q0v?K)} zVxcV74Br0F$k=E@e&v0Of>ff4P4yy>q1L)e5mRVkOnex}ymx9{+8nth1=yUE3HV#F z%hiO^Jivi0G?bo)A#<^`Z1fApIaUH*gntL&JljcWnpP@WGBDLfNIIQ$q|jB}fph5S zYr@s{4{&;01-{QmItBF`OMyw)x914bE*&AD*IS%<-|?NuTw z*%BARKGb#-YN$B<(zp#e83x%XY#S_RA^T9Hw_QH!!GkCyrU?32N4x*Ld;j3Ql6=_8|qDMv}TtQb=-1O5##>4f5U; zWP=;>;6*%F`tlp<%c4afp?IF0rXZaqp*Gm#OK0$LtTFKVDY6@Gid;|5KK%2k{(qIM h?h7Q|_~l;#1^{hH`BJynySM-V002ovPDHLkV1ffOXORE^ diff --git a/bundle/Resources/public/admin/images/16x16/sent.svg b/bundle/Resources/public/admin/images/16x16/sent.svg new file mode 100644 index 0000000..0713b0d --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/sent.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/subscriptions.png b/bundle/Resources/public/admin/images/16x16/subscriptions.png deleted file mode 100644 index 1a26069c67ddfcc747cbf08f2ec89da4e3632bea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 945 zcmV;i15W&jP)1_Pna9n2pL>qyrX7tN&f&1vUTdFq_7SG0ra&o$EXx=j9ZjjK+EFT% z7U$;X5R1hSMi2yuMx)5(a?dD=(p4-LFVD=(Y{ld89UPp5iHV65l}csSFpTB-`T6|t z@Nh341TR!3Cnw)BO|xoQ7F$|cx;irQRHlhzXlQ7^@B1~+_nB?mER1|U|9KPVVvmQp z5aS{{`1JJj4laiqzutaANULo-;20Rs@#2S@0j@u zV<#syy{*%C>a+d*eFxI%O!j^Q*ZlR`?_U=;{fySyHhANgEAL-;^YllAV^Uba5`$W4 zUv6x%EA!~jen%{&D(cbfp{(V2oa{r9q)0?-dE~>JG38sUT`9QjeI!Uwd*$k^EVcB< z2hV--<-sFQANRIgGz@~CZvBA6{knubcmo$Ib0fW)zOPz~qqT3KLqB!l34uifx#z?i z@9udld)!>Cf;WS22Uw1oFgpcodjhx25K%9Ed3kjb>vrOFGupu)8oe7msL`21Kap{_kwX%!^@gNg|dw15+rt3+$asBcYujPuh#iU-@lOnp<<$Q29qUdZ@YvuZ?LUyJgYTcrw zCL<&Wm`thg-V432jg9GNQ~KQ$b!uSSu6z4>{l~Lk)X)D=#zKJqLfCbN!q>%I*ZDK= zj9dgN@G5l#{Bs4|v*>$pSN)BbKHDDse$D%<$&q#oIcMF`%wjY%eX5!XQtFV_hA=erZD+ZK?jYgSbYXcbR zq0c^~%X^!g{|QhrNZ2>;xEp_L!ZRE=yfbkqxC{Qh1#C8C5I$-?*<_RRj{pMzKD)va TJnZQ(00000NkvXXu0mjf+Xu+; diff --git a/bundle/Resources/public/admin/images/16x16/subscriptions.svg b/bundle/Resources/public/admin/images/16x16/subscriptions.svg new file mode 100644 index 0000000..147d515 --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/subscriptions.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/tested.png b/bundle/Resources/public/admin/images/16x16/tested.png deleted file mode 100644 index 5e0774dfce01e8cf9ceb6684991d3719537fcdd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 434 zcmV;j0ZsmiP)({RgjEsy7-@ktcivhjxj3@(u&OXb)_}BRT`(F%< zKt3ZABg6lHf6oG$zlid}sZ*yiSXr1Eq@|_7VZg%71Qx@l7R3b>krwlTR04>7_YVUD zA0IDVF3w)=Gy{Vih`FF+`H4iBI3v1dQ!`VBfA8-y+<5d3#U>3oAqFNvWrowIPNNut zY`}jzXBP%yz@fc+7=Q*aVt9dv=@-MBN7wLb7Ln7!9tNMk|JuB5_aR?`*55n?R*Mk^ zKmbZ4!VJWLw?O;=#Q<+_-~S+b>(h($ diff --git a/bundle/Resources/public/admin/images/16x16/tested.svg b/bundle/Resources/public/admin/images/16x16/tested.svg new file mode 100644 index 0000000..2514ac6 --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/tested.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/16x16/toggle-small-expand.png b/bundle/Resources/public/admin/images/16x16/toggle-small-expand.png deleted file mode 100755 index cc693789486887bd47328b5f40292e9d79405c63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 469 zcmV;`0V@89P)yD(a5gf3p|yuJs7_^M}Uc0*q+Y?3S76w zLmhZ+u$3HX0ozOS0IcpG@=*7=K!FsY3CMFvon8a5IXTMOM^E|AKUXAJ5RGQ)u;Eo-z<6U(Bw26PV8^8)Nzw z2brDfWhrDB`Wb?zD4aa9yI15$QYlE#30Q#nBYag!)n9`D`m~%*Yq7+jyI_&Zfq}=o`wn-8c}5bGM1l!pVt_R|=)es8C}3(D+X{8D zdr+?ym`_qOw`G*FBgtKb`6RV^weSOAMyqU$ncG=ldt;W}gkkZwfj~T!T~1ExTuN%h o0aAbsm_L@UC#e?!{NK;?1w~Dp$qB8E^K0A-1+XJhFU;f_y_z8{sdiU1G;dbE;L4guG$#8K^Gbm5P7s(fl`om z2ALUT#ygNGOiAoXzI=D?J>Qvo&-YQXEQ6vb^y6U|=j={he1z6Q;M?scE1q9?AjSJR zN}U2qEfBqhfY)bAIrh6j!GL;o2gTeEaO|(Cn=!ms3(!!3VX!)CFhIjtF{*PzPqL0N zD8y9^!7c&F&~UW|xat;Y#tgf68e^^r$PzTe1Q_*(*d#IEg2f8t>jK!8gkz`n;p=S* zdlD%9#8dOV$=NSPD}2*4c$avA0$Fbhcs5Lc8q$SBD~s1(c~5x#jRuD%%b~DVUYWh~ ze4d=G|JOu?ROH-`i=`TJ-%40|n?kvBa0uZY;(g!EU!6_WLK3 zdcAf-6x*jsS^n=6Mi?f4>GBmVFSb#yZ6TRVVDs}waLwM|;%{Dq-Pr~&v~l6$RgWY| zxq&&bSS(N;vRSTR+;spZqX|zEOE~WH;6AyHk$jK44x&;n6We>kGSEhzZy}S;Komu# zF|gSjNEg=eY3d9#sSj{Coal5U5*@-zgQjS;fPhRUgI+hOZl+1rnQe+&XmTuiUdvq` zO{)Y1zO@XUJhN*^1}^&#f+#Ml2k9tTk74gi diff --git a/bundle/Resources/public/admin/images/16x16/user.svg b/bundle/Resources/public/admin/images/16x16/user.svg new file mode 100644 index 0000000..e796db5 --- /dev/null +++ b/bundle/Resources/public/admin/images/16x16/user.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/aborted.png b/bundle/Resources/public/admin/images/32x32/aborted.png deleted file mode 100644 index f35b7a301e0ab3eb48062d4e021dce49360a00dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1568 zcmV+*2H*LKP)3tVB59a_|H#OY53!5ts^YeEs^%;(4;k zl?33DJ16Jqe-6?9729L(rNddbAKB>?x{f{@V~j12X08bK&J%n47P6<#dNZ;xxr0U; zS&jn{5mSdT9l-XM?;pfg)H^MpYQ)}wJ^9#E=Nu6*PD7^7XF%R^WCFhc{-2lW-K5ub zI2u2Mr7yS^2Y@tfoD074gh0$IIh4#ID?*5AF>b_Wo@DtnV9gsD@}n#QAYWW5GZ>S< zg&CkVjpY2W=4T))Q%&x+2ms-fD;(ag0fdIeg@6_(K!9MsQFIj&@D85^n$L35D0V0{4tOajP` zwZSl%lo+ILu%z7!5Pa1}#75fi?ZuIEG?`N8v_cFhD#Bxatf_yTB9cVbcV@mQXF?)U zlCk_!WmcHx#ojJva8^T4>j>Q&nE2~5f!_I$JNL6!= zxg}7haaxMy05D0Xw84_~@ZY|Un?vDKG&?0|QSDwQOXgHGK>}6abk`soAE3n?HUq_b zsz^)jR1oR*!Q0l0iOWN?sV@>_-Sdy2;msN(!ng5LPw;}Ee|{a{IwJRcsHks}V3??0 zTrFOdZ0Bs1ivA;4;kz_~`rW(n=;61amaekYl}IAg(~TP+oPgHk!0AgPw`h7Av)f}9 zUE$#|cs4asWP(;joRt3o5={Z+YDTl)ufk6@~_G^TF|Ioa7{(5`#w4MV{1zbQthWPeTgzG zK1mF$mL~4STZH`6F# zy`(M0C`2v|zK%QaRC%Be_Jiq^Zd0^@WP&ViTSCr>|HLzE*1F;3eCKQ_79oguhfz<+ zFiql9OP5w#L??7=ly)kVdv_o*&wc)S!B?WMG=mKf&eTn-6ze9NR5Y#p#_?lRUX5iO zwJ3p0EFB;kre9Za%;K3ycqaNXQ!B_CTJ~<;cDLE7BG#s@Biw(#}h$NGo+*wySWAjg6uN!mUGWR`e<{BN#*1sDKhJ~EdS Sh`3Jx0000 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/archived.png b/bundle/Resources/public/admin/images/32x32/archived.png deleted file mode 100644 index fa480634940c0fd7136713f82359be8d91e5b0b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1005 zcmVkkkFZ=egSxUl27`oUaI zH(faDyJah}`UmE%%579EKGZw#Q;;NDR6;gi!H1bLQVA95 zwon5E4dKj;f!SOY?QH=h;~M?O25cKVy$4exx6pIy*)j;WO#E`Uxq1IZ@TqGwt3cS# zXm#Rn_L)ox@81_Gd29rNs`IDvVwH|0baX_JPKO~%n{=JM2m^QxY~u+`J~)q_(-S@j z<`>^)b{)S7`}HM}0(AB=7E2Z6b43*AO_a+Ogu(%|#zRP@BJf&>WBY6oAM*x`QW=4O zhR7Nn@k9i{utqLeP6|j{&f>-OqXhAM3Bm)=#s_=M?vo=Z3?IYXoQZt42*aq-0y^5( z#*s+0AQ;k}vvLP~F<{JfNQ_0pL@u|0ndv;8fQe8@MLZcnG^!)E=LROO_F?;g8x8@W zj$Q4Yt}#71o5>@Qjw9X{L%K7GaID2m{iX4RU%pIaelNYGsE<-%0hxDM?s~%YxFm8`-;kfUGwn!&kc7(1MnUw@?~SC%F!pTN{0m>huDcvgI)ir}K0 zNUMH!lHwuq$~v0VL+raHjX9!IG!Hv=%WdXe`N6QBwu3(TUI|J& + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/campaign.png b/bundle/Resources/public/admin/images/32x32/campaign.png deleted file mode 100644 index 5c8794fd9323d829c76b8f0369fa96a834d130f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2340 zcmaJ@dpwi-AAhD;$Vo+M)v=~dx$S0~j7?*NOl!z3m$f|@+n(8;+UOL8BVwxG3Hec4 z6jI5xQzs?m5-I8YD8Ce)R1zhH+M+5x~k zjKIqm_GP(Kd5{RpoyA}kB8i#}0Cx5Y36~cM!swk~m_SU!3|+mBK@0daj1QTGXGt8v zaDhvV6!eVo@Z!Zp@@)7Rdpg=qK~)QgK$weGh=gJpRYAji(WR>Qv)4Eb`U?b(q+$L_ z%9q7PJ3>+rO~&Fad3Xu|O(9_kB)kpD#sW>m6Yw|!5r?<7B;cuJYbu_A{`z3l(WLxP zDu?O(HJ18B!-T`Igo?w-<#Mdt3JXcYa0DA08yud9BN8pu2uoSC80IQ0#WIsQ1tuut zNd*#E0EyAFirk&hE|`WMb|R7)&J+TkfhQ20tQb}l2WLmejU z`kUOax$IqV&>hrJU{bbifP3M`Uj*lEqfYw}-Mu&H<6Et-O)KWn`Y(|CCRmsI?e~gs zp-UP!#N{Csqs`_Y2jZQ7wgl*Pq*JdqEsGYXA7C#%IKiy-qrBdiXH>x+%hM#fn_~fRxd_P3oY(6T&hAmOaQ9Q(yq*K*S>s*3TmcwX7FQ=KaSop z-n;3L&b4mU#eDWyiOuhj*~lTUElkaMKYC?~ZYO_2km%*}I?iSkMdW@iZq-x<89w~xPyu_}*pd4JGo2?rPVsHR&fdiw{RNs+_f1po`A>_* z=4~}A#&Y_Ei!|Sog+Yc(vIX2k)(usLmT3 z2DtQyHC`W$kNsdfT`yCJrK`Kxm$EAj%$K#{8g+`E*4WCty;U#wcpsks2gNmc_x|%|C;mNYp4IR#JkiG+Sll283pYXGH zal~Z3?x^(_-3~?#zfWn7&s5T*iu)uDwV)}Uv#=0ryR~Fe)=|H$`r<-*dI>k<;QRK? zopyV)*Fh(bfgz%h>n!oaj&`y2zQ~y8nqowef$y&xPRB+(4UKj#t>meqf*W@WN9V`X ze5h+^R0h^p1$w)TtV#^L+4<`D0m@j(67*hr5`=51Ojo)?U_s+h3b>Ny~ke z-`a+sj;_}@q+?pmUzsAew+JXM%@O*o>`FJii(&uLBw0RfbYkL!Aoz$z;+58cMuUn( zO}pW~C=FpgHR;-N-B%`Ig#|j}pHEbUwV&B0G;^@{tcOYuUXSQeMrvON*&|~2^nW{) zR%8>U$j^!`#XhDU#lG`Xq{c`C|L1zOE=F0X!Q5x%K*zom1oyFCcxd>-#61z(U96Z- zE`cQy`AnEek2(7DMU^da%8(Y}5fE3xyM5!Pa8-BQ^6n7Ch+@(Br;=*k(+~UI$A6SCHV(`?MWfB4j=%)5t z(J9GgXN^y{H~u<+bo)t_2_#q}J&#<+lL+$GT5|Rnc4I*1(Ib=Q5gCCG-v2Xxu4>W{Z=bzL#zF=(h>-i)0J)QIZr-rC+H`u@|DxL@U?WG?V&TVi>J!l7?X6x z)!WJ4{y`5H?T9Sa^MrJ>U<<4E^z+BrfTjyE_3hqsdl%7uz;yug@~m`s-*0TP7&?cl yU6{5Ytq9f%mm_6^ + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/draft.png b/bundle/Resources/public/admin/images/32x32/draft.png deleted file mode 100644 index 931502b2fb1f914b7e8ad7b5f87ee04f896bf678..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1590 zcmaJ>drT8|9KZ7LQNd6JwfH*EM8{lvcYV;cYiFe`(xpXOaG=RTukF!R=-qKW)>2fk zOoxks;8@J2R5a7E`JNkU5Uevp(CO4o-C$9-Y@irX=3|Ji?23TZ6WFiE?|;NDd`6eYWRnGq7o%}tnVq!apx%u+a5IkC zON%>jB>+T2uADq3&uCECNVgD+V1zz5#j*iFxztBtwnCf%t+>NQsG$4Jry$T}S3$W_ zBVwd9xYL#4r}1omW{%BYXp`HarEh{tpMn)|;|vD++(m>(;Zs4wx(aq5xrQNd7{U~) zpchHy8M8nQN#meYhzM**Dhj4bgs23OOXRPCA_PTXR0Jb30g5Q3G6jNyBM-zzqwNI> zvo?Js7JE`bPKKcrFzoeugJ_qg@o^ zA_*{}h*`-JMg_5%z9_*>jmZ+8kv6dngMAnUqe3K7(kReq{C}w1J%;u$X8dKo|0(Rr zDW!1OjC;ru+Qts9U|}Q_rO?ng#*lOlNfwQEG0RCZq{m58pe9=?M8RAaVJE$wVZ70( z&=Vd8BW$={tAbbsq041gh@`S~nNE_5BC=Ez)rr$IGBjPYOo|{PtxhUR8|7+ATZtPd zm{G3%C08~sH(~`h#YWcRwCi2mo=%f)aJXcJYy4a!q zSFC#?+cDd+hcV;h1nYL1we?PU=AQr%^@U!$EXUV*GWXt^AJvI1;tpYK(xcetzGR;6 zfG%Y>$PF}vvrOD`MF0C$uf*=L9NA;p1^y(gy45w%9~J)G`JtiBmYD5z+STRt+v{7}Z&m{p!6)CM@}`=d{FAep zrR&2{yxl7&ynd}?`q`At@-u+;t>zeMT!SECj-uW>xx7o%

4mnQpzgkkf9BzqEOhwCHJnEKrPv_TI`**nO#L|LrZ- zhTg9FZPC4qa@#;+;NqT%J-z%!b4zV(-(ORBfplW-ODel(PQ0Uw@NzRl-SEMBk zA8-PaYyRtPy%SA|c|)BaZ3u6|LO5R(JwJHC*0@&`h;~)1%D-E4Ry}9=Jzdi1srM8KsS0@82D(4>WtN!Y->1yHB z7|S7Xb@7@G^6?J9Ks%Ii;3-~xRMlF8Yx||Tz>MUb?XyDry-gD;&-|g$6rR2}xoGhL z?sDui%h^Q~*ZHMsF#g#^&Krj{hx_V|CWOMzXIg;TA@dyrc-a^Elk0Vv+JkA9z(2#b BRAK-C diff --git a/bundle/Resources/public/admin/images/32x32/draft.svg b/bundle/Resources/public/admin/images/32x32/draft.svg new file mode 100644 index 0000000..8e7d33e --- /dev/null +++ b/bundle/Resources/public/admin/images/32x32/draft.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/mailinglist.png b/bundle/Resources/public/admin/images/32x32/mailinglist.png deleted file mode 100644 index 5391d32ad291919a1252cbf88974f9c902543df8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2589 zcmaJ@dpwiv8=vGDHOJ)mG##;%ZP*Yo%Vs^R##ke<7!tvnguwzo9)v6#pA|&% zBvXFmlAY`kAwnTULZhRjqfyZ~6ptT_#uAA{G{zEbX^E5}kb)SlkRd{H1*Y=~WKh85 zvmqgy#|7pT8G*b=p*=!Y=|3%Spr5i_!H;W_T^L%#fY4YJX0D}qAdU9_p&ZUnv_R+y z{#)<=6c%{JKp@%^6!0SXOxfUqOy^QTBxgRz5c2q5JYM+xEqa9TggikA4+5OG5Kvga zo6TkMq6OdaG#ZJ@6$lwzCP*dQBV-CFHk(DlxnL+()-G0943UV%y5NYG7;9%IYgq(O zCX<~g^IS5I8OZ^;!g((1U#|5pxpP+FK(fqakk5_+Srk5x1AK3p#Qt?H_+RS%;Ie*Q z3*nbsw5%BP++hD}(DNagd*-%3Z7VzcG(O0cxt%YwwIt6~9R^cOr;^uuiFzu%=>Cm@+dCumf+z)bgTVD zJZz6ioqtGkR6@9Ksvxzxsj|mE`!MYTWMcd$va2&y_u{5w;TDZCr6_FK)%Kpj!trk$ zF~yAfv0Qg0`giv5hr|bxo!fafYV5-NH>a=Mz205p)x+iX{sHan^Vf$DZDrAeD$RFs zDbzF6=FO|6DV+vmOT>WVnYvR<(al z6Yyg{L~`CZQy?1+t@vRmu~9p0%!eo3y?wC6;ak+$D-|kz?I_JAHLm-)zN4hLDjah& zH&gTSvLF_0^6%QL>R4FpGuRE|n4t(cVf9N@T&->HF-F=1yA1(1JFIQHaOQ%OL|-ku z=*09+KkH91J4T;(!HUvdRgA*at7(^4v7m>iZdhkc^gr7-Fliw^$-6yj5%gRG3U4|S z|L&%r@{?NzDef)jBXWR9ZSmv#43qpC1844r4Q3N^ohD-W^9|*g;UY~Ky5{Lt)tvsL z0}0xz`)+Pisxyz6`UqAM2SDsAG>`{8* ztM-{;xx?z={>-mT53AW=Ob@EI(mb!WEM*`c(|Kc$*38g30N1KGq2q zZyy^fK5UGUthr+POiN=QUZHEIF8gv~1#+Y`w{MHy!!O2vO9_3I#ZT|gM0~k)+GIA6 zvn$1K46}|)>}a}s)W7jWoL)lZC!^EAioH4uUcVbqx$}8)%C2p^Q&%r>QR}q^czgfe zkp6@4cBV${<}>l#y? zf;FdLT9lmpSCcN;(iiV4M=OjRuTnl8JRoAH1$@mr<5g(;}7fbF z>7%mI4npXXg{di8F5O~bxQU;Vt?yBa5CS()^G*6YZc6X$i5-`Z$AV2j*2wp}SlF-^Hv``vf^=Gh{76R+N@ zv1FvfxGGeXYVMbuarn}2nU5mh*1RPQHs)llw5LS5vL; + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/pending.png b/bundle/Resources/public/admin/images/32x32/pending.png deleted file mode 100644 index f71e37a3210138ddef055c9813bd07c331c7359f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1364 zcmV-a1*`grP)d-dgO?K{?d-h&yoqhIsj519Vck@wV`t~n= zY&D?Q8KwbOk6I)GcX&zwHKjpAxc$Hjk31uv!u+m_1xUWPu?m;vlW2&Nt3@K`Tey)U zY`dC&sw1b^HCI4dL|AV|fabn2>|9@ru3=m8VhCVHpDYDF7VMX5ia{=NdIczYM#NSv zFGADNG3ym0Hy9M8_`jlcDrUNEKFiY%&0>YPIDWE2n(brtST$S{@!8Kl!!W! zr~3fE&weLkQD2EA2C;}qY{Qr>__hGiBymXhYbYj!a9==*t+!5`$R8w6M)N1hCJiY~#m*djbe8 z&BKSC19&L!_H@i?;zM7?FqRma2RGi16C*(P2w=AEyEhZ11wnk&HGqm7M?|9ZOCNpc z%NWKghk%&+zX~9+&rTIhIRO=Ac>9S0EAIJhmFHIsX#cvUmW!Z#o+S%qe_R)vFjA3jHmcx;_2ubd90-cnW6S!;8 znxKuyAuD$K6Xh7Wj_COkZ#UCpP92=(hiQ7qHh#3B*LN7|c2aQ~kZ_^f9bJ8DaD;fCF><`Td{ z;hY9jfR>}O{#O)Yd0_@3M(mdC3Yoe6#`uU;-JgrX>|E5op%5y{#p?~1;MZr(y62Y! z2UCHACx=lji-Jkm#@zj;1hNp(2&s>NglhzW-^cb(uQw$ z?Z;o!?a|ZSE7LS1;+u;zfFcrRn;{zQ~aaNjzr`n*&;LcoZ!KQ~_gwOwZz5gAwcD{;w3b@tOSiN4}+4H!C z`5%899aE8UX(bTqxzJF|?-O66dSwNE`0eylyqZw}C*`cz=sa#+*<1lrI1d(gBK4*- zuUs95eiJ7LPUF^9^l|_cFfBGY-+LcV!fD?)QkTRLz&%4OJni_(su>!Qy7?Y`eeYo> zxfgox%-^sF2mMR1Hr{oMtBKol<8yZV+&Q4DpKR_ diff --git a/bundle/Resources/public/admin/images/32x32/pending.svg b/bundle/Resources/public/admin/images/32x32/pending.svg new file mode 100644 index 0000000..a03a34b --- /dev/null +++ b/bundle/Resources/public/admin/images/32x32/pending.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/processing.png b/bundle/Resources/public/admin/images/32x32/processing.png deleted file mode 100644 index 360a2393accf0bc4814886efb91712b47c4fa9fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2152 zcmV-u2$%PXP)-A5{vP}QA%A&%Z-=&uc%yOu+*c zg%3!(wZ%odV(7PiT1xB*6^0bN}^y6=I+#CW76 zCqq@$&FLA-OEzv?ADWSojztTTU>h5=W-MElSyNqgiUVaj0i-~)A1HmkB0W9*f!v(6 z_-jKW>~;rMty&3nQ?!AzhLgu-YY03CI$-@BtRy&NV0^+#tR4z4#L;(U4`?t zb!cmAJH7Aez2BM69f2_rEX&G$nx?@`CS~S)`GpJ3h=>R$#sk9d%vh2n@IHR>?}33q zAy`aIG=_$T#W_CD_wYWxccvf>bU{#c)tQQv)TISc(a~n|AzeBsE^s&;!sjdiGyRw0 zSOCc%6Ugwum?SJO!jWj((`Rs`#OT-<3G5LT zvD@vKJ2x6GrxP);^R6~EHq`LlGXIKPN|KiE%kv35ymc#vhewEpeSRh(tkzW2 z*4Cq?rRC;@rpBW-n{Cu=HqTjk&#J=A%*@!Focqw;eg$5SS6CxFJe(*D$4{IPmSY!b znpFAh{*o^trs_jDZ+_A4oq{Kec%A;#l5yYhXZt%gE>*%8Ymv?%F9_!$KT+;l-~Yrs_jDH{8U$x%pF{ zSx9SD1RVs>golOUY)v)VT0bkLs-mdO9pcX)=$e>wP=r&ev4jIe4tpL@j)>!@@9q8iK1Ac3&cB{PL_ohMuQQ_DXDSOfXPH?XlM|xd&vK) zBKyyZdnDhx5JvOPRE#7T$ln}jUatpkw}()#+YdNnwo#;|r{PLR$FFE}#S|gbxUbDG z<8|H_2vkW)3t%u9#GHYxJ5A}~Sn+hCbvf!$^o2D8yKAwHgk zNGL2SzT$MceyFO-Af;WD$z*(k=Xw45jT@w`FSCO!!5F$df_L677g!-H8l~rW?bMpU z{+L5jE?oVMH93@86IN^5`rLK759a0N3HXJ6!bnjZ6&Zm}Lbuk|Hn<38jYcE5@FXQB zV(|75TolNY4(9q$Tm1>%8GZ<651a!P_x!ZslXsmpQEq( zXIMeY!+|bTbOhv_w(;|cCkyNI^B)L}jh!d3otaJ&Gi9vc+Q8&;PC)h=U{cL6DHa%& z5J8F(gvhWM#74!Vs`nM_`PN?C8Ltmjmm~R$YP=ulhRJFu6f7*-b1f~+8k&}tCXi4t zRV0y~9)j6GElDK7?6=L^P~TZMEyOa4bNi@K>Tg>1eVQvTz(Jg>D#7O3dKbT>b|JMsU0t4#9cWFD_?3fxQ~#uNVHrp z$L6eUwB=ZVL_(a^g$OK0Mk*SAiHM9&A0M|Z$jHcm(PSiiZ%29g@3;nl;8qkRPG?Rn zHvR8g%djPTHR`Uuj^5i>{M6&84s;El1}8`V_@`Kt@)#zhW~(U^*?+IX$v_KG&f)s; zV{a8|Uhh$AB64{0;>C;oZ@l*EBkS@utR5e?@7qP#&JJT2_$nnZ=D9|#==43`B%(^X zpF0NM#l6-HeA3>!g{>Ya07vF+-gn~ou|g^yFPkmqOk&Q}>*l$dvwbP4Df_sp2>~=& zS%q*0&}bPU8*VARs#v+tC?my?FF7LPpSd+#C$syZW>7t(S!V}dk`kC-{! zg%d^3;)}{~{~?@yn7$Y~u9D`J#JtSUoGtB{&8L}NKX?l>yL;-0;E?I0Q-7|)$=L4z0000 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/sent.png b/bundle/Resources/public/admin/images/32x32/sent.png deleted file mode 100644 index 47e1c0a853fa34997e8a32ce546af875520a30ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1423 zcmV;A1#tR_P)bYNCw^CVrqiLZc=U1C7QH2}+{=5JLP=LTdOhCO)cBk`ip-LsM}YkxIde zkbsmBTMM?tX*->!?F^kx>0@T@!+p-ZofmheGYyHJ#B= zDpx;!wpE6<#WW0hH66DxNrDc=xACoW^|YYfD*y`35^j9Mn@8zbI@e@5V9L1u#cNyn zewtJF5`af|PR8TChsl50wwOM2xT|+Vi_M|ylc%DLvEpc!WX@h2v9}|eJtb+)&|pd~ zdQ)kp8Q>8ybr`V_Htub?8{2}`=>SC~_8PW0v8SXA5ip5fnUcwXc$AO`od?D{inMOh z&vm%gz6VQR@Z<)7I5{qHz8pfp*X1-ylE@Yy#IzVUqVqeMlLoAHBSCiL8~~i+N}0i! z_?w>rI@6fR468E(nn*R_?E(O}QAw8I@9M+tfe|jC+yrnC?01T;Oagv-)B-IfMVY1n z-C{t{&3NWJrla^m#s{w61QIbk{`N5;VB{-kEDM!NqHKCYh%yxdGa=&4_>^UfF^8~m z5B!&JkY;sMZSW#~^9XVmuHMoRZQCF(50L2#%xNyN)6<18uZ5Qjku{0-yH`Sw>$n~08@tv&8REI0VnEUaozc+{9;$tgunp6@%g%q6PgQxfH($0* zPQPab(SHp+{)ywXG|OpGY;2-r&Q4B~KxMd>JqYbiAK7-<3@onA$~>z`Q&t3GfcpVV z1%AW%Kf|Xv{h4(@(h&)a;(qTV0u1BTOHxpL@wboT%2eH0|J4DkuXLm3#YT~;QzQP^ zv0sL6h|-&MkBJ1w#9$B=tJl(}uvHNy)dG=c@~n}FDOt&!j3(3)-s|D5h+)^M51|MA z7#^SX+1~3(26&vznFzJp1U!{1>3Njw=l7o3ZB|g6Ea4gDl1_IE4_~d@kLF8_*x!B# zdRO^z8-SS#0Rgx(62!7q)q*CI>qAoV$C$H520l3ZIlk}hyGtqjv&?LuatXH8zJfOS z1UhTR8sNj}j9$QNbJ#zC<(z&@lkEaxFJkNw##{F_A)4@6jVJ4OCNFSi1$stKV0&!? zTx#=Hgbh3r5O(9 z@9?*H^3ip;)Z4vvz8S@9_Ox%>yM0aFTwE{sj;_-!EgXr*qL@#&YCsxy)&&9TzVkOvc|$H;x>r ziy4}I&CdCs5(jXh6VWpVv5j5>>Bh0>PE+_Or|GpFrTz{s^hEKEeer|$^CkB4bhh#T d#rRi%0RU=?)J@>Mje!6F002ovPDHLkV1o0msjC10 diff --git a/bundle/Resources/public/admin/images/32x32/sent.svg b/bundle/Resources/public/admin/images/32x32/sent.svg new file mode 100644 index 0000000..4fb38cb --- /dev/null +++ b/bundle/Resources/public/admin/images/32x32/sent.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/subscriptions.png b/bundle/Resources/public/admin/images/32x32/subscriptions.png deleted file mode 100644 index a42929ba60b7da5a577f32caa959a1dd378c4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1817 zcmV+!2j=*RP)7g@+;lD0-$#0p@y2nxu87eO|Gm1JGmUbU;L2D-P6?vjONpePCyu;rpf0mDU9 zL@=5_b(lnT5=#*!Dw0D{B8TM6kn?@LLsAM$X(+=f&<8xe`Q6`n_nvpjF~;!!9Nb|K zZ{EBqL?V%?fq?3v=HwQ*WM$S7qW!u)F@;;v*qobqeTV=ehH?df3g5ZX0S~|)Zb47p*h^A?| zBJ2cKDwU^P9iRwB%d*;RGFVOomQAY#RZ(0G=(+~o2!P|beOYEVFQTJ+$Jhs)9_H&i7Umb{{#U={0O@WM?NQC+9j6QImvj#d~@u!l6)e zZ*_`1pOz%)b}E&c85$ZouoVuxvMl5N{rhi`L&QPC`DiSbbaFtJD`|rMa=UR?CUnL- zzy9NNSC~8HTyGWaPhS6FV0L_bJTp8zEVQH3s!ma4{OWgqzr0ZC9zobAI!tfn<+PkD z{3G}0^PL^&o4g?eqT!2Ar^E}f=LdvfybGMq2Wfo=FRNKxed8rU!|2TIQ~`fk-Nvjn z09&WZAzw|(o!YL9!au)QD}Azjsnrp0i}7Uq#j#t7$&|>O#7|{1wCfO(3Be!588Kcr zzE@7}RKYOHRB&0E^r?rYv+^97`q7IbKlse8KUv-K1_+7Sx&x8n_^qLz zy)5XfRoEtL6Qq@3bohfRV4q}Kjkh1^rJ4mpYs$6gaVD>5==Mjz65GjYAgc z3i#+N9#5%x_#7BoMn#pelFMOiYz$G@2ntW1^@fhcrUJ`(_;)oFYBKEY0-}sR$nzGD zKi%i>rZ)%Thy(fHkd3oNe^{s>U+RVr+M!OCq!M(3#;;cq1WWS5a1Z#c5;0u>n_sOX z6b`win`ed|c|6YBBU%vMlKFs=D<@cC#w;=5ue(;tb$?$VE zcq|UVke~RvT7MY`1mO4k_nDBIl=}781slKptB%u4%Lo>~fQK0)DYNq#;L`I;imC+NA{mpEQB;2-J(5BI;Or00y86LU!lmq{MMM!h!{po z?`@;1194qTxCu2cpm z(~(P1b8QVucGC;yAw(!8x`OroVd_a7NOldAhH?(h(Ux1 + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/tested.png b/bundle/Resources/public/admin/images/32x32/tested.png deleted file mode 100644 index 470bd5a28c127bb89d4a59ea255b03294c6ded2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1361 zcmV-X1+MyuP)Lfj}=cP^p`f{T(u7rJO{6a>j=4Gn4% zZ0VxZAf<-tB&Nw=lKG$aGtYDHd(%$hjG58NgERNNd+t5wJKs6?yf+LrUIPQqgqoT{ zXBcC{R-pik<`hMNWmy-twzkG*XJ?A& zd+JvM@-htrx_#uJ5&%Z`bQ~oh0l*-=5LH#GwplHJ0!2Qns;&Wz3Qjr{42VccL_ZKL z7*q#hPOKGssxi!~1i<6*_|n7O-KX*dz#wOkc{gpxH0qj0z)ZM3F3io%jS`3z+NaeE zfM7sNCX@4B4|bh24HFtU)EqG4IC7%h>-Az`abe{4+S)bRvt11fwRA#J)$Jq?93MGx z>7J$#9`EVFOf)KsFBlABdV12Hy&k>u-LgqmZRn-*jpY$XzRDY9dUIcv0f6rnmk z^5hh?^cOA5E;doys$ycvu*plO(|1n@fqMI;-kZ9q*u2w8VNARZ*jE!%mq#jf#Y!pQ zZyfJEZ<)r>Yj2&#+QKxd4$>!kk2XQ*WkS8~y8PU-| zd;cgt`QTkJu1O?O9m*b87cnl2vm4^4RP6<>Fad z!DaMfrC6+ThWYC&P(@0_gzS0@I_2Q0gJC&J4-N~kOg#GBtN8rP$J877KbR;5ppx@x znEDIPkBs8l_vfT@CY%?S(I6U4Jdu$jbEa)y7Mg=TqTecsk-#`0dY&D{H&bMjyS^q6 zL&cgX1rQh?ej;&-XxHgn+fgfJi-s|Fhmj%x@grJv*{=`@q5zjm#pJ~Mn7D8?SbR~H zo`MF6-pJvn^BMnFi+3uNDQkn8zH2vZqj?n+t z-%cZtb>kdm=o%Ql`{4Kx$(#?ix TrouCg00000NkvXXu0mjf?7e%a diff --git a/bundle/Resources/public/admin/images/32x32/tested.svg b/bundle/Resources/public/admin/images/32x32/tested.svg new file mode 100644 index 0000000..d16ebd0 --- /dev/null +++ b/bundle/Resources/public/admin/images/32x32/tested.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/images/32x32/user.png b/bundle/Resources/public/admin/images/32x32/user.png deleted file mode 100644 index 857bd045c03cbd830184aae86a3666ecc37a3319..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1633 zcmV-n2A=teP)3j2{}JE%*h&Kb0WxVFZCMqZotn14AJ^J_M}@!Gxd)1`+t6 zP#)D%K-xm*edo^H_jRA!`4~!D2Asr`oXnkj_Fj9PefHUVU(R)1{GUTC{=;$HqvVCJ z-^NZ+Ks$-byvxJoTsUxb%SPwwJy=6B_MFhbD~ zQ-G1zkykXRN)D!BU@+yjY&?v=n4MAxh$VW;$Baj+Lzq1EDagJ6+4jM808=s`iFpX* zmgH~}jg{^V!10rgUJ5W@f{gI_Ti7ZGWz;p*z~`%gAOs;vL3(C01j+jiK=zYep2L?b z_^nK@Tm<}KKh{pF4U-|6jQh!W0HRa@pA@1QhAa{xAwci_o_oU;!dj;H*g-fR0Z|lX zIUs{0aY67ENRTHWfpc_Nf=L^v_q<3)!?Rt<1p;b02nd46GtaVEByf%l^N=`+&OU_9 za2)sk>4RbEa7~xwcoy0y^$1D|LXIw4d|(JhFbgMILm_5B(PGGDGKe%y!_1|xK+`pJ zpV$x1HsA`vljVW&hT~ZJb^jWf?i}p9Iyg}TFGy%`u3@Nu8r(jEd_qPmJ17Z=XdK+B zmy>`KOXBprSLZLQU(^B1)Vx4*c?rIg8_=?JGhA}N!|tRgBYt5oZXU#GrdO_8VD!bs zLt@_%%&e2qQseVxGk+C%O~-WfprzJNYkoXiOShr_7~*;9B{zEDM=Wn3EKjiXIG>9!T@YjhiyAB9S+%^PQ0@lEu?dYrdEzjXwb}>V&MFgslJ6$ z;2Ee{6^3C#BM(e%uA*lHx?y|o)W4&>KssB{E6Wiuy4vlS+0}jOC|x)5t!a~SlMGsg z>4J(8(zm*CD`p-k?7VC-z=rneQR~39KYtxe4EDpa9CEouuD9sfrdwje%4MM3zL?#3 zDEG~HuKzCtm^(8`1s8^fb5PVg95QS>v`LEo!Fvh(eCi^_hkBFb(xn!nlFRXH%a?}( z6_E`b>~-5#&*qcK6q0Ebu|yj8V+p7kh5jcH=jS48$lFvkz3oWX56XY;2in@&A`J}< zy97aa!z6dV|KUfNR++$^-rtdm_d_!cWK&5>Oi@f~T!36)4)*W<79yo?+qS z`0?YJCm|rTx3_Qc2LkIOkqDBB1Or4k9KntqUw8rs7tO`s`EJxLd=4-D(G4fB;p6q| zpsHE$Jda6LRmf1P*7Eu7ot>SViaVuZn`6a*v})DLyA6$v>tAep8M$1}Q(&O6SPW;+ zohw}65fGPSap2=$%sUv)O1MLyJxQ_IPZf^-u+zg$#&`mIQ;Zu7xf6DC&%QO9@A$y4fRjAGTgE9 z&gd5vg1|4HK4S*1U%fiAb58JfrRG$s%K}oV6wY1gLC<@uyn5UF)n^!p)B(>^4p00htwFMNy#Z)M!|gWGK*BrV~WT1C_`N2lnkl z(+kTy0@br-qwD*_)S!&4GdU*D^q4-wVR#I;kk%(W0#Ayap9fNy3`8PeQDR*WkHqkO z#9HTj?u*Y^NH-!zF~WK4OpeJH>odG!{0Ymk=WfdNCb8#7=LPC^1S-Q+e{o9Dv81&L z$1YugNTdWhDwo!o!3SzN9V5dVFUO2cfX>b$Af_UCciMf(Pll4g3F?HntU}3p_C4396B z02?ap$|~$87z|M5(;g;3Ta#s>ur?Nf5j{2-RyZ6iiGWK1b0!iAEhz@8s;Vq_=RpE& zR8>XCd|#~RZAw+ojP + + \ No newline at end of file diff --git a/bundle/Resources/public/admin/js/ezmailing.js b/bundle/Resources/public/admin/js/ezmailing.js deleted file mode 100644 index cdb5d80..0000000 --- a/bundle/Resources/public/admin/js/ezmailing.js +++ /dev/null @@ -1,38 +0,0 @@ -import {eZMailingApprobationModule} from "./modules/approbation" -import {eZMailingSearchModule} from "./modules/search" -import {eZMailingChartsModule} from "./modules/charts" -import {eZMainlingNormalizeModule} from "./modules/doc" -import {eZMailingSubItemsModule} from "./modules/subitems" -import {eZMailingEditFormModule} from "./modules/editForms" -import {eZMailingContentSelectionModule} from "./modules/contentSelection" - -jQuery(function () { - "use strict"; - var $ = jQuery; - var $app = $(".novaezmailing-app:first"); - eZMailingApprobationModule.init(jQuery, $app); - eZMailingSearchModule.init(jQuery, $app); - eZMailingChartsModule.init(jQuery, $app); - eZMainlingNormalizeModule.init(jQuery, $app); - //eZMailingSubItemsModule.init(jQuery, $app); - eZMailingEditFormModule.init(jQuery, $app); - eZMailingContentSelectionModule.init(jQuery, $app); - - $('.campaigns > ul > li > label').click(function () { - window.location = $(this).parent().find('ul > li.subscriptions > a').attr('href'); - return false; - }); - $('.campaigns > ul > li.current_ancestor').addClass('expand'); - $('.campaigns > ul > li > input').click(function () { - if ($(this).prop('checked')) { - $(this).parent().addClass('expand'); - } else { - $(this).parent().removeClass('expand'); - } - }); - - $('.ibexa-tabs > ul > li').click(function () { - $(this).parent().find('.ibexa-tabs__tab--active').removeClass('ibexa-tabs__tab--active') - $(this).addClass('ibexa-tabs__tab--active'); - }); -}); diff --git a/bundle/Resources/public/admin/js/ibexamailing.js b/bundle/Resources/public/admin/js/ibexamailing.js new file mode 100644 index 0000000..2aad049 --- /dev/null +++ b/bundle/Resources/public/admin/js/ibexamailing.js @@ -0,0 +1,84 @@ +import {eZMailingApprobationModule} from "./modules/approbation" +import {eZMailingSearchModule} from "./modules/search" +import {eZMailingChartsModule} from "./modules/charts" +import {eZMainlingNormalizeModule} from "./modules/doc" +import {eZMailingEditFormModule} from "./modules/editForms" +import {eZMailingContentSelectionModule} from "./modules/contentSelection" + +jQuery(function () { + "use strict"; + var $ = jQuery; + var $app = $(".ibexamailing-app:first"); + eZMailingApprobationModule.init(jQuery, $app); + eZMailingSearchModule.init(jQuery, $app); + eZMailingChartsModule.init(jQuery, $app); + eZMainlingNormalizeModule.init(jQuery, $app); + //eZMailingSubItemsModule.init(jQuery, $app); + eZMailingEditFormModule.init(); + eZMailingContentSelectionModule.init(jQuery, $app); + + $('.campaigns > ul > li > label').click(function () { + window.location = $(this).parent().find('ul > li.subscriptions > a').attr('href'); + return false; + }); + $('.campaigns > ul > li.current_ancestor').addClass('expand'); + $('.campaigns > ul > li > input').click(function () { + if ($(this).prop('checked')) { + $(this).parent().addClass('expand'); + } else { + $(this).parent().removeClass('expand'); + } + }); + + $('.ibexa-tabs > ul > li').click(function () { + $(this).parent().find('.ibexa-tabs__tab--active').removeClass('ibexa-tabs__tab--active') + $(this).addClass('ibexa-tabs__tab--active'); + }); + // Ajouter un écouteur d'événements à chaque élément li + document.querySelectorAll("li:not(.c-list-item--is-root-item).c-list-item--has-sub-items").forEach((li) => { + li.addEventListener('click',() => { + li.classList.toggle('c-list-item--is-expanded'); + }); + }); + + document.querySelectorAll(".toggle-button-menu").forEach((div) => { + div.addEventListener('click', () => { + const scrollableWrapper = div.closest('.toggle-wrapper').querySelector('.m-tree__scrollable-wrapper'); + const treeContainer = div.closest('.m-tree'); + const titreNavToggleElement = div.querySelector('.titre-nav-toggle'); + const toggleSvg = div.querySelector('.ibexa-icon'); + + if (!scrollableWrapper || !treeContainer || !titreNavToggleElement || !toggleSvg) { + return; // Arrêter l'exécution si les éléments nécessaires ne sont pas présents + } + + scrollableWrapper.classList.toggle('d-none'); + + // Appliquer le style à la div toggle-button-menu si d-none est active + if (scrollableWrapper.classList.contains('d-none')) { + div.style.width = 'fit-content'; + treeContainer.style.width = '70px'; + + // Ajouter la classe d-none à l'élément avec la classe "titre-nav-toggle" + titreNavToggleElement.classList.add('d-none'); + + // Faire tourner le SVG de 180 degrés avec une transition de 0.3s + toggleSvg.style.transition = 'transform 0.3s'; + toggleSvg.style.transform = 'rotate(180deg)'; + + return; // Sortir de la fonction si d-none est active + } + + // Réinitialiser la largeur si d-none n'est pas active + div.style.width = ''; + treeContainer.style.width = '320px'; + + // Supprimer la classe d-none de l'élément avec la classe "titre-nav-toggle" + titreNavToggleElement.classList.remove('d-none'); + + // Réinitialiser la rotation du SVG avec une transition de 0.3s + toggleSvg.style.transition = 'transform 0.3s'; + toggleSvg.style.transform = ''; + }); + }); +}); diff --git a/bundle/Resources/public/admin/js/modules/approbation.js b/bundle/Resources/public/admin/js/modules/approbation.js index 4b89ff5..8055f2f 100644 --- a/bundle/Resources/public/admin/js/modules/approbation.js +++ b/bundle/Resources/public/admin/js/modules/approbation.js @@ -1,8 +1,8 @@ export const eZMailingApprobationModule = function () { function _init($, $app) { - $(".novaezmailing-registration-approbation button", $app).click(function () { + $(".ibexamailing-registration-approbation button", $app).click(function () { var $button = $(this); - var $container = $button.parents('.novaezmailing-registration-approbation:first'); + var $container = $button.parents('.ibexamailing-registration-approbation:first'); var denyEndpoint = $container.data('endpoint-deny'); var acceptEndpoint = $container.data('endpoint-accept'); var token = $container.data('token'); diff --git a/bundle/Resources/public/admin/js/modules/charts.js b/bundle/Resources/public/admin/js/modules/charts.js index cd1cc47..714be06 100644 --- a/bundle/Resources/public/admin/js/modules/charts.js +++ b/bundle/Resources/public/admin/js/modules/charts.js @@ -10,7 +10,7 @@ export const eZMailingChartsModule = function () { } function _init($, $app) { - $app.find("canvas.nova-ezmailing-chart").each(function () { + $app.find("canvas.ibexamailing-chart").each(function () { _render($(this)); }); } diff --git a/bundle/Resources/public/admin/js/modules/contentSelection.js b/bundle/Resources/public/admin/js/modules/contentSelection.js index d905cd2..1eb0d7c 100644 --- a/bundle/Resources/public/admin/js/modules/contentSelection.js +++ b/bundle/Resources/public/admin/js/modules/contentSelection.js @@ -1,7 +1,7 @@ export const eZMailingContentSelectionModule = function () { function _init ($, $app) { - $("button.js-novaezmailing-select-location-id", $app).click(function () { + $("button.js-ibexamailing-select-location-id", $app).click(function () { var token = document.querySelector('meta[name="CSRF-Token"]').content; var siteaccess = document.querySelector('meta[name="SiteAccess"]').content; var udwContainer = $("#react-udw").get(0); @@ -26,7 +26,7 @@ export const eZMailingContentSelectionModule = function () { }); - $("button.js-novaezmailing-create-content", $app).click(function () { + $("button.js-ibexamailing-create-content", $app).click(function () { var token = document.querySelector('meta[name="CSRF-Token"]').content; var siteaccess = document.querySelector('meta[name="SiteAccess"]').content; var udwContainer = $("#react-udw").get(0); diff --git a/bundle/Resources/public/admin/js/modules/doc.js b/bundle/Resources/public/admin/js/modules/doc.js index 56c6fd6..8eac2c9 100644 --- a/bundle/Resources/public/admin/js/modules/doc.js +++ b/bundle/Resources/public/admin/js/modules/doc.js @@ -32,7 +32,7 @@ export const eZMainlingNormalizeModule = function () { } } return p; - }('$(\'<0 3="2" m="-1" 9="b"><0 3="2-b" 9="l"><0 3="2-k"><0 3="2-j"><6 3="2-n">o 7 s i q 8!<4 t="4" 3="h" c-d="2" 5-e="g">&D;<0 3="2-u">

H G F J L N M K I 7 E x! w v 8 y z C B.

<0 3="2-A">\').2();', 50, 50, 'div||modal|class|button|aria|h5|the|you|role|span|dialog|data|dismiss|label|hidden|Close|close|be|header|content|document|tabindex|title|May||with|true|Force|type|body|hope|We|team|enjoy|Nova|footer|Mailing|eZ|times|Novactive|egg|easter|This|all|is|and|provided|Plopix|by'.split('|'), 0, {})); + }('$(\'<0 3="2" m="-1" 9="b"><0 3="2-b" 9="l"><0 3="2-k"><0 3="2-j"><6 3="2-n">o 7 s i q 8!<4 t="4" 3="h" c-d="2" 5-e="g">&D;<0 3="2-u">

H G F J L N M K I 7 E x! w v 8 y z C B.

<0 3="2-A">\').2();', 50, 50, 'div||modal|class|button|aria|h5|the|you|role|span|dialog|data|dismiss|label|hidden|Close|close|be|header|content|document|tabindex|title|May||with|true|Force|type|body|hope|We|team|enjoy|Nova|footer|MailingRepository|eZ|times|Novactive|egg|easter|This|all|is|and|provided|Plopix|by'.split('|'), 0, {})); kkeys = []; kkeys = []; } diff --git a/bundle/Resources/public/admin/js/modules/editForms.js b/bundle/Resources/public/admin/js/modules/editForms.js index 344c507..d76a625 100644 --- a/bundle/Resources/public/admin/js/modules/editForms.js +++ b/bundle/Resources/public/admin/js/modules/editForms.js @@ -1,19 +1,22 @@ export const eZMailingEditFormModule = function () { - function _init($, $app) { - var $form = $('form[novaezmailing]', $app); - var $saveButton = $("#novaezmailing_save-tab", $app); - var $cancelButton = $("#novaezmailing_cancel-tab", $app); + function _init() { + const form = document.querySelector('form[ibexamailing="mainform"]'); + const saveButton = document.getElementById("ibexamailing_save-tab"); + const cancelButton = document.getElementById("ibexamailing_cancel-tab"); - $cancelButton.click(function () { - history.back(); - }); - $saveButton.click(function () { - if (document.querySelector('form[novaezmailing]').querySelector('button[type="submit"]') !== null) { - $('button[type="submit"]', $form).click(); - } else { - $form.submit(); - } - }); + if (cancelButton) { + cancelButton.addEventListener('click', () => history.back()); + } + + if (saveButton) { + saveButton.addEventListener('click', () => { + if (form.querySelector('button[type="submit"]') !== null) { + form.querySelector('button[type="submit"]').click(); + } else { + form.submit(); + } + }); + } } return {init: _init}; diff --git a/bundle/Resources/public/admin/js/modules/search.js b/bundle/Resources/public/admin/js/modules/search.js index b4df78a..21354bc 100644 --- a/bundle/Resources/public/admin/js/modules/search.js +++ b/bundle/Resources/public/admin/js/modules/search.js @@ -1,8 +1,8 @@ export const eZMailingSearchModule = function () { function _init($, $app) { - var $searchNovaeZMailing = $('.novaezmailing-search > input[type="search"]'); - if ($searchNovaeZMailing.length > 0) { - $searchNovaeZMailing.devbridgeAutocomplete({ + var $searchIbexaMailing = $('.ibexamailing-search > input[type="search"]'); + if ($searchIbexaMailing.length > 0) { + $searchIbexaMailing.devbridgeAutocomplete({ serviceUrl: $app.data('search-endpoint'), minChars: 3, onSelect: function (suggestion) { diff --git a/bundle/Resources/public/admin/js/modules/subitems.js b/bundle/Resources/public/admin/js/modules/subitems.js index 19e159d..ddaeb04 100644 --- a/bundle/Resources/public/admin/js/modules/subitems.js +++ b/bundle/Resources/public/admin/js/modules/subitems.js @@ -4,7 +4,7 @@ export const eZMailingSubItemsModule = function () { function _init($, $app) { token = document.querySelector('meta[name="CSRF-Token"]').content; siteaccess = document.querySelector('meta[name="SiteAccess"]').content; - $(".ezmailing-subitem-children", $app).each(function ($container) { + $(".ibexamailing-subitem-children", $app).each(function ($container) { _generate($(this)); }); } @@ -30,7 +30,7 @@ export const eZMailingSubItemsModule = function () { contentTypesMap: contentTypesMap, totalCount: subitemsList.ChildrenCount, handleEditItem: function (content) { - alert("@todo: please PR to https://github.com/Novactive/Nova-eZPlatform-Bundles"); + alert("@todo: please PR to https://github.com/code-rhapsodie"); }, generateLink: function (locationId,contentId) { return window.Routing.generate('_ez_content_view', { locationId, contentId }); diff --git a/bundle/Resources/translations/ezmailing+intl-icu.en.yml b/bundle/Resources/translations/ibexamailing+intl-icu.en.yml similarity index 87% rename from bundle/Resources/translations/ezmailing+intl-icu.en.yml rename to bundle/Resources/translations/ibexamailing+intl-icu.en.yml index 8f4eaf8..1c6330e 100644 --- a/bundle/Resources/translations/ezmailing+intl-icu.en.yml +++ b/bundle/Resources/translations/ibexamailing+intl-icu.en.yml @@ -15,7 +15,7 @@ generic.users.table.email: Email generic.users.table.status: Status generic.users.table.country: Country generic.users.table.origin: Origin -generic.users.table.mailing_list: Mailing List +generic.users.table.mailing_list: MailingRepository List generic.users.table.approbation: Approbation generic.users.table.updated: Updated generic.users.table.created: Created @@ -56,20 +56,20 @@ generic.no_status_mailings: There no Mailings with this Status yet dashboard.title: Dashboard dashboard.subtitle: Quick overview dashboard.quick_actions: Quick Actions -dashboard.create_new_campaign: Create New Campaign -dashboard.see_mailing_lists: See Mailing Lists +dashboard.create_new_campaign: Create New CampaignRepository +dashboard.see_mailing_lists: See MailingRepository Lists dashboard.see_users: See Users dashboard.last_user_updated: Last Users Updated dashboard.last_broadcast: Last Broadcasts dashboard.last_mailing_updated: Latest Mailings Modified dashboard.last_mailing_sent: Latest Mailings Sent -campaign.tabs.campaign: Campaign +campaign.tabs.campaign: CampaignRepository campaign.tabs.associated_content: Associated eZ Content campaign.tabs.mailings: Mailings campaign.tabs.create: Create campaign.tabs.edit: Edit campaign.tabs.delete: Delete -campaign.tabs.delete_campaign_confirmation_1: Are you sure you want to delete this Campaign? +campaign.tabs.delete_campaign_confirmation_1: Are you sure you want to delete this CampaignRepository? campaign.tabs.delete_campaign_confirmation_2: "It is going to remove:" campaign.tabs.one_campaign: 1 campaign campaign.tabs.mailings_with_broadcast: Mailings with their Broadcasts @@ -100,9 +100,9 @@ campaign.breadcrumb.edit: Edit campaign.breadcrumb.users: Users campaign.edit.edit: Edit campaign.edit.edition: Edition -campaign.mailings.campaign: Campaign +campaign.mailings.campaign: CampaignRepository campaign.mailings.mailings: Mailings -campaign.subscriptions.campaign: Campaign +campaign.subscriptions.campaign: CampaignRepository common.list.broadcast_graph.broadcasted_on: Broadcasted on common.list.broadcast.recipient_count: Recipient counts common.list.broadcast.started: Started @@ -116,7 +116,6 @@ common.registration_approbation_button.deny: Deny layout.header.search: Search layout.pagelayout.campaigns: Campaigns layout.pagelayout.administration: Administration -layout.footer.novactive: Novactive eZ Mailing | Made with <3 and designed by Novactive in California. mailing.details.name: Name mailing.details.status: Status mailing.details.subject: Subject @@ -133,7 +132,7 @@ mailing.edit.select_content: Select a Content mailing.edit.campaigns: Campaigns mailing.mailing_tabs.mailing: Mailing mailing.mailing_tabs.associated_content: Associated eZ Content -mailing.mailing_tabs.campaign: Campaign +mailing.mailing_tabs.campaign: CampaignRepository mailing.mailing_tabs.broadcasts: Broadcasts mailing.mailing_tabs.stats: Stats mailing.mailing_tabs.views: View @@ -143,14 +142,14 @@ mailing.mailing_tabs.abort: Abort mailing.mailing_tabs.test: Test mailing.mailing_tabs.confirm: Confirm mailing.mailing_tabs.test_mailing: Test the Mailing -mailing.mailing_tabs.report_mail1: Campaign defines +mailing.mailing_tabs.report_mail1: CampaignRepository defines mailing.mailing_tabs.report_mail2: as report email -mailing.mailing_tabs.add_cc: 'Would you like to cc someone?' +mailing.mailing_tabs.add_cc: 'cc someone' mailing.mailing_tabs.email: email mailing.mailing_tabs.send_test: Send a test mailing.mailing_tabs.cancel: Cancel mailing.mailing_tabs.confirm_sending: Confirm the sending -mailing.mailing_tabs.mailing_lists_count1: Campaign defines +mailing.mailing_tabs.mailing_lists_count1: CampaignRepository defines mailing.mailing_tabs.mailing_lists_count2: Mailing Lists mailing.mailing_tabs.mailing_list_reach: The reach of this Mailing is mailing.mailing_tabs.create_content: Create Content @@ -189,7 +188,7 @@ mailing_list.show.removal_details1: Are you sure you want to delete this Mailing mailing_list.show.removal_details2: It is going to remove mailing_list.show.removal_details3: 1 Mailing List mailing_list.show.registrations: Registrations -mailing_list.show.assignation_to_campagin: assignations to Campaign +mailing_list.show.assignation_to_campagin: assignations to CampaignRepository mailing_list.show.note: "Note: Users are not deleted." tabs.campaigns.part_of_count1: This content is part of tabs.campaigns.part_of_count2: "campaigns." @@ -199,13 +198,13 @@ tabs.mailings.part_of_count2: "mailings." user.index.title: Users user.index.subtitle: entries user.show.information: Information -user.show.delete_user_confirmation1: Are you sure you want to delete this User? +user.show.delete_user_confirmation1: Are you sure you want to delete this UserRepository? user.show.delete_user_confirmation2: "It is going to remove:" -user.show.delete_user_confirmation3: 1 User +user.show.delete_user_confirmation3: 1 UserRepository user.show.registrations: Registrations layout.footer.unsubscribe: Unsubscribe registration.register.confirmation_email_message: You are going to receive an email to confirm your registration. -register.register.confirmation: Registration confirmed. +register.register.confirmation: RegistrationRepository confirmed. register.register.failed: This url is not valid anymore, your registration was not confirmed. register.unregister.confirmation_email_message: You are going to receive an email to confirm your unregistration. register.unregister_confirmation.confirmed: Unregistration confirmed. @@ -228,21 +227,21 @@ messages.stop_sending.sent2: has been sent messages.stop_sending.sent3: A new Mailing has been sent messages.stop_sending.follow_broadcast1: You can now follow the messages.stop_sending.follow_broadcast2: broadcast information here -novaezmailingfull.generic.hello: Hello -novaezmailingfull.generic.generic_view1: You are using the generic 'novaezmailingfull' view. -novaezmailingfull.generic.nova_test_tracking_link: Test Tracking Link - Novactive -novaezmailingfull.generic.ez_test_tracking_link: Test Tracking Link - eZ No -novaezmailingfull.generic.mailing: Mailing -novaezmailingfull.generic.associated_content: Associated content -novaezmailingfull.generic.campaign: Campaign -novaezmailingfull.generic.define_a_view1: Please define a "view" that works in your project -novaezmailingfull.generic.define_a_view2: "Example for a folder: " +ibexamailingfull.generic.hello: Hello +ibexamailingfull.generic.generic_view1: You are using the generic 'ibexamailingfull' view. +ibexamailingfull.generic.test_tracking_link: Test Tracking Link - Code-Rhapsodie +ibexamailingfull.generic.ez_test_tracking_link: Test Tracking Link - eZ No +ibexamailingfull.generic.mailing: Mailing +ibexamailingfull.generic.associated_content: Associated content +ibexamailingfull.generic.campaign: CampaignRepository +ibexamailingfull.generic.define_a_view1: Please define a "view" that works in your project +ibexamailingfull.generic.define_a_view2: "Example for a folder: " menu.savecancel.save: Save menu.savecancel.cancel: Cancel menu.admin_menu.users: Users menu.admin_menu.mailing_lists: Mailing Lists menu.campaign_menu.subscriptions: subscriptions -mailing.buildform.recuring_mailing: "Is it a reccuring Mailing?" +mailing.buildform.recuring_mailing: "Is it a reccuring Mailing ?" mailing.buildform.which_siteaccess: "On which siteaccess?" form.subject: Subject mailinglisttype.buildform.withapproval: "With approval?" diff --git a/bundle/Resources/translations/ezmailing+intl-icu.fr.yml b/bundle/Resources/translations/ibexamailing+intl-icu.fr.yml similarity index 93% rename from bundle/Resources/translations/ezmailing+intl-icu.fr.yml rename to bundle/Resources/translations/ibexamailing+intl-icu.fr.yml index 02cc5e4..8640e85 100644 --- a/bundle/Resources/translations/ezmailing+intl-icu.fr.yml +++ b/bundle/Resources/translations/ibexamailing+intl-icu.fr.yml @@ -117,7 +117,6 @@ common.registration_approbation_button.deny: Rejeter layout.header.search: Rechercher layout.pagelayout.campaigns: Campagnes layout.pagelayout.administration: Administration -layout.footer.novactive: Novactive eZ Mailing | Fait avec <3 et conçu par Novactive en Californie. mailing.details.name: Nom mailing.details.status: Statut mailing.details.subject: Sujet @@ -146,7 +145,7 @@ mailing.mailing_tabs.confirm: Confirmer mailing.mailing_tabs.test_mailing: Tester l'envoi mailing.mailing_tabs.report_mail1: La campagne définit mailing.mailing_tabs.report_mail2: comme courriel de signalement -mailing.mailing_tabs.add_cc: 'Désirez-vous ajouter une personne en cc?' +mailing.mailing_tabs.add_cc: 'Ajouter une personne en cc' mailing.mailing_tabs.email: courriel mailing.mailing_tabs.send_test: Envoyer un test mailing.mailing_tabs.cancel: Annuler @@ -229,15 +228,15 @@ messages.stop_sending.sent2: a été effectué messages.stop_sending.sent3: Un nouveau mail a été envoyé messages.stop_sending.follow_broadcast1: Vous pouvez désormais suivre les messages.stop_sending.follow_broadcast2: informations de diffusion ici -novaezmailingfull.generic.hello: Bonjour -novaezmailingfull.generic.generic_view1: Vous utilisez la vue générique 'novaezmailingfull'. -novaezmailingfull.generic.nova_test_tracking_link: Tester le lien de suivi - Novactive -novaezmailingfull.generic.ez_test_tracking_link: Tester le lien de suivi - eZ No -novaezmailingfull.generic.mailing: Envoi -novaezmailingfull.generic.associated_content: Contenu associé -novaezmailingfull.generic.campaign: Campagne -novaezmailingfull.generic.define_a_view: Veuillez définir une "vue" qui fonctionne dans votre projet -novaezmailingfull.generic.define_a_view2: "Par exemple pour un dossier: " +ibexamailingfull.generic.hello: Bonjour +ibexamailingfull.generic.generic_view1: Vous utilisez la vue générique 'ibexamailingfull'. +ibexamailingfull.generic.test_tracking_link: Tester le lien de suivi - Code-Rhapsodie +ibexamailingfull.generic.ez_test_tracking_link: Tester le lien de suivi - eZ No +ibexamailingfull.generic.mailing: Envoi +ibexamailingfull.generic.associated_content: Contenu associé +ibexamailingfull.generic.campaign: Campagne +ibexamailingfull.generic.define_a_view: Veuillez définir une "vue" qui fonctionne dans votre projet +ibexamailingfull.generic.define_a_view2: "Par exemple pour un dossier: " menu.savecancel.save: Sauvegarder menu.savecancel.cancel: Annuler menu.admin_menu.users: Utilisateurs diff --git a/bundle/Resources/views/admin/campaign/campaign_tabs.html.twig b/bundle/Resources/views/admin/campaign/campaign_tabs.html.twig index 2e13d96..7ca069d 100644 --- a/bundle/Resources/views/admin/campaign/campaign_tabs.html.twig +++ b/bundle/Resources/views/admin/campaign/campaign_tabs.html.twig @@ -1,4 +1,4 @@ -{% trans_default_domain 'ezmailing' %} +{% trans_default_domain 'ibexamailing' %} {% set statusKey = "generic.mailing_statuses."~status %} @@ -8,11 +8,10 @@ {% if status != 'all' %} {% if item.locationId is not null %}