diff --git a/.gitignore b/.gitignore index 38d06d315..26802dca0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,9 @@ composer composer.phar composer.lock docs/build/ +node_modules/* .php_cs.cache +.cache/* ###> symfony/framework-bundle ### /.env.local diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ddf7fccbe..3f1d75ed5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,7 @@ cache: # Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service # See http://docs.gitlab.com/ee/ci/services/README.html for examples. services: - - name: postgis/postgis:12-3.1-alpine + - name: postgis/postgis:14-3.3-alpine alias: db - name: redis alias: redis @@ -21,7 +21,7 @@ variables: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres # configure database access - DATABASE_URL: postgresql://postgres:postgres@db:5432/postgres?serverVersion=12&charset=utf8 + DATABASE_URL: postgresql://postgres:postgres@db:5432/postgres?serverVersion=14&charset=utf8 # fetch the chill-app using git submodules GIT_SUBMODULE_STRATEGY: recursive REDIS_HOST: redis @@ -37,12 +37,11 @@ stages: build: stage: Composer install - image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4 + image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 before_script: - - curl -sS https://getcomposer.org/installer | php - - php -d memory_limit=2G composer.phar config -g cache-dir "$(pwd)/.cache" + - composer config -g cache-dir "$(pwd)/.cache" script: - - php -d memory_limit=2G composer.phar install --optimize-autoloader --no-ansi --no-interaction --no-progress + - composer install --optimize-autoloader --no-ansi --no-interaction --no-progress cache: paths: - .cache/ @@ -54,9 +53,12 @@ build: code_style: stage: Tests - image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4 + image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 script: - - bin/grumphp run --tasks=phpcsfixer + - php-cs-fixer fix --dry-run -v --show-progress=none + cache: + paths: + - .cache/ artifacts: expire_in: 30 min paths: @@ -65,30 +67,49 @@ code_style: phpstan_tests: stage: Tests - image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4 + image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 script: - - bin/grumphp run --tasks=phpstan + - bin/phpstan analyze --memory-limit=2G + cache: + paths: + - .cache/ artifacts: expire_in: 30 min paths: - bin - tests/app/vendor/ -psalm_tests: +rector_tests: stage: Tests - image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4 + image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 script: - - bin/grumphp run --tasks=psalm - allow_failure: true + - bin/rector --dry-run + cache: + paths: + - .cache/ artifacts: expire_in: 30 min paths: - bin - tests/app/vendor/ +# psalm_tests: +# stage: Tests +# image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 +# script: +# - bin/psalm +# allow_failure: true +# artifacts: +# expire_in: 30 min +# paths: +# - bin +# - tests/app/vendor/ + unit_tests: stage: Tests - image: registry.gitlab.com/chill-projet/chill-app/php-base-image:7.4 + image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 + # until we fix testes + allow_failure: true script: - php tests/app/bin/console doctrine:migrations:migrate -n - php -d memory_limit=2G tests/app/bin/console cache:clear --env=dev diff --git a/.php_cs.dist.php b/.php-cs-fixer.dist.php similarity index 64% rename from .php_cs.dist.php rename to .php-cs-fixer.dist.php index bf15b5876..4b5bf98ee 100644 --- a/.php_cs.dist.php +++ b/.php-cs-fixer.dist.php @@ -9,13 +9,24 @@ declare(strict_types=1); * the LICENSE file that was distributed with this source code. */ -$config = require __DIR__ . '/tests/app/vendor/drupol/php-conventions/config/php73/php_cs_fixer.config.php'; +$finder = PhpCsFixer\Finder::create(); -$config - ->getFinder() - ->ignoreDotFiles(false) +$finder + ->in(__DIR__.'/src') + ->append([__FILE__]) + ->exclude(['docs/', 'tests/app']) ->notPath('tests/app') - ->name(['.php_cs.dist.php']); + ->ignoreDotFiles(true) + ->name('**.php') +; + +$config = new PhpCsFixer\Config(); +$config + ->setFinder($finder) + ->setRiskyAllowed(true) + ->setCacheFile('.cache/php-cs-fixer.cache') + ->setUsingCache(true) +; $rules = $config->getRules(); @@ -68,9 +79,42 @@ $riskyRules = [ // 'psr_autoloading' => false, ]; +$untilFullSwitchToPhp8 = [ + 'blank_line_between_import_groups' => false, + 'declare_strict_types' => true, + 'multiline_whitespace_before_semicolons' => false, + 'phpdoc_no_empty_return' => false, +]; + $rules = array_merge( + [ + '@PhpCsFixer' => true, + '@PhpCsFixer:risky' => false, + '@Symfony' => false, + '@Symfony:risky' => false, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public', + 'property_protected', + 'property_private', + 'construct', + 'destruct', + 'magic', + 'phpunit', + 'method_public', + 'method_protected', + 'method_private', + ], + 'sort_algorithm' => 'alpha', + ] + ], $rules, - $riskyRules + $riskyRules, + $untilFullSwitchToPhp8, ); $rules['header_comment']['header'] = trim(file_get_contents(__DIR__ . '/resource/header.txt')); diff --git a/composer.json b/composer.json index 45d7ca832..b47856954 100644 --- a/composer.json +++ b/composer.json @@ -8,19 +8,23 @@ "social worker" ], "require": { - "php": "^7.4", + "php": "^7.4|^8.2", + "ext-json": "*", + "ext-openssl": "*", + "ext-redis": "*", "champs-libres/async-uploader-bundle": "dev-sf4#d57134aee8e504a83c902ff0cf9f8d36ac418290", - "champs-libres/wopi-bundle": "dev-master#6dd8e0a14e00131eb4b889ecc30270ee4a0e5224", - "champs-libres/wopi-lib": "dev-master#8615f4a45a39fc2b6a98765ea835fcfd39618787", + "champs-libres/wopi-bundle": "dev-master@dev", + "champs-libres/wopi-lib": "dev-master@dev", "doctrine/doctrine-bundle": "^2.1", "doctrine/doctrine-migrations-bundle": "^3.0", - "doctrine/orm": "^2.7", + "doctrine/orm": "^2.13.0", "erusev/parsedown": "^1.7", "graylog2/gelf-php": "^1.5", "knplabs/knp-menu-bundle": "^3.0", "knplabs/knp-time-bundle": "^1.12", "knpuniversity/oauth2-client-bundle": "^2.10", "league/csv": "^9.7.1", + "lexik/jwt-authentication-bundle": "^2.16", "nyholm/psr7": "^1.4", "ocramius/package-versions": "^1.10 || ^2", "odolbeau/phone-number-bundle": "^3.6", @@ -29,12 +33,12 @@ "ramsey/uuid-doctrine": "^1.7", "sensio/framework-extra-bundle": "^5.5", "spomky-labs/base64url": "^2.0", - "symfony/asset": "^4.4", "symfony/browser-kit": "^4.4", "symfony/css-selector": "^4.4", "symfony/expression-language": "^4.4", "symfony/form": "^4.4", "symfony/framework-bundle": "^4.4", + "symfony/http-client": "^4.4 || ^5", "symfony/http-foundation": "^4.4", "symfony/intl": "^4.4", "symfony/mailer": "^5.4", @@ -43,12 +47,10 @@ "symfony/monolog-bundle": "^3.5", "symfony/security-bundle": "^4.4", "symfony/serializer": "^5.3", - "symfony/swiftmailer-bundle": "^3.5", "symfony/templating": "^4.4", "symfony/translation": "^4.4", "symfony/twig-bundle": "^4.4", "symfony/validator": "^4.4", - "symfony/web-link": "*", "symfony/webpack-encore-bundle": "^1.11", "symfony/workflow": "^4.4", "symfony/yaml": "^4.4", @@ -61,19 +63,25 @@ }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^3.3", - "drupol/php-conventions": "^5", "fakerphp/faker": "^1.13", + "jangregor/phpstan-prophecy": "^1.0", "nelmio/alice": "^3.8", "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.1", "phpstan/phpstan-strict-rules": "^1.0", "phpunit/phpunit": ">= 7.5", + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^4.0.2", + "rector/rector": "^0.15.23", "symfony/debug-bundle": "^5.1", "symfony/dotenv": "^4.4", "symfony/maker-bundle": "^1.20", "symfony/phpunit-bridge": "^4.4", "symfony/stopwatch": "^4.4", "symfony/var-dumper": "^4.4", - "symfony/web-profiler-bundle": "^4.4" + "vimeo/psalm": "^4.30.0" }, "conflict": { "symfony/symfony": "*" diff --git a/docs/source/_static/code/exports/CountPerson.php b/docs/source/_static/code/exports/CountPerson.php index 48eab8a55..afe19c73b 100644 --- a/docs/source/_static/code/exports/CountPerson.php +++ b/docs/source/_static/code/exports/CountPerson.php @@ -90,9 +90,7 @@ class CountPerson implements ExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { // we gather all center the user choose. - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn($el) => $el['center'], $acl); $qb = $this->entityManager->createQueryBuilder(); diff --git a/docs/source/development/cronjob.rst b/docs/source/development/cronjob.rst new file mode 100644 index 000000000..df72fa922 --- /dev/null +++ b/docs/source/development/cronjob.rst @@ -0,0 +1,93 @@ + +.. Copyright (C) 2014-2023 Champs Libres Cooperative SCRLFS + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +.. _cronjob: + +Cron jobs +********* + +Some tasks must be executed regularly: refresh some materialized views, remove old data, ... + +For this purpose, one can programmatically implements a "cron job", which will be scheduled by a specific command. + +The command :code:`chill:cron-job:execute` +========================================== + +The command :code:`chill:cron-job:execute` will schedule a task, one by one. In a classical implementation, it should +be executed every 15 minutes (more or less), to ensure that every task can be executed. + +.. warning:: + + This command should not be executed in parallel. The installer should ensure that two job are executed concurrently. + +How to implements a cron job ? +============================== + +Implements a :code:`Chill\MainBundle\Cron\CronJobInterface`. Here is an example: + +.. code-block:: php + + namespace Chill\MainBundle\Service\Something; + + use Chill\MainBundle\Cron\CronJobInterface; + use Chill\MainBundle\Entity\CronJobExecution; + use DateInterval; + use DateTimeImmutable; + + class MyCronJob implements CronJobInterface + { + public function canRun(?CronJobExecution $cronJobExecution): bool + { + // the parameter $cronJobExecution contains data about the last execution of the cronjob + // if it is null, it should be executed immediatly + if (null === $cronJobExecution) { + return true; + } + + if ($cronJobExecution->getKey() !== $this->getKey()) { + throw new UnexpectedValueException(); + } + + // this cron job should be executed if the last execution is greater than one day, but only during the night + + $now = new DateTimeImmutable('now'); + + return $cronJobExecution->getLastStart() < $now->sub(new DateInterval('P1D')) + && in_array($now->format('H'), self::ACCEPTED_HOURS, true) + // introduce a random component to ensure a roll of task execution when multiple instances are hosted on same machines + && mt_rand(0, 5) === 0; + } + + public function getKey(): string + { + return 'arbitrary-and-unique-key'; + } + + public function run(): void + { + // here, we execute the command + } + } + +How are cron job scheduled ? +============================ + +If the command :code:`chill:cron-job:execute` is run with one or more :code:`job` argument, those jobs are run, **without checking that the job can run** (the method :code:`canRun` is not executed). + +If any :code:`job` argument is given, the :code:`CronManager` schedule job with those steps: + +* the tasks are ordered, with: + * a priority is given for tasks that weren't never executed; + * then, the tasks are ordered, the last executed are the first in the list +* then, for each tasks, and in the given order, the first task where :code:`canRun` return :code:`TRUE` will be executed. + +The command :code:`chill:cron-job:execute` execute **only one** task. + + + diff --git a/docs/source/development/index.rst b/docs/source/development/index.rst index f35bc12db..52c541c8e 100644 --- a/docs/source/development/index.rst +++ b/docs/source/development/index.rst @@ -34,6 +34,7 @@ As Chill rely on the `symfony `_ framework, reading the fram Useful snippets manual/index.rst Assets + Cron Jobs Layout and UI ************** diff --git a/docs/source/installation/index.rst b/docs/source/installation/index.rst index 01a8c4aee..852a2a6d0 100644 --- a/docs/source/installation/index.rst +++ b/docs/source/installation/index.rst @@ -18,6 +18,7 @@ Installation & Usage :maxdepth: 2 prod.rst + load-addresses.rst prod-calendar-sms-sending.rst msgraph-configure.rst @@ -128,12 +129,12 @@ This script will : .. note:: - In some cases it can happen that an old image (chill_base_php or chill_php) stored in the docker cache will make the script fail. To solve this problem you have to delete the image and the container, before the make init : + In some cases it can happen that an old image (chill_base_php82 or chill_php82) stored in the docker cache will make the script fail. To solve this problem you have to delete the image and the container, before the make init : .. code-block:: bash docker-compose images php - docker rmi -f chill_php:prod + docker rmi -f chill_php82:prod docker-compose rm php @@ -170,7 +171,7 @@ There are several users available: The password is always ``password``. -Now, read `Operations` below. +Now, read `Operations` below. For running in production, read `prod_`. Operations diff --git a/docs/source/installation/load-addresses.rst b/docs/source/installation/load-addresses.rst new file mode 100644 index 000000000..779032fd0 --- /dev/null +++ b/docs/source/installation/load-addresses.rst @@ -0,0 +1,50 @@ + +.. _addresses: + +Addresses +********* + +Chill can store a list of geolocated address references, which are used to suggest address and ensure that the data is correctly stored. + +Those addresses may be load from a dedicated source. + +In France +========= + +The address are loaded from the `BANO `_. The postal codes are loaded from `the official list of +postal codes `_ + +.. code-block:: bash + + # first, load postal codes + bin/console chill:main:postal-code:load:FR + # then, load all addresses, by departement (multiple departement can be loaded by repeating the departement code + bin/console chill:main:address-ref-from-bano 57 54 51 + +In Belgium +========== + +Addresses are prepared from the `BeST Address data `_. + +Postal code are loaded from this database. There is no need to load postal codes from another source (actually, this is strongly discouraged). + +The data are prepared for Chill (`See this repository `_). +One can select postal code by his first number (:code:`1xxx` for postal codes from 1000 to 1999), or a limited list for development purpose. + +.. code-block:: bash + + # load postal code from 1000 to 3999: + bin/console chill:main:address-ref-from-best-addresse 1xxx 2xxx 3xxx + + # load only an extract (for dev purposes) + bin/console chill:main:address-ref-from-best-addresse extract + + # load full addresses (discouraged) + bin/console chill:main:address-ref-from-best-addresse full + +.. note:: + + There is a possibility to load the full list of addresses is discouraged: the loading is optimized with smaller extracts. + + Once you load the full list, it is not possible to load smaller extract: each extract loaded **after** will not + delete the addresses loaded with the full extract (and some addresses will be present twice). diff --git a/docs/source/installation/prod.rst b/docs/source/installation/prod.rst index 4e670b8f8..f51141e8d 100644 --- a/docs/source/installation/prod.rst +++ b/docs/source/installation/prod.rst @@ -1,10 +1,12 @@ .. Copyright (C) 2014-2019 Champs Libres Cooperative SCRLFS -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. -A copy of the license is included in the section entitled "GNU -Free Documentation License". + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +.. _prod: Installation for production ########################### @@ -36,12 +38,25 @@ This should be adapted to your needs: * Think about how you will backup your database. Some adminsys find easier to store database outside of docker, which might be easier to administrate or replicate. +Cron jobs +========= + +The command :code:`chill:cron-job:execute` should be executed every 15 minutes (more or less). + +This command should never be executed concurrently. It should be not have more than one process for a single instance. + +Post-install tasks +================== + +- import addresses. See :ref:`addresses`. + + Tweak symfony messenger ======================= Calendar sync is processed using symfony messenger. -You can tweak the configuration +You can tweak the configuration Going further: diff --git a/grumphp.yml b/grumphp.yml deleted file mode 100644 index c81830d5b..000000000 --- a/grumphp.yml +++ /dev/null @@ -1,40 +0,0 @@ -imports: - - { - resource: tests/app/vendor/drupol/php-conventions/config/php73/grumphp.yml, - } - -parameters: - tasks.phpcsfixer.config: .php_cs.dist.php - tasks.license.name: AGPL-3.0 - tasks.license.holder: Champs-Libres - tasks.license.date_from: 2001 - - tasks.phpcsfixer.allow_risky: true - tasks.phpcsfixer.diff: true - tasks.phpstan.level: 1 - tasks.phpstan.blocking: true - tasks.phpstan.ignore_patterns: - - "/.github/" - - "/.idea/" - - "/build/" - - "/benchmarks/" - - "/docs/" - - "/node_modules/" - - "/resource/" - - "/spec/" - - "/var/" - - "/vendor/" - - "/tests/app" - - # Psalm - tasks.psalm.blocking: true - tasks.psalm.ignore_patterns: - - "/.github/" - - "/.idea/" - - "/build/" - - "/benchmarks/" - - "/node_modules/" - - "/resource/" - - "/spec/" - - "/var/" - - "/vendor/" diff --git a/package.json b/package.json index 17b02c63a..590976cfa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "chill", - "version": "2.0.0", - "devDependencies": { + "name": "chill", + "version": "2.0.0", + "devDependencies": { "@alexlafroscia/yaml-merge": "^4.0.0", "@apidevtools/swagger-cli": "^4.0.4", "@babel/core": "^7.20.5", @@ -34,13 +34,14 @@ "webpack-cli": "^5.0.1" }, "dependencies": { - "@fullcalendar/core": "^5.11.0", - "@fullcalendar/daygrid": "^5.11.0", - "@fullcalendar/interaction": "^5.11.0", - "@fullcalendar/list": "^5.11.0", - "@fullcalendar/timegrid": "^5.11.0", - "@fullcalendar/vue3": "^5.11.1", + "@fullcalendar/core": "^6.1.4", + "@fullcalendar/daygrid": "^6.1.4", + "@fullcalendar/interaction": "^6.1.4", + "@fullcalendar/list": "^6.1.4", + "@fullcalendar/timegrid": "^6.1.4", + "@fullcalendar/vue3": "^6.1.4", "@popperjs/core": "^2.9.2", + "@types/leaflet": "^1.9.3", "dropzone": "^5.7.6", "es6-promise": "^4.2.8", "leaflet": "^1.7.1", diff --git a/phpstan-baseline-level-2.neon b/phpstan-baseline-level-2.neon new file mode 100644 index 000000000..6f7cec495 --- /dev/null +++ b/phpstan-baseline-level-2.neon @@ -0,0 +1,301 @@ +parameters: + ignoreErrors: + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\ActivityBundle\\\\Entity\\\\Activity\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\MainBundle\\\\Entity\\\\Scope\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\PersonBundle\\\\Entity\\\\Person\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, DateTime\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReasonCategory\\|null given\\.$#" + count: 3 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReason\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php + + - + message: "#^Call to method DateTime\\:\\:setTimezone\\(\\) with incorrect case\\: setTimeZone$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Form/ActivityType.php + + - + message: "#^Only booleans are allowed in &&, Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\|null given on the right side\\.$#" + count: 2 + path: src/Bundle/ChillActivityBundle/Form/ActivityType.php + + - + message: "#^Only booleans are allowed in an if condition, Chill\\\\AsideActivityBundle\\\\Entity\\\\AsideActivityCategory\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php + + - + message: "#^Call to method DateTimeImmutable\\:\\:setTimezone\\(\\) with incorrect case\\: setTimeZone$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\MainBundle\\\\Entity\\\\Location\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarController.php + + - + message: "#^Only booleans are allowed in an if condition, Symfony\\\\Component\\\\Validator\\\\ConstraintViolationListInterface given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\|null given\\.$#" + count: 3 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\|null given\\.$#" + count: 4 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, string given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getFirstName\\(\\) with incorrect case\\: getFirstname$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getLastName\\(\\) with incorrect case\\: getLastname$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getMobilenumber\\(\\) with incorrect case\\: getMobileNumber$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getPhonenumber\\(\\) with incorrect case\\: getPhoneNumber$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\Event given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\Event\\|null given\\.$#" + count: 3 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, int given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Only numeric types are allowed in pre\\-increment, string given\\.$#" + count: 2 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\EventType\\|null given\\.$#" + count: 4 + path: src/Bundle/ChillEventBundle/Controller/EventTypeController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\Participation\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\Role\\|null given\\.$#" + count: 4 + path: src/Bundle/ChillEventBundle/Controller/RoleController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\EventBundle\\\\Entity\\\\Status\\|null given\\.$#" + count: 4 + path: src/Bundle/ChillEventBundle/Controller/StatusController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\Language\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/LoadAndUpdateLanguagesCommand.php + + - + message: "#^Only booleans are allowed in an if condition, Chill\\\\MainBundle\\\\Entity\\\\Language\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/LoadAndUpdateLanguagesCommand.php + + - + message: "#^Only booleans are allowed in an if condition, int given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\Center\\|null given\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/Controller/CenterController.php + + - + message: "#^Call to method Redis\\:\\:setex\\(\\) with incorrect case\\: setEx$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\|null given\\.$#" + count: 5 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\RoleScope\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\Scope\\|null given\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/Controller/ScopeController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\GroupCenter\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/UserController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\MainBundle\\\\Entity\\\\User\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/UserController.php + + - + message: "#^Only booleans are allowed in an if condition, int given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadPostalCodes.php + + - + message: "#^Only numeric types are allowed in pre\\-increment, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php + + - + message: "#^Only booleans are allowed in an if condition, int given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, string\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/PickUserLocationType.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, int\\<0, max\\> given\\.$#" + count: 4 + path: src/Bundle/ChillMainBundle/Search/SearchApiQuery.php + + - + message: "#^Call to method Chill\\\\MainBundle\\\\Entity\\\\Address\\:\\:getPostcode\\(\\) with incorrect case\\: getPostCode$#" + count: 6 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Only booleans are allowed in an if condition, Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\ClassDiscriminatorMapping\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DoctrineExistingEntityNormalizer.php + + - + message: "#^Only booleans are allowed in a negated boolean, null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriodParticipation\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getFirstName\\(\\) with incorrect case\\: getFirstname$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getLastName\\(\\) with incorrect case\\: getLastname$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php + + - + message: "#^Only booleans are allowed in an if condition, int\\<0, max\\> given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/SimilarPersonMatcher.php + + - + message: "#^Only booleans are allowed in &&, null given on the left side\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\Household\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Only booleans are allowed in a ternary operator condition, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Call to method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getDeathdate\\(\\) with incorrect case\\: getDeathDate$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Templating/Entity/PersonRender.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\PersonBundle\\\\Entity\\\\Person\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Only booleans are allowed in a negated boolean, Chill\\\\ReportBundle\\\\Entity\\\\Report given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Call to method Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:setFirstname\\(\\) with incorrect case\\: setFirstName$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/EventListener/ThirdPartyEventListener.php + + - + message: "#^Dynamic call to static method Chill\\\\ThirdPartyBundle\\\\ThirdPartyType\\\\ThirdPartyTypeProviderInterface\\:\\:getKey\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/ThirdPartyType/ThirdPartyTypeManager.php diff --git a/phpstan-baseline-level-3.neon b/phpstan-baseline-level-3.neon new file mode 100644 index 000000000..b7091f4ad --- /dev/null +++ b/phpstan-baseline-level-3.neon @@ -0,0 +1,804 @@ +parameters: + ignoreErrors: + - + message: "#^Return type \\(array\\\\) of method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepository\\:\\:findByPerson\\(\\) should be covariant with return type \\(array\\\\) of method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepositoryInterface\\:\\:findByPerson\\(\\)$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Return type \\(array\\\\) of method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityReasonRepository\\:\\:findAll\\(\\) should be covariant with return type \\(array\\\\) of method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findAll\\(\\)$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php + + - + message: "#^Return type \\(array\\\\>\\) of method Chill\\\\AsideActivityBundle\\\\Security\\\\AsideActivityVoter\\:\\:getRolesWithHierarchy\\(\\) should be covariant with return type \\(array\\\\>\\) of method Chill\\\\MainBundle\\\\Security\\\\ProvideRoleHierarchyInterface\\:\\:getRolesWithHierarchy\\(\\)$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Security/AsideActivityVoter.php + + - + message: "#^Parameter \\#1 \\$criteria \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$criteria \\(array\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepositoryInterface\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php + + - + message: "#^Parameter \\#1 \\$criteria \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepository\\:\\:findOneBy\\(\\) should be contravariant with parameter \\$criteria \\(array\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepositoryInterface\\:\\:findOneBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php + + - + message: "#^Parameter \\#2 \\$orderBy \\(array\\\\|null\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$orderBy \\(array\\|null\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepositoryInterface\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php + + - + message: "#^Return type \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepository\\:\\:findAll\\(\\) should be covariant with return type \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepositoryInterface\\:\\:findAll\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php + + - + message: "#^Return type \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepository\\:\\:findBy\\(\\) should be covariant with return type \\(array\\\\) of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarDocRepositoryInterface\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\CalendarBundle\\\\Entity\\\\CalendarDoc\\) of method Chill\\\\CalendarBundle\\\\Security\\\\Voter\\\\CalendarDocVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Security/Voter/CalendarDocVoter.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\CalendarBundle\\\\Entity\\\\Invite\\) of method Chill\\\\CalendarBundle\\\\Security\\\\Voter\\\\InviteVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Security/Voter/InviteVoter.php + + + - + message: "#^Return type \\(int\\|void\\|null\\) of method Chill\\\\CustomFieldsBundle\\\\Command\\\\CreateFieldsOnGroupCommand\\:\\:execute\\(\\) should be covariant with return type \\(int\\) of method Symfony\\\\Component\\\\Console\\\\Command\\\\Command\\:\\:execute\\(\\)$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php + + - + message: "#^Parameter \\#1 \\$customFieldsGroup \\(Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\|null\\) of method Chill\\\\CustomFieldsBundle\\\\Form\\\\DataTransformer\\\\CustomFieldsGroupToIdTransformer\\:\\:transform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:transform\\(\\)$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Parameter \\#1 \\$id \\(string\\) of method Chill\\\\CustomFieldsBundle\\\\Form\\\\DataTransformer\\\\CustomFieldsGroupToIdTransformer\\:\\:reverseTransform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:reverseTransform\\(\\)$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Parameter \\#2 \\$query \\(Doctrine\\\\ORM\\\\QueryBuilder\\) of method Chill\\\\DocGeneratorBundle\\\\Controller\\\\AdminDocGeneratorTemplateController\\:\\:orderQuery\\(\\) should be contravariant with parameter \\$query \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:orderQuery\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Controller/AdminDocGeneratorTemplateController.php + + - + message: "#^Parameter \\#1 \\$object \\(Doctrine\\\\Common\\\\Collections\\\\Collection\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\CollectionDocGenNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\CollectionDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\CollectionDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php + + - + message: "#^Return type \\(array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|void\\|null\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\CollectionDocGenNormalizer\\:\\:normalize\\(\\) should be covariant with return type \\(array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Return type \\(Chill\\\\MainBundle\\\\Entity\\\\Scope\\|null\\) of method Chill\\\\DocStoreBundle\\\\Entity\\\\PersonDocument\\:\\:getScope\\(\\) should be covariant with return type \\(Chill\\\\MainBundle\\\\Entity\\\\Scope\\) of method Chill\\\\MainBundle\\\\Entity\\\\HasScopeInterface\\:\\:getScope\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Entity/PersonDocument.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\DocStoreBundle\\\\Entity\\\\PersonDocument\\) of method Chill\\\\DocStoreBundle\\\\Security\\\\Authorization\\\\PersonDocumentVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\DocStoreBundle\\\\Serializer\\\\Normalizer\\\\StoredObjectDenormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\DocStoreBundle\\\\Serializer\\\\Normalizer\\\\StoredObjectDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\DocStoreBundle\\\\Entity\\\\AccompanyingCourseDocument\\) of method Chill\\\\DocStoreBundle\\\\Workflow\\\\AccompanyingCourseDocumentWorkflowHandler\\:\\:getRelatedObjects\\(\\) should be contravariant with parameter \\$object \\(object\\) of method Chill\\\\MainBundle\\\\Workflow\\\\EntityWorkflowHandlerInterface\\:\\:getRelatedObjects\\(\\)$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php + + - + message: "#^Parameter \\#1 \\$value \\(null\\) of method Chill\\\\EventBundle\\\\Form\\\\ChoiceLoader\\\\EventChoiceLoader\\:\\:loadChoiceList\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoiceList\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\EventBundle\\\\Form\\\\ChoiceLoader\\\\EventChoiceLoader\\:\\:loadChoicesForValues\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoicesForValues\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\EventBundle\\\\Form\\\\ChoiceLoader\\\\EventChoiceLoader\\:\\:loadValuesForChoices\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadValuesForChoices\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\EventBundle\\\\Entity\\\\Event\\) of method Chill\\\\EventBundle\\\\Security\\\\Authorization\\\\EventVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\EventBundle\\\\Entity\\\\Participation\\) of method Chill\\\\EventBundle\\\\Security\\\\Authorization\\\\ParticipationVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php + + - + message: "#^Parameter \\#1 \\$entity \\(Chill\\\\EventBundle\\\\Entity\\\\Event\\) of method Chill\\\\EventBundle\\\\Timeline\\\\TimelineEventProvider\\:\\:getEntityTemplate\\(\\) should be contravariant with parameter \\$entity \\(Chill\\\\MainBundle\\\\Timeline\\\\type\\) of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineProviderInterface\\:\\:getEntityTemplate\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php + + - + message: "#^Parameter \\#2 \\$type \\(null\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Routing\\\\CRUDRoutesLoader\\:\\:supports\\(\\) should be contravariant with parameter \\$type \\(string\\|null\\) of method Symfony\\\\Component\\\\Config\\\\Loader\\\\LoaderInterface\\:\\:supports\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php + + - + message: "#^Parameter \\#2 \\$query \\(Doctrine\\\\ORM\\\\QueryBuilder\\) of method Chill\\\\MainBundle\\\\Controller\\\\LocationApiController\\:\\:orderQuery\\(\\) should be contravariant with parameter \\$query \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:orderQuery\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/LocationApiController.php + + - + message: "#^Parameter \\#3 \\$query \\(Doctrine\\\\ORM\\\\QueryBuilder\\) of method Chill\\\\MainBundle\\\\Controller\\\\UserApiController\\:\\:customizeQuery\\(\\) should be contravariant with parameter \\$query \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:customizeQuery\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/UserApiController.php + + - + message: "#^Return type \\(object\\|null\\) of method Chill\\\\MainBundle\\\\DependencyInjection\\\\ChillMainExtension\\:\\:getConfiguration\\(\\) should be covariant with return type \\(Symfony\\\\Component\\\\Config\\\\Definition\\\\ConfigurationInterface\\|null\\) of method Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\ConfigurationExtensionInterface\\:\\:getConfiguration\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php + + - + message: "#^Return type \\(object\\|null\\) of method Chill\\\\MainBundle\\\\DependencyInjection\\\\ChillMainExtension\\:\\:getConfiguration\\(\\) should be covariant with return type \\(Symfony\\\\Component\\\\Config\\\\Definition\\\\ConfigurationInterface\\|null\\) of method Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\Extension\\:\\:getConfiguration\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php + + - + message: "#^Parameter \\#1 \\$value \\(null\\) of method Chill\\\\MainBundle\\\\Form\\\\ChoiceLoader\\\\PostalCodeChoiceLoader\\:\\:loadChoiceList\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoiceList\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\MainBundle\\\\Form\\\\ChoiceLoader\\\\PostalCodeChoiceLoader\\:\\:loadChoicesForValues\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoicesForValues\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\MainBundle\\\\Form\\\\ChoiceLoader\\\\PostalCodeChoiceLoader\\:\\:loadValuesForChoices\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadValuesForChoices\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php + + - + message: "#^Parameter \\#1 \\$address \\(Chill\\\\MainBundle\\\\Entity\\\\Address\\) of method Chill\\\\MainBundle\\\\Form\\\\DataMapper\\\\AddressDataMapper\\:\\:mapDataToForms\\(\\) should be contravariant with parameter \\$viewData \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapDataToForms\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Parameter \\#1 \\$forms \\(Iterator\\) of method Chill\\\\MainBundle\\\\Form\\\\DataMapper\\\\AddressDataMapper\\:\\:mapFormsToData\\(\\) should be contravariant with parameter \\$forms \\(iterable\\&Traversable\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapFormsToData\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Parameter \\#2 \\$address \\(Chill\\\\MainBundle\\\\Entity\\\\Address\\) of method Chill\\\\MainBundle\\\\Form\\\\DataMapper\\\\AddressDataMapper\\:\\:mapFormsToData\\(\\) should be contravariant with parameter \\$viewData \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapFormsToData\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Parameter \\#2 \\$forms \\(Iterator\\) of method Chill\\\\MainBundle\\\\Form\\\\DataMapper\\\\AddressDataMapper\\:\\:mapDataToForms\\(\\) should be contravariant with parameter \\$forms \\(iterable\\&Traversable\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapDataToForms\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Parameter \\#1 \\$value \\(string\\) of method Chill\\\\MainBundle\\\\Form\\\\DataTransformer\\\\IdToEntityDataTransformer\\:\\:reverseTransform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:reverseTransform\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php + + - + message: "#^Parameter \\#1 \\$value \\(array\\\\|Chill\\\\MainBundle\\\\Entity\\\\User\\) of method Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\EntityToJsonTransformer\\:\\:transform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:transform\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php + + - + message: "#^Parameter \\#1 \\$array \\(array\\) of method Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\MultipleObjectsToIdTransformer\\:\\:transform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:transform\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php + + - + message: "#^Parameter \\#1 \\$id \\(string\\) of method Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\ObjectToIdTransformer\\:\\:reverseTransform\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataTransformerInterface\\:\\:reverseTransform\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/ObjectToIdTransformer.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\) of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\EntityWorkflowVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/EntityWorkflowVoter.php + + - + message: "#^Parameter \\#1 \\$entity \\(Chill\\\\MainBundle\\\\Entity\\\\HasCenterInterface\\) of method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\DefaultCenterResolver\\:\\:resolveCenter\\(\\) should be contravariant with parameter \\$entity \\(object\\) of method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\CenterResolverInterface\\:\\:resolveCenter\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultCenterResolver.php + + - + message: "#^Parameter \\#1 \\$entity \\(Chill\\\\MainBundle\\\\Entity\\\\HasScopeInterface\\|Chill\\\\MainBundle\\\\Entity\\\\HasScopesInterface\\) of method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\DefaultScopeResolver\\:\\:resolveScope\\(\\) should be contravariant with parameter \\$entity \\(mixed\\) of method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\ScopeResolverInterface\\:\\:resolveScope\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultScopeResolver.php + + - + message: "#^Parameter \\#1 \\$address \\(Chill\\\\MainBundle\\\\Entity\\\\Address\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\AddressNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\AddressNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\AddressNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CenterNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CenterNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CenterNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CenterNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CenterNormalizer.php + + - + message: "#^Parameter \\#1 \\$collection \\(Chill\\\\MainBundle\\\\Serializer\\\\Model\\\\Collection\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CollectionNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CollectionNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CollectionNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CollectionNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\MainBundle\\\\Entity\\\\Embeddable\\\\CommentEmbeddable\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\CommentEmbeddableDocGenNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CommentEmbeddableDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DiscriminatedObjectDenormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DiscriminatedObjectDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DiscriminatedObjectDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareDenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DiscriminatedObjectDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DiscriminatedObjectDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DiscriminatedObjectDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DoctrineExistingEntityNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DoctrineExistingEntityNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DoctrineExistingEntityNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DoctrineExistingEntityNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\EntityWorkflowNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/EntityWorkflowNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflowStep\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\EntityWorkflowStepNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/EntityWorkflowStepNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\MainBundle\\\\Entity\\\\Notification\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\NotificationNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/NotificationNormalizer.php + + - + message: "#^Return type \\(array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|void\\|null\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\NotificationNormalizer\\:\\:normalize\\(\\) should be covariant with return type \\(array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/NotificationNormalizer.php + + - + message: "#^Parameter \\#1 \\$data \\(string\\|null\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\PhonenumberNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$data \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\PhonenumberNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PhonenumberNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\PointNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PointNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\PointNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PointNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\PrivateCommentEmbeddableNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PrivateCommentEmbeddableNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\UserNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\UserNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\UserNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php + + + - + message: "#^Parameter \\#1 \\$value \\(string\\) of method Chill\\\\MainBundle\\\\Validation\\\\Validator\\\\ValidPhonenumber\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Validation/Validator/ValidPhonenumber.php + + - + message: "#^Parameter \\#2 \\$constraint \\(Chill\\\\MainBundle\\\\Validation\\\\Constraint\\\\PhonenumberConstraint\\) of method Chill\\\\MainBundle\\\\Validation\\\\Validator\\\\ValidPhonenumber\\:\\:validate\\(\\) should be contravariant with parameter \\$constraint \\(Symfony\\\\Component\\\\Validator\\\\Constraint\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Validation/Validator/ValidPhonenumber.php + + - + message: "#^Parameter \\#1 \\$value \\(object\\) of method Chill\\\\MainBundle\\\\Validator\\\\Constraints\\\\Entity\\\\UserCircleConsistencyValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Validator/Constraints/Entity/UserCircleConsistencyValidator.php + + - + message: "#^Parameter \\#2 \\$constraint \\(Chill\\\\MainBundle\\\\Validator\\\\Constraints\\\\Entity\\\\UserCircleConsistency\\) of method Chill\\\\MainBundle\\\\Validator\\\\Constraints\\\\Entity\\\\UserCircleConsistencyValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$constraint \\(Symfony\\\\Component\\\\Validator\\\\Constraint\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Validator/Constraints/Entity/UserCircleConsistencyValidator.php + + - + message: "#^Parameter \\#1 \\$value \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\) of method Chill\\\\MainBundle\\\\Workflow\\\\Validator\\\\EntityWorkflowCreationValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Workflow/Validator/EntityWorkflowCreationValidator.php + + - + message: "#^Parameter \\#1 \\$value \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflowStep\\) of method Chill\\\\MainBundle\\\\Workflow\\\\Validator\\\\StepDestValidValidator\\:\\:validate\\(\\) should be contravariant with parameter \\$value \\(mixed\\) of method Symfony\\\\Component\\\\Validator\\\\ConstraintValidatorInterface\\:\\:validate\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Workflow/Validator/StepDestValidValidator.php + + - + message: "#^Parameter \\#3 \\$query \\(Doctrine\\\\ORM\\\\QueryBuilder\\) of method Chill\\\\PersonBundle\\\\Controller\\\\HouseholdCompositionTypeApiController\\:\\:customizeQuery\\(\\) should be contravariant with parameter \\$query \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:customizeQuery\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionTypeApiController.php + + - + message: "#^Return type \\(Doctrine\\\\Common\\\\Collections\\\\Collection\\) of method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:getScopes\\(\\) should be covariant with return type \\(iterable\\\\) of method Chill\\\\MainBundle\\\\Entity\\\\HasScopesInterface\\:\\:getScopes\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Return type \\(Chill\\\\MainBundle\\\\Entity\\\\Center\\|null\\) of method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:getCenter\\(\\) should be covariant with return type \\(Chill\\\\MainBundle\\\\Entity\\\\Center\\) of method Chill\\\\MainBundle\\\\Entity\\\\HasCenterInterface\\:\\:getCenter\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Parameter \\#1 \\$value \\(null\\) of method Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\PersonChoiceLoader\\:\\:loadChoiceList\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoiceList\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\PersonChoiceLoader\\:\\:loadChoicesForValues\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadChoicesForValues\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$value \\(null\\) of method Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\PersonChoiceLoader\\:\\:loadValuesForChoices\\(\\) should be contravariant with parameter \\$value \\(\\(callable\\(\\)\\: mixed\\)\\|null\\) of method Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\Loader\\\\ChoiceLoaderInterface\\:\\:loadValuesForChoices\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$viewData \\(Doctrine\\\\Common\\\\Collections\\\\Collection\\) of method Chill\\\\PersonBundle\\\\Form\\\\DataMapper\\\\PersonAltNameDataMapper\\:\\:mapFormsToData\\(\\) should be contravariant with parameter \\$viewData \\(mixed\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapFormsToData\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php + + - + message: "#^Parameter \\#3 \\$limit \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$limit \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php + + - + message: "#^Parameter \\#4 \\$offset \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$offset \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkEvaluationRepository.php + + - + message: "#^Parameter \\#3 \\$limit \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\HouseholdCompositionRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$limit \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/HouseholdCompositionRepository.php + + - + message: "#^Parameter \\#4 \\$offset \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\HouseholdCompositionRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$offset \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/HouseholdCompositionRepository.php + + - + message: "#^Parameter \\#3 \\$limit \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\HouseholdCompositionRepositoryInterface\\:\\:findBy\\(\\) should be contravariant with parameter \\$limit \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/HouseholdCompositionRepositoryInterface.php + + - + message: "#^Parameter \\#4 \\$offset \\(int\\) of method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\HouseholdCompositionRepositoryInterface\\:\\:findBy\\(\\) should be contravariant with parameter \\$offset \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/HouseholdCompositionRepositoryInterface.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\EvaluationRepository\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepository.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\EvaluationRepositoryInterface\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/EvaluationRepositoryInterface.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\GoalRepository\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\ResultRepository\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\SocialActionRepository\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialActionRepository.php + + - + message: "#^Return type \\(class\\-string\\) of method Chill\\\\PersonBundle\\\\Repository\\\\SocialWork\\\\SocialIssueRepository\\:\\:getClassName\\(\\) should be covariant with return type \\(class\\-string\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:getClassName\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/SocialWork/SocialIssueRepository.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationDocument\\) of method Chill\\\\PersonBundle\\\\Security\\\\Authorization\\\\AccompanyingPeriodWorkEvaluationDocumentVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationDocumentVoter.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluation\\) of method Chill\\\\PersonBundle\\\\Security\\\\Authorization\\\\AccompanyingPeriodWorkEvaluationVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationVoter.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\) of method Chill\\\\PersonBundle\\\\Security\\\\Authorization\\\\AccompanyingPeriodWorkVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Parameter \\#1 \\$period \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\|null\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodDocGenNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Parameter \\#1 \\$origin \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\Origin\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodOriginNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodOriginNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodOriginNormalizer.php + + - + message: "#^Parameter \\#1 \\$participation \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriodParticipation\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodParticipationNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodParticipationNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodResourceNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodResourceNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodResourceNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkDenormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareDenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationDenormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareDenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationDenormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDenormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluation\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\MembersEditorNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\MembersEditorNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonDocGenNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Parameter \\#1 \\$person \\(Chill\\\\PersonBundle\\\\Entity\\\\Person\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonJsonNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonJsonNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonJsonNormalizer\\:\\:denormalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:denormalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Parameter \\#3 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonJsonNormalizer\\:\\:supportsDenormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface\\:\\:supportsDenormalization\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Parameter \\#1 \\$relation \\(Chill\\\\PersonBundle\\\\Entity\\\\Relationships\\\\Relationship\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\RelationshipDocGenNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/RelationshipDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\RelationshipDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/RelationshipDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\RelationshipDocGenNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/RelationshipDocGenNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialActionNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialActionNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialActionNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialIssueNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialIssueNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\ContextAwareNormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php + + - + message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialIssueNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\) of method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\WorkflowNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/WorkflowNormalizer.php + + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationDocument\\) of method Chill\\\\PersonBundle\\\\Workflow\\\\AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler\\:\\:getRelatedObjects\\(\\) should be contravariant with parameter \\$object \\(object\\) of method Chill\\\\MainBundle\\\\Workflow\\\\EntityWorkflowHandlerInterface\\:\\:getRelatedObjects\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluation\\) of method Chill\\\\PersonBundle\\\\Workflow\\\\AccompanyingPeriodWorkEvaluationWorkflowHandler\\:\\:getRelatedObjects\\(\\) should be contravariant with parameter \\$object \\(object\\) of method Chill\\\\MainBundle\\\\Workflow\\\\EntityWorkflowHandlerInterface\\:\\:getRelatedObjects\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkEvaluationWorkflowHandler.php + + - + message: "#^Parameter \\#1 \\$object \\(Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\) of method Chill\\\\PersonBundle\\\\Workflow\\\\AccompanyingPeriodWorkWorkflowHandler\\:\\:getRelatedObjects\\(\\) should be contravariant with parameter \\$object \\(object\\) of method Chill\\\\MainBundle\\\\Workflow\\\\EntityWorkflowHandlerInterface\\:\\:getRelatedObjects\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkWorkflowHandler.php + + - + message: "#^Return type \\(Chill\\\\MainBundle\\\\Entity\\\\Center\\|null\\) of method Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:getCenter\\(\\) should be covariant with return type \\(Chill\\\\MainBundle\\\\Entity\\\\Center\\) of method Chill\\\\MainBundle\\\\Entity\\\\HasCenterInterface\\:\\:getCenter\\(\\)$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Return type \\(Chill\\\\MainBundle\\\\Entity\\\\Scope\\|null\\) of method Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:getScope\\(\\) should be covariant with return type \\(Chill\\\\MainBundle\\\\Entity\\\\Scope\\) of method Chill\\\\MainBundle\\\\Entity\\\\HasScopeInterface\\:\\:getScope\\(\\)$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Parameter \\#3 \\$entity \\(Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\) of method Chill\\\\ThirdPartyBundle\\\\Controller\\\\ThirdPartyController\\:\\:onPostFetchEntity\\(\\) should be contravariant with parameter \\$entity \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:onPostFetchEntity\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Controller/ThirdPartyController.php + + - + message: "#^Parameter \\#1 \\$createdAt \\(DateTimeImmutable\\) of method Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:setCreatedAt\\(\\) should be contravariant with parameter \\$datetime \\(DateTimeInterface\\) of method Chill\\\\MainBundle\\\\Doctrine\\\\Model\\\\TrackCreationInterface\\:\\:setCreatedAt\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^Parameter \\#1 \\$updatedAt \\(DateTimeImmutable\\) of method Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:setUpdatedAt\\(\\) should be contravariant with parameter \\$datetime \\(DateTimeInterface\\) of method Chill\\\\MainBundle\\\\Doctrine\\\\Model\\\\TrackUpdateInterface\\:\\:setUpdatedAt\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^Parameter \\#3 \\$limit \\(null\\) of method Chill\\\\ThirdPartyBundle\\\\Repository\\\\ThirdPartyRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$limit \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php + + - + message: "#^Parameter \\#4 \\$offset \\(null\\) of method Chill\\\\ThirdPartyBundle\\\\Repository\\\\ThirdPartyRepository\\:\\:findBy\\(\\) should be contravariant with parameter \\$offset \\(int\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php + + - + message: "#^Parameter \\#2 \\$subject \\(Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\|null\\) of method Chill\\\\ThirdPartyBundle\\\\Security\\\\Voter\\\\ThirdPartyVoter\\:\\:voteOnAttribute\\(\\) should be contravariant with parameter \\$subject \\(mixed\\) of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authorization\\\\Voter\\\\Voter\\:\\:voteOnAttribute\\(\\)$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php + + - + message: "#^Parameter \\#1 \\$document \\(Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getBasename\\(\\) should be contravariant with parameter \\$document \\(ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document\\) of method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\DocumentManagerInterface\\:\\:getBasename\\(\\)$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Parameter \\#1 \\$document \\(Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getCreationDate\\(\\) should be contravariant with parameter \\$document \\(ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document\\) of method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\DocumentManagerInterface\\:\\:getCreationDate\\(\\)$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Parameter \\#1 \\$document \\(Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getDocumentId\\(\\) should be contravariant with parameter \\$document \\(ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document\\) of method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\DocumentManagerInterface\\:\\:getDocumentId\\(\\)$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Parameter \\#1 \\$document \\(Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getLastModifiedDate\\(\\) should be contravariant with parameter \\$document \\(ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document\\) of method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\DocumentManagerInterface\\:\\:getLastModifiedDate\\(\\)$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php diff --git a/phpstan-baseline-level-4.neon b/phpstan-baseline-level-4.neon new file mode 100644 index 000000000..833a55afb --- /dev/null +++ b/phpstan-baseline-level-4.neon @@ -0,0 +1,4793 @@ +parameters: + ignoreErrors: + - + message: "#^Access to an undefined property Chill\\\\ActivityBundle\\\\Entity\\\\Activity\\:\\:\\$personsAssociated\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Access to an undefined property Chill\\\\ActivityBundle\\\\Entity\\\\Activity\\:\\:\\$personsNotAssociated\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Serializer\\\\SerializerInterface\\:\\:normalize\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and 'ChillActivityBundle…'\\|'ChillActivityBundle…' will always evaluate to false\\.$#" + count: 3 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Controller\\\\ActivityReasonCategoryController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Controller\\\\ActivityReasonCategoryController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Controller\\\\ActivityReasonController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Controller\\\\ActivityReasonController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php + + - + message: "#^Else branch is unreachable because previous condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReason will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityNotifications.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Entity\\\\Activity\\:\\:\\$user \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/Activity.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Entity\\\\ActivityPresence\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReason\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReason.php + + - + message: "#^Argument of an invalid type string supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php + + - + message: "#^Binary operation \"\\.\" between 'ActivityReasonCateg…' and array results in an error\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReasonCategory\\:\\:getName\\(\\) should return array but returns string\\.$#" + count: 3 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReasonCategory\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Entity\\\\ActivityReasonCategory\\:\\:\\$name \\(string\\) does not accept array\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/EntityListener/ActivityEntityListener.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Export\\\\Aggregator\\\\ACPAggregators\\\\DateAggregator\\:\\:\\$translator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\ActivityBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\ActivityBundle\\\\Form\\\\ActivityReasonCategoryType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\ActivityBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByAccompanyingPeriod\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByPersonImplied\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepository\\:\\:findByAccompanyingPeriod\\(\\) has invalid return type Chill\\\\ActivityBundle\\\\Repository\\\\Activity\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepository\\:\\:getWhereClause\\(\\) should return array but returns string\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepositoryInterface\\:\\:findByAccompanyingPeriod\\(\\) has invalid return type Chill\\\\ActivityBundle\\\\Repository\\\\Activity\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php + + - + message: "#^Method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepositoryInterface\\:\\:findByPerson\\(\\) has invalid return type Chill\\\\ActivityBundle\\\\Repository\\\\Activity\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php + + - + message: "#^Property Chill\\\\ActivityBundle\\\\Service\\\\DocGenerator\\\\ActivityContext\\:\\:\\$documentCategoryRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php + + - + message: "#^Parameter \\$context of method Chill\\\\ActivityBundle\\\\Timeline\\\\TimelineActivityProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php + + - + message: "#^Parameter \\$entity of method Chill\\\\ActivityBundle\\\\Timeline\\\\TimelineActivityProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php + + - + message: "#^Result of && is always false\\.$#" + count: 7 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\Embeddable\\\\CommentEmbeddable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\User will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and DateTime will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Doctrine\\\\Common\\\\Collections\\\\Collection will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and bool will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\AsideActivityBundle\\\\Entity\\\\AsideActivity\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php + + - + message: "#^Property Chill\\\\AsideActivityBundle\\\\Entity\\\\AsideActivityCategory\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php + + - + message: "#^Call to method DateTimeImmutable\\:\\:add\\(\\) on a separate line has no effect\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php + + - + message: "#^Call to method DateTimeImmutable\\:\\:setTimezone\\(\\) on a separate line has no effect\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php + + - + message: "#^Property Chill\\\\AsideActivityBundle\\\\Form\\\\AsideActivityFormType\\:\\:\\$storage is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php + + - + message: "#^Static call to instance method Chill\\\\BudgetBundle\\\\Calculator\\\\CalculatorInterface\\:\\:getAlias\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php + + - + message: "#^Call to an undefined method Chill\\\\BudgetBundle\\\\Entity\\\\AbstractElement\\:\\:getId\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Controller\\\\AbstractElementController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByEntityAndDate\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByHousehold\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByPerson\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByEntityAndDate\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByHousehold\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByPerson\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Controller/ElementController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\BudgetBundle\\\\Entity\\\\AbstractElement\\:\\:\\$startDate \\(DateTimeImmutable\\) does not accept null\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php + + - + message: "#^Strict comparison using \\=\\=\\= between 0 and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and DateTimeImmutable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php + + - + message: "#^Property Chill\\\\BudgetBundle\\\\Entity\\\\ChargeKind\\:\\:\\$tags is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php + + - + message: "#^Property Chill\\\\BudgetBundle\\\\Entity\\\\ResourceKind\\:\\:\\$tags is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ChargeKindRepository\\:\\:findAll\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ChargeType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ChargeKindRepository\\:\\:findAllActive\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ChargeType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ChargeKindRepository\\:\\:findAllByType\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ChargeType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ChargeKindRepository\\:\\:findBy\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ChargeType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^PHPDoc tag @param for parameter \\$limit with type mixed is not subtype of native type int\\|null\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^PHPDoc tag @param for parameter \\$offset with type mixed is not subtype of native type int\\|null\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ResourceKindRepository\\:\\:findAll\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ResourceType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ResourceKindRepository\\:\\:findAllActive\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ResourceType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ResourceKindRepository\\:\\:findAllByType\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ResourceType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^Method Chill\\\\BudgetBundle\\\\Repository\\\\ResourceKindRepository\\:\\:findBy\\(\\) has invalid return type Chill\\\\BudgetBundle\\\\Repository\\\\ResourceType\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^PHPDoc tag @param for parameter \\$limit with type mixed is not subtype of native type int\\|null\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^PHPDoc tag @param for parameter \\$offset with type mixed is not subtype of native type int\\|null\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php + + - + message: "#^Property Chill\\\\BudgetBundle\\\\Service\\\\Summary\\\\SummaryBudget\\:\\:\\$chargeLabels is unused\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php + + - + message: "#^Property Chill\\\\BudgetBundle\\\\Service\\\\Summary\\\\SummaryBudget\\:\\:\\$resourcesLabels is unused\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Command\\\\AzureGrantAdminConsentAndAcquireToken\\:\\:\\$clientRegistry is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Command/AzureGrantAdminConsentAndAcquireToken.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Command\\\\SendTestShortMessageOnCalendarCommand\\:\\:\\$phoneNumberHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php + + - + message: "#^Strict comparison using \\=\\=\\= between false and DateInterval will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php + + - + message: "#^Strict comparison using \\=\\=\\= between false and DateTimeImmutable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Form\\\\FormInterface\\:\\:isClicked\\(\\)\\.$#" + count: 4 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Serializer\\\\SerializerInterface\\:\\:normalize\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarController.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarController.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Controller\\\\CalendarDocController\\:\\:\\$docGeneratorTemplateRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Controller\\\\CalendarDocController\\:\\:\\$serializer is unused\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php + + - + message: "#^Method Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\:\\:remove\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarConnectAzureController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Entity/Calendar.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Entity\\\\CalendarRange\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Entity\\\\CancelReason\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Entity/CancelReason.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\CalendarMessage\\:\\:\\$oldInvites \\(array\\\\) does not accept array\\\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php + + - + message: "#^PHPDoc tag @return has invalid value \\(array\\\\)\\: Unexpected token \"\\:\", expected '\\>' at offset 408$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php + + - + message: "#^Method Chill\\\\CalendarBundle\\\\RemoteCalendar\\\\Connector\\\\MSGraph\\\\OnBehalfOfUserTokenStorage\\:\\:getToken\\(\\) should return TheNetworg\\\\OAuth2\\\\Client\\\\Token\\\\AccessToken but returns League\\\\OAuth2\\\\Client\\\\Token\\\\AccessTokenInterface\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php + + - + message: "#^Call to method DateTimeImmutable\\:\\:setTimezone\\(\\) on a separate line has no effect\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php + + - + message: "#^PHPDoc tag @return has invalid value \\(array\\{\\?id\\: string, \\?lastModifiedDateTime\\: int, \\?changeKey\\: string\\}\\)\\: Unexpected token \"\\:\", expected '\\}' at offset 129$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Security\\\\Voter\\\\CalendarVoter\\:\\:\\$authorizationHelper is unused\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php + + - + message: "#^Property Chill\\\\CalendarBundle\\\\Security\\\\Voter\\\\CalendarVoter\\:\\:\\$centerResolverManager is unused\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Console\\\\Helper\\\\HelperInterface\\:\\:ask\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php + + - + message: "#^If condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Controller\\\\CustomFieldController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Controller\\\\CustomFieldController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string\\)\\: Unexpected token \"\\\\n \\* \", expected variable at offset 130$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Ternary operator condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQuery\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findOneByEntity\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findOneById\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Form\\\\FormInterface\\:\\:isClicked\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Controller\\\\CustomFieldsGroupController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Controller\\\\CustomFieldsGroupController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Controller\\\\CustomFieldsGroupController\\:\\:createMakeDefaultForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php + + - + message: "#^Call to an undefined method Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\:\\:getFallbackLocales\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Method Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\:\\:create\\(\\) invoked with 4 parameters, 1\\-3 required\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldChoice\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and array\\|string will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 3 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:render\\(\\) should return string but returns null\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldDate\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php + + - + message: "#^PHPDoc tag @param for parameter \\$builder with type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface is not subtype of native type Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 2 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^PHPDoc tag @param for parameter \\$customField with type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField is not subtype of native type Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\.$#" + count: 4 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldInterface\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php + + - + message: "#^Anonymous function never returns null so it can be removed from the return type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldLongChoice\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldLongChoice\\\\Option will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Ternary operator condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldNumber\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldText\\:\\:\\$requestStack is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:buildOptionsForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\FormTypeInterface\\|null but returns Symfony\\\\Component\\\\Form\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$builder of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:buildOptionsForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\FormBuilderInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:buildForm\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:deserialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:render\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Parameter \\$customField of method Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:serialize\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\CustomField\\\\CustomField\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\CustomFields\\\\CustomFieldTitle\\:\\:\\$requestStack is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\:\\:getName\\(\\) should return array but returns string\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldLongChoice\\\\Option\\:\\:\\$children is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldLongChoice\\\\Option\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsDefaultGroup\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsDefaultGroup.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\:\\:getActiveCustomFields\\(\\) should return Doctrine\\\\Common\\\\Collections\\\\Collection but returns array\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\:\\:getName\\(\\) should return array but returns string\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php + + - + message: "#^Call to method buildOptionsForm\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/CustomFieldType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\CustomFieldsBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/CustomFieldType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\CustomFieldsBundle\\\\Form\\\\CustomFieldType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/CustomFieldType.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Form\\\\CustomFieldsGroupType\\:\\:\\$translator \\(Symfony\\\\Component\\\\Translation\\\\TranslatorInterface\\) does not accept Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/CustomFieldsGroupType.php + + - + message: "#^Instanceof between Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup and Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Instanceof between string and Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomFieldsGroup will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Form\\\\DataTransformer\\\\CustomFieldsGroupToIdTransformer\\:\\:transform\\(\\) should return string but returns int\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/CustomFieldsGroupToIdTransformer.php + + - + message: "#^Call to an undefined method Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\:\\:getLabel\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/JsonCustomFieldToArrayTransformer.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findOneById\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/DataTransformer/JsonCustomFieldToArrayTransformer.php + + - + message: "#^Call to method getCustomFieldByType\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldCompiler\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/Type/CustomFieldType.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldType\\:\\:\\$customFieldCompiler \\(Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldCompiler\\) does not accept Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/Type/CustomFieldType.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldType\\:\\:\\$customFieldCompiler has unknown class Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldCompiler as its type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/Type/CustomFieldType.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Form\\\\Type\\\\CustomFieldType\\:\\:\\$om is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/Type/CustomFieldType.php + + - + message: "#^Invalid array key type Chill\\\\CustomFieldsBundle\\\\Service\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:getCustomFieldByType\\(\\) has invalid return type Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Parameter \\$serviceName of method Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:addCustomField\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\Service\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Parameter \\$type of method Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:addCustomField\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\Service\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:\\$container \\(Chill\\\\CustomFieldsBundle\\\\Service\\\\Container\\) does not accept Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:\\$container has unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\Container as its type\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldProvider\\:\\:\\$container is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldProvider.php + + - + message: "#^Call to method deserialize\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldsHelper.php + + - + message: "#^Call to method isEmptyValue\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldsHelper.php + + - + message: "#^Call to method render\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldsHelper.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldsHelper\\:\\:renderCustomField\\(\\) has invalid return type Chill\\\\CustomFieldsBundle\\\\Service\\\\The\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldsHelper.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldsHelper\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Service/CustomFieldsHelper.php + + - + message: "#^Method Chill\\\\CustomFieldsBundle\\\\Templating\\\\Twig\\\\CustomFieldRenderingTwig\\:\\:renderWidget\\(\\) should return string but returns Chill\\\\CustomFieldsBundle\\\\Service\\\\The\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Templating/Twig/CustomFieldRenderingTwig.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Templating\\\\Twig\\\\CustomFieldRenderingTwig\\:\\:\\$container \\(Symfony\\\\Component\\\\DependencyInjection\\\\Container\\) does not accept Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Templating/Twig/CustomFieldRenderingTwig.php + + - + message: "#^Parameter \\$customFielsGroup of method Chill\\\\CustomFieldsBundle\\\\Templating\\\\Twig\\\\CustomFieldsGroupRenderingTwig\\:\\:renderWidget\\(\\) has invalid type Chill\\\\CustomFieldsBundle\\\\Templating\\\\Twig\\\\CustomFieldsGroud\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Templating/Twig/CustomFieldsGroupRenderingTwig.php + + - + message: "#^Property Chill\\\\CustomFieldsBundle\\\\Templating\\\\Twig\\\\CustomFieldsGroupRenderingTwig\\:\\:\\$container \\(Symfony\\\\Component\\\\DependencyInjection\\\\Container\\) does not accept Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Templating/Twig/CustomFieldsGroupRenderingTwig.php + + - + message: "#^Left side of && is always true\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php + + - + message: "#^PHPDoc tag @return with type void is incompatible with native type Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and int will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php + + - + message: "#^Binary operation \"\\.\" between 'Adding doc…' and array\\{filename\\: 'pKNlhCrQDCRsAuC8vYH…', key\\: '\\{\"alg\"\\:\"A256CBC\",…', iv\\: '\\[86,231,83,148,117…', type\\: 'application/vnd…'\\} results in an error\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/DataFixtures/ORM/LoadDocGeneratorTemplate.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\DocGeneratorBundle\\\\Entity\\\\DocGeneratorTemplate\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Doctrine\\\\Common\\\\Collections\\\\Collection will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/CollectionDocGenNormalizer.php + + - + message: "#^Call to an undefined method ReflectionType\\:\\:getName\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQuery\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Controller/DocumentCategoryController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 4 + path: src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\Person will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Entity/Document.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:\\$user has unknown class Chill\\\\PersonBundle\\\\Entity\\\\user as its type\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Entity/Document.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findByFilename\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Object/ObjectToAsyncFileTransformer.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Repository\\\\AccompanyingCourseDocumentRepository\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Repository/AccompanyingCourseDocumentRepository.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Repository\\\\DocumentCategoryRepository\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Repository/DocumentCategoryRepository.php + + - + message: "#^Instanceof between Chill\\\\DocStoreBundle\\\\Entity\\\\PersonDocument and Chill\\\\DocStoreBundle\\\\Entity\\\\PersonDocument will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php + + - + message: "#^Default value of the parameter \\#5 \\$options \\(array\\{\\}\\) of method Chill\\\\DocStoreBundle\\\\Templating\\\\WopiEditTwigExtensionRuntime\\:\\:renderButtonGroup\\(\\) is incompatible with type array\\{small\\: bool\\}\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php + + - + message: "#^Property Chill\\\\DocStoreBundle\\\\Templating\\\\WopiEditTwigExtensionRuntime\\:\\:\\$discovery is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:countByPerson\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findByPersonInCircle\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Cannot call method getUsernameCanonical\\(\\) on int\\\\|int\\<1, max\\>\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\EventTypeController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventTypeController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\EventTypeController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventTypeController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\EventTypeController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventTypeController.php + + - + message: "#^Call to an undefined method Traversable\\:\\:count\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Call to an undefined method Traversable\\:\\:current\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\ParticipationController\\:\\:handleRequest\\(\\) has invalid return type Chill\\\\EventBundle\\\\Controller\\\\Participations\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and int will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and int\\|string will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\EventBundle\\\\Entity\\\\Event will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\EventBundle\\\\Entity\\\\Participation will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\RoleController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/RoleController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\RoleController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/RoleController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\RoleController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/RoleController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\StatusController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/StatusController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\StatusController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/StatusController.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Controller\\\\StatusController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/StatusController.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/DependencyInjection/Configuration.php + + - + message: "#^Call to an undefined method Chill\\\\EventBundle\\\\Entity\\\\Participation\\:\\:getIterator\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Call to an undefined method Chill\\\\EventBundle\\\\Entity\\\\Participation\\:\\:removeElement\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Entity\\\\Event\\:\\:getModerator\\(\\) should return int but returns Chill\\\\MainBundle\\\\Entity\\\\User\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Event\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Event\\:\\:\\$moderator \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept int\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Event\\:\\:\\$participations \\(Chill\\\\EventBundle\\\\Entity\\\\Participation\\) does not accept Doctrine\\\\Common\\\\Collections\\\\ArrayCollection\\<\\*NEVER\\*, \\*NEVER\\*\\>\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Event.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\EventType\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/EventType.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Participation\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Participation.php + + - + message: "#^Result of \\|\\| is always false\\.$#" + count: 2 + path: src/Bundle/ChillEventBundle/Entity/Participation.php + + - + message: "#^Strict comparison using \\=\\=\\= between Chill\\\\EventBundle\\\\Entity\\\\Event and null will always evaluate to false\\.$#" + count: 3 + path: src/Bundle/ChillEventBundle/Entity/Participation.php + + - + message: "#^Strict comparison using \\=\\=\\= between Chill\\\\EventBundle\\\\Entity\\\\Role and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Participation.php + + - + message: "#^Strict comparison using \\=\\=\\= between Chill\\\\EventBundle\\\\Entity\\\\Status and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Participation.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Role\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Role.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Entity\\\\Status\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Entity/Status.php + + - + message: "#^Call to method setDefaults\\(\\) on an unknown class Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/EventTypeType.php + + - + message: "#^Call to method setDefaults\\(\\) on an unknown class Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/RoleType.php + + - + message: "#^Call to method setDefaults\\(\\) on an unknown class Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/StatusType.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Form\\\\Type\\\\PickEventType\\:\\:\\$user \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/Type/PickEventType.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Form\\\\ResolvedFormTypeInterface\\:\\:getName\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Form\\\\ResolvedFormTypeInterface\\:\\:getName\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php + + - + message: "#^Method Chill\\\\EventBundle\\\\Search\\\\EventSearch\\:\\:renderResult\\(\\) should return string but returns array\\\\|bool\\>\\>\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Search/EventSearch.php + + - + message: "#^Property Chill\\\\EventBundle\\\\Search\\\\EventSearch\\:\\:\\$user \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Search/EventSearch.php + + - + message: "#^Instanceof between Chill\\\\EventBundle\\\\Entity\\\\Event and Chill\\\\EventBundle\\\\Entity\\\\Event will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php + + - + message: "#^Instanceof between Chill\\\\EventBundle\\\\Entity\\\\Participation and Chill\\\\EventBundle\\\\Entity\\\\Participation will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php + + - + message: "#^Parameter \\#2 \\$context \\(string\\) of method Chill\\\\EventBundle\\\\Timeline\\\\TimelineEventProvider\\:\\:getEntityTemplate\\(\\) should be compatible with parameter \\$context \\(Chill\\\\MainBundle\\\\Timeline\\\\type\\) of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineProviderInterface\\:\\:getEntityTemplate\\(\\)$#" + count: 1 + path: src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php + + - + message: "#^Instanceof between DateTimeImmutable and DateTime will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Instanceof between DateTimeImmutable and DateTimeImmutable will always evaluate to true\\.$#" + count: 2 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:getBirthdate\\(\\) has invalid return type Chill\\\\FamilyMembersBundle\\\\Entity\\\\date_immutable\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setBirthdate\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setEndDate\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setFirstname\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setGender\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setLastname\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setLink\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setProfessionnalSituation\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Method Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:setStartDate\\(\\) should return Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember but returns \\$this\\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\)\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Property Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:\\$birthdate \\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\date_immutable\\|null\\) does not accept DateTimeImmutable\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Property Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:\\$birthdate \\(Chill\\\\FamilyMembersBundle\\\\Entity\\\\date_immutable\\|null\\) does not accept DateTimeImmutable\\|null\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Property Chill\\\\FamilyMembersBundle\\\\Entity\\\\AbstractFamilyMember\\:\\:\\$birthdate has unknown class Chill\\\\FamilyMembersBundle\\\\Entity\\\\date_immutable as its type\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Result of \\|\\| is always true\\.$#" + count: 3 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and DateTimeImmutable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and null will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/AbstractFamilyMember.php + + - + message: "#^Property Chill\\\\FamilyMembersBundle\\\\Entity\\\\FamilyMember\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillFamilyMembersBundle/Entity/FamilyMember.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQueryBuilder\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php + + - + message: "#^Call to method select\\(\\) on an unknown class Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php + + - + message: "#^Call to method setFirstResult\\(\\) on an unknown class Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:buildQueryEntities\\(\\) has invalid return type Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php + + - + message: "#^PHPDoc tag @throws with type Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AccessDeniedHttpException is not subtype of Throwable$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php + + - + message: "#^PHPDoc tag @param for parameter \\$postedDataContext with type string is incompatible with native type array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^PHPDoc tag @param has invalid value \\(mixed id\\)\\: Unexpected token \"id\", expected variable at offset 956$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string action\\)\\: Unexpected token \"action\", expected variable at offset 929$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^PHPDoc tag @return with type void is incompatible with native type Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and object will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQueryBuilder\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Call to method getQuery\\(\\) on an unknown class Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Instanceof between Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse and Symfony\\\\Component\\\\HttpFoundation\\\\Response will always evaluate to true\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:index\\(\\) has invalid return type Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:queryEntities\\(\\) has invalid return type Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^PHPDoc tag @throws with type Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AccessDeniedHttpException is not subtype of Throwable$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Parameter \\$formClass of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:formCreateAction\\(\\) has invalid type Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Constant Chill\\\\MainBundle\\\\CRUD\\\\Routing\\\\CRUDRoutesLoader\\:\\:ALL_INDEX_METHODS is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php + + - + message: "#^Constant Chill\\\\MainBundle\\\\CRUD\\\\Routing\\\\CRUDRoutesLoader\\:\\:ALL_SINGLE_METHODS is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php + + - + message: "#^Strict comparison using \\=\\=\\= between 'CRUD' and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php + + - + message: "#^Strict comparison using \\=\\=\\= between 'collection' and 'single'\\|null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findOneByName\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/ChillImportUsersCommand.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Command\\\\ChillImportUsersCommand\\:\\:getCenters\\(\\) should return array\\ but returns null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/ChillImportUsersCommand.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Command\\\\ChillUserSendRenewPasswordCodeCommand\\:\\:\\$output is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/ChillUserSendRenewPasswordCodeCommand.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Console\\\\Helper\\\\HelperInterface\\:\\:askHiddenResponse\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/SetPasswordCommand.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\CenterController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/CenterController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\CenterController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/CenterController.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Export\\\\DirectExportInterface and Chill\\\\MainBundle\\\\Export\\\\DirectExportInterface will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^PHPDoc tag @param for parameter \\$request with type string is incompatible with native type Symfony\\\\Component\\\\HttpFoundation\\\\Request\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQueryBuilder\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findOneByUsernameCanonical\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PasswordController\\:\\:passwordForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 4 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:addLinkRoleScopeAction\\(\\) has invalid return type Chill\\\\MainBundle\\\\Controller\\\\Respon\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:addLinkRoleScopeAction\\(\\) should return Chill\\\\MainBundle\\\\Controller\\\\Respon but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:addLinkRoleScopeAction\\(\\) should return Chill\\\\MainBundle\\\\Controller\\\\Respon but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:createAddRoleScopeForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:createDeleteRoleScopeForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:deleteLinkRoleScopeAction\\(\\) has invalid return type Chill\\\\MainBundle\\\\Controller\\\\redirection\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\PermissionsGroupController\\:\\:deleteLinkRoleScopeAction\\(\\) should return Chill\\\\MainBundle\\\\Controller\\\\redirection but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^PHPDoc tag @param for parameter \\$permissionsGroup with type mixed is not subtype of native type Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^PHPDoc tag @throws with type Chill\\\\MainBundle\\\\Controller\\\\type is not subtype of Throwable$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQuery\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/PostalCodeController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\:\\:getFlashBag\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/SavedExportController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\ScopeController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ScopeController.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Controller\\\\ScopeController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ScopeController.php + + - + message: "#^Call to method buildForm\\(\\) on an unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Call to method convertFormDataToQuery\\(\\) on an unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Call to method convertTermsToFormData\\(\\) on an unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Call to method getAdvancedSearchTitle\\(\\) on an unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^PHPDoc tag @var for variable \\$variable contains unknown class Chill\\\\MainBundle\\\\Controller\\\\Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchFormInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^PHPDoc tag @var for variable \\$variable contains unknown class Chill\\\\MainBundle\\\\Controller\\\\Chill\\\\MainBundle\\\\Search\\\\SearchProvider\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Variable \\$variable in PHPDoc tag @var does not match assigned variable \\$search\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Variable \\$variable in PHPDoc tag @var does not match assigned variable \\$searchProvider\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/SearchController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\:\\:getGroupCenters\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/TimelineCenterController.php + + - + message: "#^Instanceof between Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse and Symfony\\\\Component\\\\HttpFoundation\\\\Response will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/UserController.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/UserController.php + + - + message: "#^PHPDoc tag @return has invalid value \\(array\\<0\\: CronJobInterface\\[\\], 1\\: array\\\\>\\)\\: Unexpected token \"\\:\", expected '\\>' at offset 26$#" + count: 1 + path: src/Bundle/ChillMainBundle/Cron/CronManager.php + + - + message: "#^Property Chill\\\\MainBundle\\\\DataFixtures\\\\ORM\\\\LoadAddressReferences\\:\\:\\$container is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadAddressReferences.php + + - + message: "#^Property Chill\\\\MainBundle\\\\DataFixtures\\\\ORM\\\\LoadLocationType\\:\\:\\$container is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLocationType.php + + - + message: "#^Property Chill\\\\MainBundle\\\\DataFixtures\\\\ORM\\\\LoadUsers\\:\\:\\$container is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadUsers.php + + - + message: "#^Parameter \\$factory of method Chill\\\\MainBundle\\\\DependencyInjection\\\\ChillMainExtension\\:\\:addWidgetFactory\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\WidgetFactoryInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php + + - + message: "#^Method Symfony\\\\Component\\\\DependencyInjection\\\\Container\\:\\:getParameter\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php + + - + message: "#^Offset 'queries' does not exist on array\\{scheme\\: 'ovh', host\\?\\: string, port\\?\\: int\\<0, 65535\\>, user\\?\\: string, pass\\?\\: string, path\\?\\: string, query\\?\\: string, fragment\\?\\: string\\}\\.$#" + count: 5 + path: src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php + + - + message: "#^Offset 'queries' does not exist on array\\{scheme\\?\\: string, host\\?\\: string, port\\?\\: int\\<0, 65535\\>, user\\?\\: string, pass\\?\\: string, path\\?\\: string, query\\?\\: string, fragment\\?\\: string\\}\\|false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:canBeUnset\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:getWidgetAliasesbyPlace\\(\\) has invalid return type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:getWidgetAliasesbyPlace\\(\\) should return Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:getWidgetFactories\\(\\) has invalid return type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\WidgetFactoryInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^PHPDoc tag @param has invalid value \\(WidgetFactoryInterface\\[\\]\\)\\: Unexpected token \"\\\\n \", expected variable at offset 42$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Parameter \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:getWidgetAliasesbyPlace\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Parameter \\$widgetFactories of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:setWidgetFactories\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\WidgetFactoryInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Call to an undefined method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:getAllowedPlaces\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\HasWidgetFactoriesExtensionInterface and Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\HasWidgetFactoriesExtensionInterface will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\AbstractWidgetsCompilerPass\\:\\:isPlaceAllowedForWidget\\(\\) has invalid return type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\unknown\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\AbstractWidgetsCompilerPass\\:\\:isPlaceAllowedForWidget\\(\\) should return Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\unknown but returns false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\AbstractWidgetsCompilerPass\\:\\:isPlaceAllowedForWidget\\(\\) should return Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\unknown but returns true\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Parameter \\$order of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\AbstractWidgetFactory\\:\\:createDefinition\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/AbstractWidgetFactory.php + + - + message: "#^Parameter \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\AbstractWidgetFactory\\:\\:createDefinition\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/AbstractWidgetFactory.php + + - + message: "#^Parameter \\$order of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:createDefinition\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/WidgetFactoryInterface.php + + - + message: "#^Parameter \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/WidgetFactoryInterface.php + + - + message: "#^Parameter \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:createDefinition\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/WidgetFactoryInterface.php + + - + message: "#^PHPDoc tag @param for parameter \\$factory with type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\WidgetFactoryInterface is not subtype of native type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/HasWidgetFactoriesExtensionInterface.php + + - + message: "#^Parameter \\$factory of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\HasWidgetFactoriesExtensionInterface\\:\\:addWidgetFactory\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\WidgetFactoryInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/HasWidgetFactoriesExtensionInterface.php + + - + message: "#^Strict comparison using \\=\\=\\= between int\\<1, max\\> and 0 will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Doctrine/Type/NativeDateIntervalType.php + + - + message: "#^Instanceof between DateTime and DateTime will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Address.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\Address\\:\\:\\$validTo \\(DateTime\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Address.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Entity/Address.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\AddressReference\\:\\:setPostcode\\(\\) should return Chill\\\\MainBundle\\\\Entity\\\\Address but returns \\$this\\(Chill\\\\MainBundle\\\\Entity\\\\AddressReference\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/AddressReference.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\AddressReference\\:\\:\\$addressCanonical is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/AddressReference.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\AddressReference\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/AddressReference.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\Country\\:\\:getCountryCode\\(\\) has invalid return type Chill\\\\MainBundle\\\\Entity\\\\the\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Country.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\Country\\:\\:getCountryCode\\(\\) should return Chill\\\\MainBundle\\\\Entity\\\\the but returns string\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Country.php + + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\GeographicalUnit\\:\\:\\$geom is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\GeographicalUnit\\:\\:\\$unitRefId is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\GroupCenter\\:\\:getPermissionsGroup\\(\\) has invalid return type Chill\\\\MainBundle\\\\Entity\\\\PermissionGroup\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GroupCenter.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\GroupCenter\\:\\:getPermissionsGroup\\(\\) should return Chill\\\\MainBundle\\\\Entity\\\\PermissionGroup but returns Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GroupCenter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\GroupCenter\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GroupCenter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\GroupCenter\\:\\:\\$permissionsGroup \\(Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\) does not accept Doctrine\\\\Common\\\\Collections\\\\ArrayCollection\\<\\*NEVER\\*, \\*NEVER\\*\\>\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/GroupCenter.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Entity\\\\Language\\:\\:getName\\(\\) should return string but returns array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Language.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string array \\$name\\)\\: Unexpected token \"array\", expected variable at offset 49$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Language.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Entity\\\\Language\\:\\:\\$name with type string is incompatible with native type array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Language.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\Location\\:\\:\\$createdAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Location.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\Location\\:\\:\\$updatedAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Location.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\Notification\\:\\:\\$updatedAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Notification.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\NotificationComment\\:\\:\\$createdAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/NotificationComment.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\NotificationComment\\:\\:\\$updateAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/NotificationComment.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\:\\:\\$groupCenters is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\PermissionsGroup\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\PostalCode\\:\\:\\$canonical is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/PostalCode.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\PostalCode\\:\\:\\$deletedAt is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/PostalCode.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\PostalCode\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/PostalCode.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Entity\\\\Regroupment\\:\\:\\$centers with type Chill\\\\MainBundle\\\\Entity\\\\Center is not subtype of native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Regroupment.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Entity\\\\RoleScope\\:\\:\\$permissionsGroups is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/RoleScope.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and array will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/User.php + + - + message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), mixed\\>\\:\\:current\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php + + - + message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), mixed\\>\\:\\:next\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php + + - + message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), mixed\\>\\:\\:rewind\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php + + - + message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), mixed\\>\\:\\:valid\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php + + - + message: "#^Access to offset \\(int\\|string\\) on an unknown class Chill\\\\MainBundle\\\\Export\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Export\\\\ExportElementInterface\\:\\:requiredRole\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Call to function is_iterable\\(\\) with array will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Empty array passed to foreach\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Instanceof between Doctrine\\\\ORM\\\\QueryBuilder and Doctrine\\\\ORM\\\\QueryBuilder will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Iterating over an object of an unknown class Chill\\\\MainBundle\\\\Export\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^PHPDoc tag @param for parameter \\$aliases with type Generator is incompatible with native type array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Parameter \\$data of method Chill\\\\MainBundle\\\\Export\\\\ExportManager\\:\\:handleAggregators\\(\\) has invalid type Chill\\\\MainBundle\\\\Export\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Parameter \\$data of method Chill\\\\MainBundle\\\\Export\\\\ExportManager\\:\\:retrieveUsedFilters\\(\\) has invalid type Chill\\\\MainBundle\\\\Export\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Export\\\\type will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Yield can be used only with these return types\\: Generator, Iterator, Traversable, iterable\\.$#" + count: 5 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and array\\|string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php + + - + message: "#^Variable \\$data in PHPDoc tag @var does not match assigned variable \\$contentData\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php + + - + message: "#^Parameter \\#2 \\$exportAlias \\(Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\) of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\CSVListFormatter\\:\\:buildForm\\(\\) should be compatible with parameter \\$exportAlias \\(string\\) of method Chill\\\\MainBundle\\\\Export\\\\FormatterInterface\\:\\:buildForm\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php + + - + message: "#^Parameter \\$exportAlias of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\CSVListFormatter\\:\\:buildForm\\(\\) has invalid type Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php + + - + message: "#^Parameter \\#2 \\$exportAlias \\(Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\) of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\CSVPivotedListFormatter\\:\\:buildForm\\(\\) should be compatible with parameter \\$exportAlias \\(string\\) of method Chill\\\\MainBundle\\\\Export\\\\FormatterInterface\\:\\:buildForm\\(\\)$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php + + - + message: "#^Parameter \\$exportAlias of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\CSVPivotedListFormatter\\:\\:buildForm\\(\\) has invalid type Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php + + - + message: "#^Access to offset 'format' on an unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Access to offset mixed on an unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Iterating over an object of an unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$aggregatorsData \\(Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\) does not accept array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$aggregatorsData has unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type as its type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$formatterData \\(Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\) does not accept array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$formatterData has unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type as its type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$result \\(Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type\\) does not accept array\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:\\$result has unknown class Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type as its type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Instanceof between string and DateTimeInterface will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php + + - + message: "#^PHPDoc tag @param has invalid value \\(Array\\(String\\) \\$aggregatorAliases Array of the aliases of the aggregators\\. An aggregator do the \"group by\" on the data\\. \\$aggregatorAliases\\)\\: Unexpected token \"\\(\", expected variable at offset 343$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/FormatterInterface.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Export\\\\Helper\\\\ExportAddressHelper\\:\\:\\$unitNamesKeysCache contains unresolvable type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Export\\\\Helper\\\\ExportAddressHelper\\:\\:\\$unitNamesKeysCache with type mixed is not subtype of native type array\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Helper/ExportAddressHelper.php + + - + message: "#^Call to method createSearchForm\\(\\) on an unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/AdvancedSearchType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/CenterType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\MainBundle\\\\Form\\\\CenterType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/CenterType.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Address and Chill\\\\MainBundle\\\\Entity\\\\Address will always evaluate to true\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\Address will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php + + - + message: "#^Else branch is unreachable because previous condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/ScopePickerDataMapper.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Scope and Chill\\\\MainBundle\\\\Entity\\\\Scope will always evaluate to true\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/DataMapper/ScopePickerDataMapper.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/ScopePickerDataMapper.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/LocationFormType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\MainBundle\\\\Form\\\\LocationFormType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/LocationFormType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\MainBundle\\\\Form\\\\PermissionsGroupType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/ScopeType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\MainBundle\\\\Form\\\\ScopeType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/ScopeType.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Form\\\\Type\\\\ChillPhoneNumberType\\:\\:\\$phoneNumberUtil is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/ChillPhoneNumberType.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\:\\:getId\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/CommentType.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and array\\\\|Chill\\\\MainBundle\\\\Entity\\\\User will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\MultipleObjectsToIdTransformer\\:\\:transform\\(\\) should return Doctrine\\\\Common\\\\Collections\\\\ArrayCollection but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/ObjectToIdTransformer.php + + - + message: "#^Call to function is_int\\(\\) with int will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/DataTransformer/PostalCodeToIdTransformer.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Export\\\\ExportInterface and Chill\\\\MainBundle\\\\Export\\\\ExportInterface will always evaluate to true\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/Type/Export/ExportType.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Form\\\\Type\\\\Select2CountryType\\:\\:\\$requestStack is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\:\\:replaceDefaults\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2EntityType.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Form\\\\Type\\\\Select2LanguageType\\:\\:\\$requestStack is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/UserType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\MainBundle\\\\Form\\\\UserType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/UserType.php + + - + message: "#^Method Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\:\\:setDefined\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/WorkflowStepType.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Notification\\\\Email\\\\NotificationMailer\\:\\:\\$translator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Notification\\\\NotificationHandlerManager\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Notification/NotificationHandlerManager.php + + - + message: "#^Strict comparison using \\=\\=\\= between 0 and float will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Pagination/Paginator.php + + - + message: "#^PHPDoc tag @param for parameter \\$phoneNumber with type string is incompatible with native type libphonenumber\\\\PhoneNumber\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Phonenumber/Templating.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Repository\\\\GeographicalUnitRepository\\:\\:findBy\\(\\) should return Chill\\\\MainBundle\\\\Entity\\\\GeographicalUnit\\|null but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Repository\\\\GeographicalUnitRepository\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php + + - + message: "#^Return type \\(Chill\\\\MainBundle\\\\Entity\\\\GeographicalUnit\\|null\\) of method Chill\\\\MainBundle\\\\Repository\\\\GeographicalUnitRepository\\:\\:findBy\\(\\) should be compatible with return type \\(array\\\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findBy\\(\\)$#" + count: 2 + path: src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php + + - + message: "#^The @implements tag of class Chill\\\\MainBundle\\\\Repository\\\\SavedExportRepository describes Doctrine\\\\Persistence\\\\ObjectRepository but the class implements\\: Chill\\\\MainBundle\\\\Repository\\\\SavedExportRepositoryInterface$#" + count: 1 + path: src/Bundle/ChillMainBundle/Repository/SavedExportRepository.php + + - + message: "#^Interface Chill\\\\MainBundle\\\\Repository\\\\SavedExportRepositoryInterface has @implements tag, but can not implement any interface, must extend from it\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Repository/SavedExportRepositoryInterface.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and array\\\\|Chill\\\\MainBundle\\\\Entity\\\\Center will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Repository/UserACLAwareRepository.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Routing\\\\MenuComposer\\:\\:\\$routeCollection is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Routing/MenuComposer.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Routing\\\\MenuTwig\\:\\:\\$container is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Routing/MenuTwig.php + + - + message: "#^Parameter \\$string of method Chill\\\\MainBundle\\\\Search\\\\AbstractSearch\\:\\:parseDate\\(\\) has invalid type Chill\\\\MainBundle\\\\Search\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/AbstractSearch.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Search\\\\SearchApi\\:\\:getResults\\(\\) has invalid return type Chill\\\\MainBundle\\\\Search\\\\Model\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApi.php + + - + message: "#^PHPDoc tag @return with type Chill\\\\MainBundle\\\\Search\\\\Model is not subtype of native type Chill\\\\MainBundle\\\\Serializer\\\\Model\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApi.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Search\\\\SearchApiNoQueryException\\:\\:\\$parameters is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApiNoQueryException.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Search\\\\SearchApiNoQueryException\\:\\:\\$pattern is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApiNoQueryException.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Search\\\\SearchApiNoQueryException\\:\\:\\$types is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApiNoQueryException.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Search\\\\SearchApiResult\\:\\:\\$pertinence is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApiResult.php + + - + message: "#^Else branch is unreachable because previous condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^If condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Search\\\\SearchProvider\\:\\:getHasAdvancedFormByName\\(\\) has invalid return type Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Parameter \\$subject of method Chill\\\\MainBundle\\\\Search\\\\SearchProvider\\:\\:extractDomain\\(\\) has invalid type Chill\\\\MainBundle\\\\Search\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Search\\\\SearchProvider\\:\\:\\$hasAdvancedFormSearchServices has unknown class Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm as its type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and string will always evaluate to true\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\:\\:getGroupCenters\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Empty array passed to foreach\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Center\\|string and Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Instanceof between string and Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\Scope\\|iterable\\ will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and null will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\DefaultVoterHelper\\:\\:\\$centerResolverDispatcher is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/DefaultVoterHelper.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Workflow\\\\EntityWorkflowHandlerInterface\\:\\:getDeletionRoles\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/WorkflowEntityDeletionVoter.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\User and Chill\\\\MainBundle\\\\Entity\\\\User will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/PasswordRecover/PasswordRecoverEvent.php + + - + message: "#^Parameter \\$ip of method Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent\\:\\:__construct\\(\\) has invalid type Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/PasswordRecover/PasswordRecoverEvent.php + + - + message: "#^Parameter \\$token of method Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent\\:\\:__construct\\(\\) has invalid type Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/PasswordRecover/PasswordRecoverEvent.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent\\:\\:\\$ip \\(string\\) does not accept Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/PasswordRecover/PasswordRecoverEvent.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent\\:\\:\\$token \\(string\\) does not accept Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\|null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/PasswordRecover/PasswordRecoverEvent.php + + - + message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/CenterResolverManager.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and array\\\\|Chill\\\\MainBundle\\\\Entity\\\\Center will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/CenterResolverManager.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/CenterResolverManager.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\HasCenterInterface and Chill\\\\MainBundle\\\\Entity\\\\HasCenterInterface will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultCenterResolver.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultCenterResolver.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\HasScopesInterface and Chill\\\\MainBundle\\\\Entity\\\\HasScopesInterface will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultScopeResolver.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/DefaultScopeResolver.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\ResolverTwigExtension\\:\\:resolveCenter\\(\\) has invalid return type Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\Center\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Security/Resolver/ResolverTwigExtension.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\ResolverTwigExtension\\:\\:resolveCenter\\(\\) should return array\\\\|Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\Center\\|null but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/ResolverTwigExtension.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\ScopeResolverDispatcher\\:\\:resolveScope\\(\\) invoked with 0 parameters, 1\\-2 required\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/ResolverTwigExtension.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\ScopeResolverDispatcher\\:\\:resolveScope\\(\\) should return Chill\\\\MainBundle\\\\Entity\\\\Scope\\|iterable\\ but returns null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Resolver/ScopeResolverDispatcher.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Security\\\\RoleProvider\\:\\:getRoleTitle\\(\\) should return string but returns null\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/RoleProvider.php + + - + message: "#^Strict comparison using \\!\\=\\= between array\\ and null will always evaluate to true\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/Security/RoleProvider.php + + - + message: "#^Constant Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\AddressNormalizer\\:\\:NULL_POSTCODE_COUNTRY is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Constant Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\AddressNormalizer\\:\\:NULL_VALUE is unused\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Address and Chill\\\\MainBundle\\\\Entity\\\\Address will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/AddressNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\Embeddable\\\\CommentEmbeddable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/CommentEmbeddableDocGenNormalizer.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\DateNormalizer\\:\\:normalize\\(\\) should return array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|null but return statement is missing\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and DateTimeInterface will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DateNormalizer.php + + - + message: "#^Instanceof between Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata\\ and Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DoctrineExistingEntityNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between false and true will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/DoctrineExistingEntityNormalizer.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Serializer\\\\Normalizer\\\\NotificationNormalizer\\:\\:\\$notificationHandlerManager is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/NotificationNormalizer.php + + - + message: "#^Result of && is always false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\User will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/UserNormalizer.php + + - + message: "#^Call to function is_int\\(\\) with int will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Mime\\\\RawMessage\\:\\:getSubject\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Service/Mailer/ChillMailer.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Mime\\\\RawMessage\\:\\:getTo\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Service/Mailer/ChillMailer.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Templating\\\\CSVCellTwig\\:\\:getName\\(\\) has invalid return type Chill\\\\MainBundle\\\\Templating\\\\The\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/CSVCellTwig.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Templating\\\\CSVCellTwig\\:\\:getName\\(\\) should return Chill\\\\MainBundle\\\\Templating\\\\The but returns string\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/CSVCellTwig.php + + - + message: "#^Instanceof between string and DateTimeInterface will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/ChillTwigHelper.php + + - + message: "#^PHPDoc tag @return has invalid value \\(array\\<'to'\\: DateTimeImmutable, 'from'\\: DateTimeImmutable\\>\\)\\: Unexpected token \"\\:\", expected '\\>' at offset 29$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php + + - + message: "#^Call to an undefined method Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\:\\:getFallbackLocales\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/TranslatableStringHelper.php + + - + message: "#^Strict comparison using \\=\\=\\= between array\\{\\} and non\\-empty\\-array\\ will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/TranslatableStringHelper.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringTwig\\:\\:getName\\(\\) has invalid return type Chill\\\\MainBundle\\\\Templating\\\\The\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/TranslatableStringTwig.php + + - + message: "#^Method Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringTwig\\:\\:getName\\(\\) should return Chill\\\\MainBundle\\\\Templating\\\\The but returns string\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/TranslatableStringTwig.php + + - + message: "#^Call to method render\\(\\) on an unknown class Chill\\\\MainBundle\\\\Templating\\\\Widget\\\\Widget\\\\WidgetInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/Widget/WidgetRenderingTwig.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/Widget/WidgetRenderingTwig.php + + - + message: "#^PHPDoc tag @var for variable \\$widget contains unknown class Chill\\\\MainBundle\\\\Templating\\\\Widget\\\\Widget\\\\WidgetInterface\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/Widget/WidgetRenderingTwig.php + + - + message: "#^Parameter \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineBuilder\\:\\:countItems\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\unknown\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php + + - + message: "#^Parameter \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineProviderInterface\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineProviderInterface.php + + - + message: "#^Parameter \\$entity of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineProviderInterface\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineProviderInterface.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Util\\\\DateRangeCovering\\:\\:\\$intervals is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Util/DateRangeCovering.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$messageDuplicateEmail\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validation/Validator/UserUniqueEmailAndUsername.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$messageDuplicateUsername\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validation/Validator/UserUniqueEmailAndUsername.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validation/Validator/ValidPhonenumber.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\MainBundle\\\\Entity\\\\User will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validator/Constraints/Entity/UserCircleConsistencyValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$element\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validator/Constraints/Export/ExportElementConstraintValidator.php + + - + message: "#^Property Chill\\\\MainBundle\\\\Workflow\\\\Templating\\\\WorkflowTwigExtensionRuntime\\:\\:\\$entityWorkflowManager is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Workflow/Templating/WorkflowTwigExtensionRuntime.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow and Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Workflow/Validator/EntityWorkflowCreationValidator.php + + - + message: "#^Instanceof between Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflowStep and Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflowStep will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Workflow/Validator/StepDestValidValidator.php + + - + message: "#^PHPDoc tag @param for parameter \\$postSql with type Chill\\\\PersonBundle\\\\Actions\\\\type is incompatible with native type string\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Actions/ActionEvent.php + + - + message: "#^Parameter \\$postSql of method Chill\\\\PersonBundle\\\\Actions\\\\ActionEvent\\:\\:addPostSql\\(\\) has invalid type Chill\\\\PersonBundle\\\\Actions\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Actions/ActionEvent.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\PersonMove\\:\\:getSQL\\(\\) has invalid return type Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\PersonMove\\:\\:getSQL\\(\\) should return Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\type but returns array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\EntityPersonCRUDController\\:\\:filterQueryEntitiesByPerson\\(\\) has invalid return type Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^PHPDoc tag @param for parameter \\$qb with type Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\QueryBuilder is not subtype of native type Doctrine\\\\ORM\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^PHPDoc tag @return with type Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\QueryBuilder is not subtype of native type Doctrine\\\\ORM\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^PHPDoc tag @throws with type Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\NotFoundHttpException is not subtype of Throwable$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^Parameter \\$action of method Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\EntityPersonCRUDController\\:\\:createEntity\\(\\) has invalid type Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\string\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^Parameter \\$qb of method Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\EntityPersonCRUDController\\:\\:filterQueryEntitiesByPerson\\(\\) has invalid type Chill\\\\PersonBundle\\\\CRUD\\\\Controller\\\\QueryBuilder\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/CRUD/Controller/EntityPersonCRUDController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\ExtensionInterface\\:\\:addWidgetFactory\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/ChillPersonBundle.php + + - + message: "#^Iterating over an object of an unknown class Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\type\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Command/ChillPersonMoveCommand.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\PersonBundle\\\\Command\\\\ImportSocialWorkMetadata\\:\\:\\$importer with type Psr\\\\Log\\\\LoggerInterface is not subtype of native type Chill\\\\PersonBundle\\\\Service\\\\Import\\\\ChillImporter\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Command/ImportSocialWorkMetadata.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\AccompanyingCourseApiController\\:\\:\\$accompanyingPeriodACLAwareRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php + + - + message: "#^Variable \\$accompanyingPeriod in PHPDoc tag @var does not match assigned variable \\$action\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and Doctrine\\\\Common\\\\Collections\\\\Collection will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Serializer\\\\SerializerInterface\\:\\:normalize\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Controller\\\\AccompanyingCourseWorkController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkController.php + + - + message: "#^Call to an undefined method Psr\\\\Container\\\\ContainerInterface\\:\\:getParameter\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Method Symfony\\\\Component\\\\Form\\\\FormInterface\\:\\:isValid\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\:\\:getFlashBag\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdCompositionController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:initialize\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findById\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Serializer\\\\SerializerInterface\\:\\:normalize\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php + + - + message: "#^Elseif condition is always true\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonAddressController.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Controller\\\\PersonAddressController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonAddressController.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Controller\\\\PersonAddressController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonAddressController.php + + - + message: "#^PHPDoc tag @param for parameter \\$person with type Chill\\\\PersonBundle\\\\Controller\\\\Chill\\\\PersonBundle\\\\Entity\\\\Person is not subtype of native type Chill\\\\PersonBundle\\\\Entity\\\\Person\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonAddressController.php + + - + message: "#^Parameter \\$person of method Chill\\\\PersonBundle\\\\Controller\\\\PersonAddressController\\:\\:validatePerson\\(\\) has invalid type Chill\\\\PersonBundle\\\\Controller\\\\Chill\\\\PersonBundle\\\\Entity\\\\Person\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonAddressController.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\\\:\\:findOneByEntity\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Form\\\\FormInterface\\:\\:isClicked\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\:\\:getGroupCenters\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Controller\\\\PersonController\\:\\:_validatePersonAndAccompanyingPeriod\\(\\) is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\PersonController\\:\\:\\$logger is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\Person will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$counters\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:countByParameters\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Cannot access property \\$getId on null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Iterating over an object of an unknown class Chill\\\\PersonBundle\\\\Actions\\\\Remove\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Controller\\\\PersonDuplicateController\\:\\:_getCounters\\(\\) never returns null so it can be removed from the return type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\PersonDuplicateController\\:\\:\\$translator \\(Symfony\\\\Component\\\\Translation\\\\TranslatorInterface\\) does not accept Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\PersonDuplicateController\\:\\:\\$translator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Call to function is_int\\(\\) with int will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\ReassignAccompanyingPeriodController\\:\\:\\$userRender is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\RelationshipApiController\\:\\:\\$validator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/RelationshipApiController.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Controller\\\\SocialWorkGoalApiController\\:\\:\\$paginator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/SocialWorkGoalApiController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/TimelinePersonController.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadAccompanyingPeriodNotifications.php + + - + message: "#^Invalid array key type array\\\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadRelationships.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:canBeDisabled\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:values\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Doctrine\\\\DQL\\\\AddressPart\\:\\:\\$part is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Doctrine/DQL/AddressPart.php + + - + message: "#^Result of method Doctrine\\\\ORM\\\\Query\\\\Parser\\:\\:match\\(\\) \\(void\\) is used\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Doctrine/DQL/AddressPart.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection\\:\\:matching\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Instanceof between Chill\\\\PersonBundle\\\\Entity\\\\Person and Chill\\\\PersonBundle\\\\Entity\\\\Person will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + + - + message: "#^Method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:getCreatedAt\\(\\) should return DateTime\\|null but returns DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:getRecursiveSocialActions\\(\\) has invalid return type Chill\\\\PersonBundle\\\\Entity\\\\SocialAction\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:getRecursiveSocialIssues\\(\\) has invalid return type Chill\\\\PersonBundle\\\\Entity\\\\SocialIssues\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Negated boolean expression is always true\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^PHPDoc tag @return with type array\\ is incompatible with native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^PHPDoc tag @return with type iterable is not subtype of native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$updatedAt is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$updatedBy is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodStepHistory will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\:\\:\\$createdAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\:\\:\\$endDate \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\:\\:\\$startDate \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork\\:\\:\\$updatedAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php + + - + message: "#^PHPDoc tag @param for parameter \\$createdAt with type DateTimeImmutable\\|null is not subtype of native type DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php + + - + message: "#^PHPDoc tag @param for parameter \\$updatedAt with type DateTimeImmutable\\|null is not subtype of native type DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluation\\:\\:\\$createdAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluation\\:\\:\\$updatedAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWorkEvaluation.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\Comment\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Comment.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriodParticipation\\:\\:checkSameStartEnd\\(\\) is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriodParticipation.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection\\:\\:matching\\(\\)\\.$#" + count: 5 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), mixed\\>\\:\\:uasort\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Cannot call method filter\\(\\) on array\\\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Cannot call method toArray\\(\\) on array\\\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\Household\\:\\:getAddresses\\(\\) should return array\\ but returns Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^PHPDoc tag @return with type array\\ is incompatible with native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^PHPDoc tag @return with type array\\ is incompatible with native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Strict comparison using \\!\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\HouseholdMember will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and int will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$address is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$household is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$person is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$validFrom is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\PersonHouseholdAddress\\:\\:\\$validTo is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Household/PersonHouseholdAddress.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string array \\$name\\)\\: Unexpected token \"array\", expected variable at offset 49$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/MaritalStatus.php + + - + message: "#^PHPDoc tag @return with type string is incompatible with native type array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/MaritalStatus.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Instanceof between DateTime and DateTimeInterface will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Negated boolean expression is always true\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^PHPDoc tag @return with type array\\ is incompatible with native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$calendars is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$center is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$currentHouseholdAt is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$deathdate \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$maritalStatusDate \\(DateTime\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$periodLocatedOn is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$proxyAccompanyingPeriodOpenState is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:\\$spokenLanguages \\(Doctrine\\\\Common\\\\Collections\\\\ArrayCollection\\) does not accept Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriodParticipation\\|null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\\\PersonResource\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person/PersonResource.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Person\\\\ResidentialAddress\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Person/ResidentialAddress.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\PersonAltName\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/PersonAltName.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\PersonPhone\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/PersonPhone.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Relationships\\\\Relationship\\:\\:\\$createdAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\Relationships\\\\Relationship\\:\\:\\$updatedAt \\(DateTimeImmutable\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/Relationships/Relationship.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\Result\\:\\:\\$desactivationDate \\(DateTime\\|null\\) does not accept DateTimeInterface\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/Result.php + + - + message: "#^If condition is always false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php + + - + message: "#^Negated boolean expression is always true\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php + + - + message: "#^Call to an undefined method Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\SocialAction\\:\\:getSocialIssue\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php + + - + message: "#^Call to an undefined method Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\SocialAction\\:\\:setSocialIssue\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php + + - + message: "#^If condition is always false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php + + - + message: "#^Negated boolean expression is always true\\.$#" + count: 4 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\SocialIssue\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php + + - + message: "#^Strict comparison using \\=\\=\\= between DateTimeImmutable and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Event/Person/PersonAddressMoveEvent.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and DateTimeImmutable will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Event/Person/PersonAddressMoveEvent.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\AccompanyingCourseAggregators\\\\DurationAggregator\\:\\:\\$translator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\EvaluationAggregators\\\\ByEndDateAggregator\\:\\:\\$translator is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\EvaluationAggregators\\\\ByMaxDateAggregator\\:\\:\\$translator is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\EvaluationAggregators\\\\ByStartDateAggregator\\:\\:\\$translator is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Aggregator\\\\HouseholdAggregators\\\\ChildrenNumberAggregator\\:\\:\\$translator is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Export\\\\ListAccompanyingPeriod\\:\\:\\$userHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Export/ListAccompanyingPeriod.php + + - + message: "#^Call to method extractOtherValue\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php + + - + message: "#^Call to method getChoices\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php + + - + message: "#^Call to method isChecked\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php + + - + message: "#^Call to method isMultiple\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php + + - + message: "#^Call to method render\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPerson.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Export\\\\ListPersonDuplicate\\:\\:\\$translator \\(Symfony\\\\Component\\\\Translation\\\\TranslatorInterface\\) does not accept Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Export/ListPersonDuplicate.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingCourseFilters\\\\AdministrativeLocationFilter\\:\\:\\$translatableStringHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingCourseFilters\\\\SocialActionFilter\\:\\:\\$translatableStringHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\AccompanyingCourseFilters\\\\UserScopeFilter\\:\\:getUserMainScope\\(\\) is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Export\\\\Filter\\\\SocialWorkFilters\\\\SocialWorkTypeFilter\\:\\:\\$socialActionRender is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php + + - + message: "#^PHPDoc tag @param for parameter \\$personRepository with type Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\EntityRepository is not subtype of native type Chill\\\\PersonBundle\\\\Repository\\\\PersonRepository\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Parameter \\$personRepository of method Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\PersonChoiceLoader\\:\\:__construct\\(\\) has invalid type Chill\\\\PersonBundle\\\\Form\\\\ChoiceLoader\\\\EntityRepository\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/CreationPersonType.php + + - + message: "#^Call to function is_array\\(\\) with Doctrine\\\\Common\\\\Collections\\\\Collection will always evaluate to false\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php + + - + message: "#^Call to method getData\\(\\) on an unknown class Chill\\\\PersonBundle\\\\Form\\\\DataMapper\\\\FormInterface\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php + + - + message: "#^Parameter \\#1 \\$forms \\(array\\\\) of method Chill\\\\PersonBundle\\\\Form\\\\DataMapper\\\\PersonAltNameDataMapper\\:\\:mapFormsToData\\(\\) should be compatible with parameter \\$forms \\(iterable\\&Traversable\\) of method Symfony\\\\Component\\\\Form\\\\DataMapperInterface\\:\\:mapFormsToData\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php + + - + message: "#^Parameter \\$forms of method Chill\\\\PersonBundle\\\\Form\\\\DataMapper\\\\PersonAltNameDataMapper\\:\\:mapFormsToData\\(\\) has invalid type Chill\\\\PersonBundle\\\\Form\\\\DataMapper\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Form\\\\PersonResourceType\\:\\:\\$personRender is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonResourceType.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Form\\\\PersonResourceType\\:\\:\\$thirdPartyRender is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonResourceType.php + + - + message: "#^PHPDoc tag @param for parameter \\$resolver with type Chill\\\\PersonBundle\\\\Form\\\\OptionsResolverInterface is not subtype of native type Symfony\\\\Component\\\\OptionsResolver\\\\OptionsResolver\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonType.php + + - + message: "#^Parameter \\$resolver of method Chill\\\\PersonBundle\\\\Form\\\\PersonType\\:\\:configureOptions\\(\\) has invalid type Chill\\\\PersonBundle\\\\Form\\\\OptionsResolverInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonType.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Form\\\\PersonType\\:\\:\\$parameterBag is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonType.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Form\\\\PersonType\\:\\:\\$translatableStringHelper \\(Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringHelper\\) does not accept Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringHelperInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/PersonType.php + + - + message: "#^Strict comparison using \\=\\=\\= between 'create' and 'create' will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/SocialWork/SocialIssueType.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Form\\\\Type\\\\PickPersonType\\:\\:\\$user \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php + + - + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Collections\\\\Collection&iterable\\\\:\\:matching\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Household/MembersEditor.php + + - + message: "#^Method Doctrine\\\\Common\\\\Collections\\\\ExpressionBuilder\\:\\:isNull\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Household/MembersEditor.php + + - + message: "#^Cannot call method getId\\(\\) on string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkGoalRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkGoalRepository.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\:\\:countByAccompanyingPeriod\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\EntityRepository\\:\\:findByAccompanyingPeriod\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\CommentRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/CommentRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\OriginRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/OriginRepository.php + + - + message: "#^PHPDoc tag @param has invalid value \\(array\\|PostalCode\\[\\]\\)\\: Unexpected token \"\\\\n \\*\", expected variable at offset 36$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodACLAwareRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriodParticipationRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriodParticipationRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\HouseholdMembersRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/HouseholdMembersRepository.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\PositionRepository\\:\\:findOneBy\\(\\) should return array\\ but returns object\\|null\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php + + - + message: "#^Return type \\(array\\\\) of method Chill\\\\PersonBundle\\\\Repository\\\\Household\\\\PositionRepository\\:\\:findOneBy\\(\\) should be compatible with return type \\(object\\|null\\) of method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findOneBy\\(\\)$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\PersonACLAwareRepository\\:\\:\\$countryRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Repository\\\\PersonAltNameRepository\\:\\:\\$repository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/PersonAltNameRepository.php + + - + message: "#^PHPDoc tag @return with type array\\\\|null is not subtype of native type array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Repository/ResidentialAddressRepository.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Search\\\\PersonSearch\\:\\:renderResult\\(\\) should return string but returns array\\\\>\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/PersonSearch.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Search\\\\SearchHouseholdApiProvider\\:\\:\\$authorizationHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Search\\\\SearchHouseholdApiProvider\\:\\:\\$security is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Search\\\\SearchPersonApiProvider\\:\\:\\$authorizationHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/SearchPersonApiProvider.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Search\\\\SearchPersonApiProvider\\:\\:\\$security is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Search/SearchPersonApiProvider.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Security\\\\Authorization\\\\AccompanyingPeriodVoter\\:\\:\\$security is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php + + - + message: "#^PHPDoc tag @return with type bool\\|void is not subtype of native type bool\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkEvaluationDocumentVoter.php + + - + message: "#^Elseif branch is unreachable because previous condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Instanceof between \\*NEVER\\* and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Instanceof between Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork and Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodWork will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Security\\\\Authorization\\\\AccompanyingPeriodWorkVoter\\:\\:\\$voterHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodWorkVoter.php + + - + message: "#^Constant Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodDocGenNormalizer\\:\\:IGNORE_FIRST_PASS_KEY is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Strict comparison using \\!\\=\\= between Chill\\\\PersonBundle\\\\Entity\\\\Person\\|Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty and null will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and null will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodDocGenNormalizer.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodParticipationNormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkDenormalizer\\:\\:\\$em is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkDenormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkDenormalizer\\:\\:\\$workRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkDenormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationDocumentNormalizer\\:\\:\\$registry is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationDocumentNormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkEvaluationNormalizer\\:\\:\\$registry is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkEvaluationNormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\AccompanyingPeriodWorkNormalizer\\:\\:\\$registry is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php + + - + message: "#^Call to function is_array\\(\\) with 'concerned' will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Expression on left side of \\?\\? is not nullable\\.$#" + count: 3 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Left side of && is always false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between false and false will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php + + - + message: "#^Instanceof between Chill\\\\PersonBundle\\\\Entity\\\\Person and Chill\\\\PersonBundle\\\\Entity\\\\Person will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonDocGenNormalizer\\:\\:hasGroup\\(\\) is unused\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\Person will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonDocGenNormalizer.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\PersonJsonNormalizer\\:\\:\\$phoneNumberHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/PersonJsonNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\Relationships\\\\Relationship will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/RelationshipDocGenNormalizer.php + + - + message: "#^Method Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\SocialIssueNormalizer\\:\\:normalize\\(\\) should return array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|null but return statement is missing\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\SocialIssue will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/SocialIssueNormalizer.php + + - + message: "#^PHPDoc tag @return with type array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|void\\|null is not subtype of native type array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/WorkflowNormalizer.php + + - + message: "#^Call to an undefined method Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:setCourse\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php + + - + message: "#^Call to function array_key_exists\\(\\) with 'category' and array will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php + + - + message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php + + - + message: "#^Call to an undefined method Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:setPerson\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php + + - + message: "#^Call to function array_key_exists\\(\\) with 'category' and array will always evaluate to true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php + + - + message: "#^Comparison operation \"\\<\" between 1 and array results in an error\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php + + - + message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/DocGenerator/PersonContext.php + + - + message: "#^PHPDoc tag @param has invalid value \\(array\\\\|SocialIssue\\|string, SocialAction\\|null\\>\\|Evaluation\\|Goal\\|Result\\> \\$previousRow\\)\\: Unexpected token \"\\<\", expected type at offset 333$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php + + - + message: "#^PHPDoc tag @return has invalid value \\(array\\\\|SocialIssue\\|string, SocialAction\\|null\\>\\|Evaluation\\|Goal\\|Result\\>\\)\\: Unexpected token \"\\<\", expected type at offset 505$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Service\\\\Import\\\\SocialWorkMetadata\\:\\:\\$socialActionRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Service\\\\Import\\\\SocialWorkMetadata\\:\\:\\$socialIssueRepository is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php + + - + message: "#^Call to method getId\\(\\) on an unknown class ChillPersonBundle\\:AccompanyingPeriod\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php + + - + message: "#^Cannot call method setKey\\(\\) on array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php + + - + message: "#^Parameter \\$context of method Chill\\\\PersonBundle\\\\Timeline\\\\TimelineAccompanyingPeriodClosing\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php + + - + message: "#^Parameter \\$entity of method Chill\\\\PersonBundle\\\\Timeline\\\\TimelineAccompanyingPeriodClosing\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php + + - + message: "#^Cannot call method setKey\\(\\) on array\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php + + - + message: "#^Parameter \\$context of method Chill\\\\PersonBundle\\\\Timeline\\\\TimelineAccompanyingPeriodOpening\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php + + - + message: "#^Parameter \\$entity of method Chill\\\\PersonBundle\\\\Timeline\\\\TimelineAccompanyingPeriodOpening\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Validator\\\\Constraints\\\\AccompanyingPeriod\\\\AccompanyingPeriodValidityValidator\\:\\:\\$token is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidityValidator.php + + - + message: "#^Property Chill\\\\PersonBundle\\\\Validator\\\\Constraints\\\\AccompanyingPeriod\\\\ParticipationOverlapValidator\\:\\:\\$thirdpartyRender is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ParticipationOverlapValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between 0 and int\\<2, max\\> will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ParticipationOverlapValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$message\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/Household/HouseholdMembershipSequentialValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$message\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/Household/MaxHolderValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$messageInfinity\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/Household/MaxHolderValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$message\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/Person/BirthdateValidator.php + + - + message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$message\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Validator/Constraints/Person/PersonHasCenterValidator.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Widget/PersonListWidget.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:info\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Widget/PersonListWidgetFactory.php + + - + message: "#^Parameter \\$place of method Chill\\\\PersonBundle\\\\Widget\\\\PersonListWidgetFactory\\:\\:configureOptions\\(\\) has invalid type Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Widget/PersonListWidgetFactory.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQuery\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findByCFGroup\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectRepository\\\\:\\:findByEntity\\(\\)\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Call to method getId\\(\\) on an unknown class ChillReportBundle\\:Report\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Call to method getPerson\\(\\) on an unknown class ChillReportBundle\\:Report\\.$#" + count: 3 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createCreateForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createEditForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:editAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:editAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:exportAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\A\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:exportAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\A but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:listAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:listAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:newAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:newAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeForExportAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeForExportAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:selectReportTypeForExportAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:updateAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:updateAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\RedirectResponse\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:updateAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:viewAction\\(\\) has invalid return type Chill\\\\ReportBundle\\\\Controller\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:viewAction\\(\\) should return Chill\\\\ReportBundle\\\\Controller\\\\Response but returns Symfony\\\\Component\\\\HttpFoundation\\\\Response\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 4 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\LoadReports\\:\\:getRandomChoice\\(\\) never returns string so it can be removed from the return type\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\LoadReports\\:\\:getRandomChoice\\(\\) should return array\\\\|string but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php + + - + message: "#^Method Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\LoadReports\\:\\:pickChoice\\(\\) has invalid return type Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\the\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php + + - + message: "#^Strict comparison using \\=\\=\\= between '_other' and Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\the will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php + + - + message: "#^Strict comparison using \\=\\=\\= between DateTime and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DataFixtures/ORM/LoadReports.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/DependencyInjection/Configuration.php + + - + message: "#^PHPDoc tag @param for parameter \\$scope with type string is incompatible with native type Chill\\\\MainBundle\\\\Entity\\\\Scope\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Entity/Report.php + + - + message: "#^Property Chill\\\\ReportBundle\\\\Entity\\\\Report\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Entity/Report.php + + - + message: "#^Call to method extractOtherValue\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php + + - + message: "#^Call to method getChoices\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php + + - + message: "#^Call to method isChecked\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php + + - + message: "#^Call to method isMultiple\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 2 + path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php + + - + message: "#^Call to method render\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php + + - + message: "#^Property Chill\\\\ReportBundle\\\\Form\\\\ReportType\\:\\:\\$user \\(Chill\\\\MainBundle\\\\Entity\\\\User\\) does not accept string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Form/ReportType.php + + - + message: "#^Call to method getId\\(\\) on an unknown class ChillReportBundle\\:Report\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Parameter \\$context of method Chill\\\\ReportBundle\\\\Timeline\\\\TimelineReportProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Parameter \\$entity of method Chill\\\\ReportBundle\\\\Timeline\\\\TimelineReportProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Controller\\\\SingleTaskController\\:\\:createDeleteForm\\(\\) should return Symfony\\\\Component\\\\Form\\\\Form but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 6 + path: src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Controller\\\\SingleTaskController\\:\\:\\$centerResolverDispatcher is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and int will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php + + - + message: "#^If condition is always true\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/TaskController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/TaskController.php + + - + message: "#^PHPDoc tag @param for parameter \\$task with type Chill\\\\TaskBundle\\\\Controller\\\\AbstractTask is not subtype of native type Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/TaskController.php + + - + message: "#^Parameter \\$task of method Chill\\\\TaskBundle\\\\Controller\\\\TaskController\\:\\:createTransitionForm\\(\\) has invalid type Chill\\\\TaskBundle\\\\Controller\\\\AbstractTask\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/TaskController.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/DependencyInjection/Configuration.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:\\$currentStates \\(Chill\\\\TaskBundle\\\\Entity\\\\json\\) does not accept array\\\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:\\$currentStates \\(Chill\\\\TaskBundle\\\\Entity\\\\json\\) does not accept default value of type array\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:\\$currentStates has unknown class Chill\\\\TaskBundle\\\\Entity\\\\json as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:getOccurenceStartDate\\(\\) has invalid return type Chill\\\\TaskBundle\\\\Entity\\\\dateinterval\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:getOccurenceWarningInterval\\(\\) has invalid return type Chill\\\\TaskBundle\\\\Entity\\\\dateinterval\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Parameter \\$occurenceStartDate of method Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:setOccurenceStartDate\\(\\) has invalid type Chill\\\\TaskBundle\\\\Entity\\\\dateinterval\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Parameter \\$occurenceWarningInterval of method Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:setOccurenceWarningInterval\\(\\) has invalid type Chill\\\\TaskBundle\\\\Entity\\\\dateinterval\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:\\$occurenceStartDate has unknown class Chill\\\\TaskBundle\\\\Entity\\\\dateinterval as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:\\$occurenceWarningInterval has unknown class Chill\\\\TaskBundle\\\\Entity\\\\dateinterval as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\RecurringTask\\:\\:\\$singleTasks is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/RecurringTask.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Entity\\\\SingleTask\\:\\:getWarningDate\\(\\) should return DateTimeImmutable but returns null\\.$#" + count: 2 + path: src/Bundle/ChillTaskBundle/Entity/SingleTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\SingleTask\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/SingleTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\SingleTask\\:\\:\\$warningInterval \\(DateInterval\\) does not accept string\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/SingleTask.php + + - + message: "#^Strict comparison using \\=\\=\\= between DateInterval and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/SingleTask.php + + - + message: "#^Strict comparison using \\=\\=\\= between DateTime and null will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/SingleTask.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:getDatetime\\(\\) has invalid return type Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\datetime_immutable\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Parameter \\$datetime of method Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:setDatetime\\(\\) has invalid type Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\datetime_immutable\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:\\$data \\(string\\) does not accept default value of type array\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:\\$datetime \\(Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\datetime_immutable\\) does not accept DateTimeImmutable\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:\\$datetime has unknown class Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\datetime_immutable as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\AbstractTaskPlaceEvent\\:\\:\\$id is never written, only read\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/Task/AbstractTaskPlaceEvent.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:getTaskPlaceEvents\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Event/Lifecycle/TaskLifecycleEvent.php + + - + message: "#^Method Knp\\\\Menu\\\\MenuItem\\:\\:setExtras\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Menu/MenuBuilder.php + + - + message: "#^Call to an undefined method Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface\\:\\:transChoice\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Menu/UserMenuBuilder.php + + - + message: "#^Method Chill\\\\TaskBundle\\\\Repository\\\\SingleTaskRepository\\:\\:findByParameters\\(\\) has invalid return type Chill\\\\TaskBundle\\\\Repository\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Repository/SingleTaskRepository.php + + - + message: "#^Parameter \\$params of method Chill\\\\TaskBundle\\\\Repository\\\\SingleTaskRepository\\:\\:findByParameters\\(\\) has invalid type Chill\\\\TaskBundle\\\\Repository\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Repository/SingleTaskRepository.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Security\\\\Authorization\\\\AuthorizationEvent\\:\\:\\$subject has unknown class Chill\\\\TaskBundle\\\\Security\\\\Authorization\\\\Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Security/Authorization/AuthorizationEvent.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Security\\\\Authorization\\\\AuthorizationEvent\\:\\:\\$vote \\(bool\\) does not accept null\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Security/Authorization/AuthorizationEvent.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php + + - + message: "#^Call to method deleteItem\\(\\) on an unknown class Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CacheItempPoolInterface\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Templating/UI/CountNotificationTask.php + + - + message: "#^Call to method getItem\\(\\) on an unknown class Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CacheItempPoolInterface\\.$#" + count: 2 + path: src/Bundle/ChillTaskBundle/Templating/UI/CountNotificationTask.php + + - + message: "#^Call to method save\\(\\) on an unknown class Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CacheItempPoolInterface\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Templating/UI/CountNotificationTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CountNotificationTask\\:\\:\\$cachePool \\(Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CacheItempPoolInterface\\) does not accept Psr\\\\Cache\\\\CacheItemPoolInterface\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Templating/UI/CountNotificationTask.php + + - + message: "#^Property Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CountNotificationTask\\:\\:\\$cachePool has unknown class Chill\\\\TaskBundle\\\\Templating\\\\UI\\\\CacheItempPoolInterface as its type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Templating/UI/CountNotificationTask.php + + - + message: "#^Call to method getData\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 2 + path: src/Bundle/ChillTaskBundle/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to method getTask\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to method getTransition\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php + + - + message: "#^Parameter \\$context of method Chill\\\\TaskBundle\\\\Timeline\\\\SingleTaskTaskLifeCycleEventTimelineProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php + + - + message: "#^Parameter \\$entity of method Chill\\\\TaskBundle\\\\Timeline\\\\SingleTaskTaskLifeCycleEventTimelineProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to method getData\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 2 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to method getTask\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 2 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to method getTransition\\(\\) on an unknown class Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Parameter \\$context of method Chill\\\\TaskBundle\\\\Timeline\\\\TaskLifeCycleEventTimelineProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Parameter \\$entity of method Chill\\\\TaskBundle\\\\Timeline\\\\TaskLifeCycleEventTimelineProvider\\:\\:getEntityTemplate\\(\\) has invalid type Chill\\\\MainBundle\\\\Timeline\\\\type\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask\\:\\:getId\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Workflow/TaskWorkflowManager.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Workflow\\\\TaskWorkflowDefinition\\:\\:getAssociatedWorkflowName\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Workflow/TaskWorkflowManager.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Workflow\\\\TaskWorkflowDefinition\\:\\:getWorkflowMetadata\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Workflow/TaskWorkflowManager.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Workflow\\\\TaskWorkflowDefinition\\:\\:isClosed\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Workflow/TaskWorkflowManager.php + + - + message: "#^Call to an undefined method Chill\\\\TaskBundle\\\\Workflow\\\\TaskWorkflowDefinition\\:\\:supports\\(\\)\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Workflow/TaskWorkflowManager.php + + - + message: "#^Method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\TreeBuilder\\:\\:getRootNode\\(\\) invoked with 1 parameter, 0 required\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/DependencyInjection/Configuration.php + + - + message: "#^PHPDoc tag @return with type DateTime\\|null is not subtype of native type DateTimeImmutable\\|null\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^PHPDoc tag @var for property Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:\\$categories with type Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdPartyCategory is not subtype of native type Doctrine\\\\Common\\\\Collections\\\\Collection\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^Property Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:\\$canonicalized is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^Property Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\:\\:\\$createdBy is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php + + - + message: "#^Property Chill\\\\ThirdPartyBundle\\\\Repository\\\\ThirdPartyACLAwareRepository\\:\\:\\$authorizationHelper is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyACLAwareRepository.php + + - + message: "#^Property Chill\\\\ThirdPartyBundle\\\\Repository\\\\ThirdPartyACLAwareRepository\\:\\:\\$security is never read, only written\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyACLAwareRepository.php + + - + message: "#^Argument of an invalid type string supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php + + - + message: "#^Method Chill\\\\ThirdPartyBundle\\\\Search\\\\ThirdPartySearch\\:\\:renderResult\\(\\) should return string but returns array\\\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php + + - + message: "#^Strict comparison using \\=\\=\\= between null and Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Controller/Editor.php + + - + message: "#^Strict comparison using \\=\\=\\= between false and array will always evaluate to false\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/AuthorizationManager.php + + - + message: "#^Default value of the parameter \\#2 \\$properties \\(array\\{\\}\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:write\\(\\) is incompatible with type array\\{content\\: string, size\\: int\\}\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\WopiInterface\\:\\:checkFileInfo\\(\\) invoked with 4 parameters, 3 required\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillWopi.php diff --git a/phpstan-baseline-level-5.neon b/phpstan-baseline-level-5.neon new file mode 100644 index 000000000..23321ba68 --- /dev/null +++ b/phpstan-baseline-level-5.neon @@ -0,0 +1,686 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Controller/ActivityController.php + + - + message: "#^Parameter \\#1 \\$context of method Chill\\\\ActivityBundle\\\\Timeline\\\\TimelineActivityProvider\\:\\:checkContext\\(\\) expects string, Chill\\\\MainBundle\\\\Timeline\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php + + - + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(Chill\\\\BudgetBundle\\\\Repository\\\\ChargeType\\)\\: mixed\\)\\|null, Closure\\(Chill\\\\BudgetBundle\\\\Entity\\\\ChargeKind\\)\\: int\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php + + - + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(Chill\\\\BudgetBundle\\\\Repository\\\\ResourceType\\)\\: mixed\\)\\|null, Closure\\(Chill\\\\BudgetBundle\\\\Entity\\\\ResourceKind\\)\\: int\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php + + - + message: "#^Parameter \\#2 \\$byUser of class Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\InviteUpdateMessage constructor expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Controller/InviteApiController.php + + - + message: "#^Parameter \\#2 \\$byUser of class Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\CalendarRemovedMessage constructor expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php + + - + message: "#^Parameter \\#3 \\$byUser of class Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\CalendarMessage constructor expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php + + - + message: "#^Parameter \\#2 \\$byUser of class Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\CalendarRangeRemovedMessage constructor expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php + + - + message: "#^Parameter \\#3 \\$byUser of class Chill\\\\CalendarBundle\\\\Messenger\\\\Message\\\\CalendarRangeMessage constructor expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php + + - + message: "#^Parameter \\#1 \\$token of method Chill\\\\CalendarBundle\\\\RemoteCalendar\\\\Connector\\\\MSGraph\\\\OnBehalfOfUserTokenStorage\\:\\:setToken\\(\\) expects TheNetworg\\\\OAuth2\\\\Client\\\\Token\\\\AccessToken, League\\\\OAuth2\\\\Client\\\\Token\\\\AccessTokenInterface given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php + + - + message: "#^Parameter \\#2 \\$code of class Exception constructor expects int, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php + + - + message: "#^Parameter \\#4 \\$offset of method Chill\\\\CalendarBundle\\\\Repository\\\\CalendarRepository\\:\\:findBy\\(\\) expects int\\|null, array\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php + + - + message: "#^Parameter \\#1 \\$prefix of function uniqid expects string, int\\<0, max\\> given\\.$#" + count: 1 + path: src/Bundle/ChillCustomFieldsBundle/Form/Type/ChoicesListType.php + + - + message: "#^Parameter \\#2 \\$callback of function array_filter expects callable\\(Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\AttributeMetadataInterface\\)\\: mixed, Closure\\(Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\AttributeMetadata\\)\\: bool given\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#3 \\$metadata of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:normalizeNullData\\(\\) expects Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\ClassMetadata, Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\ClassMetadataInterface given\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#4 \\$attributes of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:normalizeNullData\\(\\) expects array\\, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#5 \\$metadata of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:normalizeObject\\(\\) expects Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\ClassMetadata, Symfony\\\\Component\\\\Serializer\\\\Mapping\\\\ClassMetadataInterface given\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#6 \\$attributes of method Chill\\\\DocGeneratorBundle\\\\Serializer\\\\Normalizer\\\\DocGenObjectNormalizer\\:\\:normalizeObject\\(\\) expects array\\, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillDocGeneratorBundle/Serializer/Normalizer/DocGenObjectNormalizer.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 4 + path: src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Parameter \\#1 \\$name of method Symfony\\\\Component\\\\Form\\\\FormFactoryInterface\\:\\:createNamedBuilder\\(\\) expects string, null given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, Chill\\\\MainBundle\\\\Entity\\\\Center given\\.$#" + count: 1 + path: src/Bundle/ChillEventBundle/Controller/EventController.php + + - + message: "#^Parameter \\#1 \\$participations of method Chill\\\\EventBundle\\\\Controller\\\\ParticipationController\\:\\:createEditFormMultiple\\(\\) expects ArrayIterator, Traversable given\\.$#" + count: 2 + path: src/Bundle/ChillEventBundle/Controller/ParticipationController.php + + - + message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, null given\\.$#" + count: 2 + path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php + + - + message: "#^Parameter \\#2 \\$previous of class Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\BadRequestHttpException constructor expects Throwable\\|null, int given\\.$#" + count: 3 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Parameter \\#3 \\$code of class Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\BadRequestHttpException constructor expects int, Symfony\\\\Component\\\\Serializer\\\\Exception\\\\NotEncodableValueException given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Parameter \\#3 \\$code of class Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\BadRequestHttpException constructor expects int, Symfony\\\\Component\\\\Serializer\\\\Exception\\\\UnexpectedValueException given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Parameter \\#3 \\$formClass of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\CRUDController\\:\\:createFormFor\\(\\) expects string\\|null, Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\type\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Parameter \\#3 \\$scope of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\Scope\\|null, Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\Scope\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php + + - + message: "#^Parameter \\#1 \\$name of method Chill\\\\MainBundle\\\\Entity\\\\Country\\:\\:setName\\(\\) expects string, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/LoadCountriesCommand.php + + - + message: "#^Parameter \\#4 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, Chill\\\\MainBundle\\\\Entity\\\\the given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php + + - + message: "#^Parameter \\#1 \\$alias of method Chill\\\\MainBundle\\\\Export\\\\ExportManager\\:\\:getExport\\(\\) expects string, Symfony\\\\Component\\\\HttpFoundation\\\\Request given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#1 \\$name of method Symfony\\\\Component\\\\Form\\\\FormFactoryInterface\\:\\:createNamedBuilder\\(\\) expects string, null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#3 \\$alias of method Chill\\\\MainBundle\\\\Controller\\\\ExportController\\:\\:exportFormStep\\(\\) expects string, Symfony\\\\Component\\\\HttpFoundation\\\\Request given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#3 \\$alias of method Chill\\\\MainBundle\\\\Controller\\\\ExportController\\:\\:formatterFormStep\\(\\) expects string, Symfony\\\\Component\\\\HttpFoundation\\\\Request given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#3 \\$alias of method Chill\\\\MainBundle\\\\Controller\\\\ExportController\\:\\:forwardToGenerate\\(\\) expects string, Symfony\\\\Component\\\\HttpFoundation\\\\Request given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#3 \\$alias of method Chill\\\\MainBundle\\\\Controller\\\\ExportController\\:\\:selectCentersStep\\(\\) expects string, Symfony\\\\Component\\\\HttpFoundation\\\\Request given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/ExportController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:countUnreadByUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:findUnreadByUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationApiController.php + + - + message: "#^Parameter \\#1 \\$addressee of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:countAllForAttendee\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$addressee of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:findAllForAttendee\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$sender of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:countAllForSender\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$sender of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:findAllForSender\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:countUnreadByUserWhereAddressee\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Repository\\\\NotificationRepository\\:\\:countUnreadByUserWhereSender\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/NotificationController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 4 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Parameter \\#1 \\$token of class Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent constructor expects Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\|null, string given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Parameter \\#3 \\$ip of class Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\PasswordRecoverEvent constructor expects Chill\\\\MainBundle\\\\Security\\\\PasswordRecover\\\\type\\|null, string\\|null given\\.$#" + count: 4 + path: src/Bundle/ChillMainBundle/Controller/PasswordController.php + + - + message: "#^Parameter \\#1 \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineBuilder\\:\\:countItems\\(\\) expects Chill\\\\MainBundle\\\\Timeline\\\\unknown, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/TimelineCenterController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:addSubscriberToFinal\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:addSubscriberToStep\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:isUserSubscribedToFinal\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:isUserSubscribedToStep\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:removeSubscriberToFinal\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflow\\:\\:removeSubscriberToStep\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php + + - + message: "#^Parameter \\#1 \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:filterWidgetByPlace\\(\\) expects string, Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Parameter \\#1 \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Configuration\\:\\:getWidgetAliasesbyPlace\\(\\) expects Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Parameter \\#2 \\$array of function implode expects array\\|null, Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php + + - + message: "#^Parameter \\#2 \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:createDefinition\\(\\) expects Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Parameter \\#3 \\$order of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:createDefinition\\(\\) expects Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type, float given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php + + - + message: "#^Parameter \\#2 \\$place of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:getServiceId\\(\\) expects string, Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/AbstractWidgetFactory.php + + - + message: "#^Parameter \\#3 \\$order of method Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\WidgetFactoryInterface\\:\\:getServiceId\\(\\) expects float, Chill\\\\MainBundle\\\\DependencyInjection\\\\Widget\\\\Factory\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/DependencyInjection/Widget/Factory/AbstractWidgetFactory.php + + - + message: "#^Parameter \\#1 \\$iterator of function iterator_to_array expects Traversable, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/ExportManager.php + + - + message: "#^Parameter \\#2 \\$nbAggregators of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\CSVFormatter\\:\\:appendAggregatorForm\\(\\) expects string, int\\<0, max\\> given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php + + - + message: "#^Parameter \\#2 \\$array of function array_map expects array, Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Parameter \\#2 \\$nbAggregators of method Chill\\\\MainBundle\\\\Export\\\\Formatter\\\\SpreadSheetFormatter\\:\\:appendAggregatorForm\\(\\) expects string, int\\<0, max\\> given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php + + - + message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, null given\\.$#" + count: 2 + path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Embeddable\\\\PrivateCommentEmbeddable\\:\\:getCommentForUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/DataMapper/PrivateCommentDataMapper.php + + - + message: "#^Parameter \\#1 \\$em of class Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\ObjectToIdTransformer constructor expects Doctrine\\\\ORM\\\\EntityManagerInterface, Doctrine\\\\Persistence\\\\ObjectManager given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php + + - + message: "#^Parameter \\#1 \\$em of class Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\MultipleObjectsToIdTransformer constructor expects Doctrine\\\\ORM\\\\EntityManagerInterface, Doctrine\\\\Persistence\\\\ObjectManager given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php + + - + message: "#^Parameter \\#1 \\$translatableStrings of method Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringHelper\\:\\:localize\\(\\) expects array, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php + + - + message: "#^Parameter \\#1 \\$datetime of class DateTime constructor expects string, Chill\\\\MainBundle\\\\Search\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/AbstractSearch.php + + - + message: "#^Parameter \\#4 \\$paginator of method Chill\\\\MainBundle\\\\Search\\\\SearchApi\\:\\:fetchRawResult\\(\\) expects Chill\\\\MainBundle\\\\Pagination\\\\Paginator, Chill\\\\MainBundle\\\\Pagination\\\\PaginatorInterface given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchApi.php + + - + message: "#^Parameter \\#2 \\$callback of function uasort expects callable\\(Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm, Chill\\\\MainBundle\\\\Search\\\\HasAdvancedSearchForm\\)\\: int, Closure\\(Chill\\\\MainBundle\\\\Search\\\\SearchInterface, Chill\\\\MainBundle\\\\Search\\\\SearchInterface\\)\\: \\-1\\|0\\|1 given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Parameter \\#2 \\$subject of function preg_match_all expects string, Chill\\\\MainBundle\\\\Search\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Search/SearchProvider.php + + - + message: "#^Parameter \\#1 \\$object of function get_class expects object, array\\ given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Notification\\:\\:isReadBy\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/NotificationNormalizer.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Entity\\\\Embeddable\\\\PrivateCommentEmbeddable\\:\\:setCommentForUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Serializer/Normalizer/PrivateCommentEmbeddableNormalizer.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Templating/Widget/WidgetRenderingTwig.php + + - + message: "#^Parameter \\#1 \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineBuilder\\:\\:buildUnionQuery\\(\\) expects string, Chill\\\\MainBundle\\\\Timeline\\\\unknown given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php + + - + message: "#^Parameter \\#2 \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineProviderInterface\\:\\:getEntityTemplate\\(\\) expects Chill\\\\MainBundle\\\\Timeline\\\\type, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php + + - + message: "#^Parameter \\#1 \\$phoneNumber of method Chill\\\\MainBundle\\\\Phonenumber\\\\PhoneNumberHelperInterface\\:\\:format\\(\\) expects libphonenumber\\\\PhoneNumber\\|null, string given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Validation/Validator/ValidPhonenumber.php + + - + message: "#^Parameter \\#1 \\$transitionBy of method Chill\\\\MainBundle\\\\Entity\\\\Workflow\\\\EntityWorkflowStep\\:\\:setTransitionBy\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowTransitionEventSubscriber.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseApiController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Parameter \\#2 \\$callback of function usort expects callable\\(mixed, mixed\\)\\: int, Closure\\(mixed, mixed\\)\\: bool given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationRepository\\:\\:countNearMaxDateByUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkEvaluationApiController.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkEvaluationRepository\\:\\:findNearMaxDateByUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkEvaluationApiController.php + + - + message: "#^Parameter \\#1 \\$object of static method DateTimeImmutable\\:\\:createFromMutable\\(\\) expects DateTime, DateTimeInterface given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdApiController.php + + - + message: "#^Parameter \\#2 \\$callback of function usort expects callable\\(mixed, mixed\\)\\: int, Closure\\(mixed, mixed\\)\\: bool given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdController.php + + - + message: "#^Parameter \\#2 \\$previous of class Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\BadRequestHttpException constructor expects Throwable\\|null, int given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php + + - + message: "#^Parameter \\#3 \\$code of class Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\BadRequestHttpException constructor expects int, Symfony\\\\Component\\\\Serializer\\\\Exception\\\\InvalidArgumentException\\|Symfony\\\\Component\\\\Serializer\\\\Exception\\\\UnexpectedValueException given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Parameter \\#1 \\$form of method Chill\\\\PersonBundle\\\\Controller\\\\PersonController\\:\\:isLastPostDataChanges\\(\\) expects Symfony\\\\Component\\\\Form\\\\Form, Symfony\\\\Component\\\\Form\\\\FormInterface given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Parameter \\#2 \\$precision of method Chill\\\\PersonBundle\\\\Search\\\\SimilarPersonMatcher\\:\\:matchPerson\\(\\) expects float, Chill\\\\PersonBundle\\\\Repository\\\\PersonNotDuplicateRepository given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Parameter \\#3 \\$orderBy of method Chill\\\\PersonBundle\\\\Search\\\\SimilarPersonMatcher\\:\\:matchPerson\\(\\) expects string, float given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Parameter \\#4 \\$addYearComparison of method Chill\\\\PersonBundle\\\\Search\\\\SimilarPersonMatcher\\:\\:matchPerson\\(\\) expects bool, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php + + - + message: "#^Parameter \\#1 \\$context of method Chill\\\\MainBundle\\\\Timeline\\\\TimelineBuilder\\:\\:countItems\\(\\) expects Chill\\\\MainBundle\\\\Timeline\\\\unknown, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/TimelinePersonController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Controller/TimelinePersonController.php + + - + message: "#^Parameter \\#1 \\$period of method Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\\\AccompanyingPeriodLocationHistory\\:\\:setPeriod\\(\\) expects Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod, null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php + + - + message: "#^Parameter \\#1 \\$now of method Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\Household\\:\\:getCurrentMembers\\(\\) expects DateTimeImmutable\\|null, DateTimeInterface\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Parameter \\#1 \\$now of method Chill\\\\PersonBundle\\\\Entity\\\\Household\\\\Household\\:\\:getNonCurrentMembers\\(\\) expects DateTimeImmutable\\|null, DateTimeInterface\\|null given\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Entity/Household/Household.php + + - + message: "#^Parameter \\#1 \\$key of method Doctrine\\\\Common\\\\Collections\\\\Collection\\<\\(int\\|string\\),mixed\\>\\:\\:remove\\(\\) expects \\(int\\|string\\), Chill\\\\PersonBundle\\\\Entity\\\\SocialWork\\\\SocialAction given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Entity/SocialWork/Evaluation.php + + - + message: "#^Parameter \\#1 \\$translatableStrings of method Chill\\\\MainBundle\\\\Templating\\\\TranslatableStringHelper\\:\\:localize\\(\\) expects array, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php + + - + message: "#^Parameter \\#1 \\$callback of function call_user_func expects callable\\(\\)\\: mixed, null given\\.$#" + count: 2 + path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php + + - + message: "#^Parameter \\#1 \\$entityName of method Doctrine\\\\ORM\\\\EntityManager\\:\\:getRepository\\(\\) expects class\\-string\\, string given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php + + - + message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:filterReachableCenters\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/AbstractTimelineAccompanyingPeriod.php + + - + message: "#^Parameter \\#3 \\$context of method Chill\\\\PersonBundle\\\\Timeline\\\\AbstractTimelineAccompanyingPeriod\\:\\:getBasicEntityTemplate\\(\\) expects string, Chill\\\\MainBundle\\\\Timeline\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodClosing.php + + - + message: "#^Parameter \\#3 \\$context of method Chill\\\\PersonBundle\\\\Timeline\\\\AbstractTimelineAccompanyingPeriod\\:\\:getBasicEntityTemplate\\(\\) expects string, Chill\\\\MainBundle\\\\Timeline\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Timeline/TimelineAccompanyingPeriodOpening.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelperInterface\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillPersonBundle/Widget/PersonListWidget.php + + - + message: "#^Parameter \\#1 \\$className of method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getRepository\\(\\) expects class\\-string\\, string given\\.$#" + count: 4 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Parameter \\#1 \\$entity of method Chill\\\\ReportBundle\\\\Controller\\\\ReportController\\:\\:createEditForm\\(\\) expects Chill\\\\ReportBundle\\\\Entity\\\\Report, ChillReportBundle\\:Report given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 4 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableScopes\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Controller/ReportController.php + + - + message: "#^Parameter \\#1 \\$em of class Chill\\\\MainBundle\\\\Form\\\\Type\\\\DataTransformer\\\\ScopeTransformer constructor expects Doctrine\\\\ORM\\\\EntityManagerInterface, Doctrine\\\\Persistence\\\\ObjectManager given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Form/ReportType.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableScopes\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Form/ReportType.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Search/ReportSearch.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableScopes\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Search/ReportSearch.php + + - + message: "#^Parameter \\#1 \\$context of method Chill\\\\ReportBundle\\\\Timeline\\\\TimelineReportProvider\\:\\:checkContext\\(\\) expects string, Chill\\\\MainBundle\\\\Timeline\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Parameter \\#1 \\$entity of method Chill\\\\ReportBundle\\\\Timeline\\\\TimelineReportProvider\\:\\:getFieldsToRender\\(\\) expects Chill\\\\ReportBundle\\\\Entity\\\\Report, Chill\\\\MainBundle\\\\Timeline\\\\type given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Parameter \\#1 \\$entityName of method Doctrine\\\\ORM\\\\EntityManager\\:\\:getRepository\\(\\) expects class\\-string\\, string given\\.$#" + count: 1 + path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 6 + path: src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Controller/TaskController.php + + - + message: "#^Parameter \\#1 \\$keys of function array_fill_keys expects array, Chill\\\\TaskBundle\\\\Entity\\\\json given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Entity/AbstractTask.php + + - + message: "#^Parameter \\#1 \\$task of method Chill\\\\TaskBundle\\\\Entity\\\\Task\\\\SingleTaskPlaceEvent\\:\\:setTask\\(\\) expects Chill\\\\TaskBundle\\\\Entity\\\\SingleTask, Chill\\\\TaskBundle\\\\Entity\\\\AbstractTask given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Event/Lifecycle/TaskLifecycleEvent.php + + - + message: "#^Parameter \\#1 \\$repository of class Chill\\\\PersonBundle\\\\Form\\\\DataTransformer\\\\PersonToIdTransformer constructor expects Chill\\\\PersonBundle\\\\Repository\\\\PersonRepository, Doctrine\\\\ORM\\\\EntityManagerInterface given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Form/SingleTaskListType.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 4 + path: src/Bundle/ChillTaskBundle/Form/SingleTaskListType.php + + - + message: "#^Parameter \\#1 \\$extras of method Knp\\\\Menu\\\\MenuItem\\:\\:setExtras\\(\\) expects array\\, string given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Menu/MenuBuilder.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Repository/SingleTaskRepository.php + + - + message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Security/Authorization/TaskVoter.php + + - + message: "#^Parameter \\#2 \\$role of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:getReachableCenters\\(\\) expects string, Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role given\\.$#" + count: 1 + path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php + + - + message: "#^Parameter \\#1 \\$storedObject of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getContent\\(\\) expects Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject, ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document given\\.$#" + count: 3 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Parameter \\#1 \\$storedObject of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:setContent\\(\\) expects Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject, ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document given\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php + + - + message: "#^Parameter \\#1 \\$type of method Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\:\\:setType\\(\\) expects string\\|null, false given\\.$#" + count: 1 + path: src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 20970a799..a89386f29 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Variable property access on \\$this\\(Chill\\\\ActivityBundle\\\\Entity\\\\ActivityType\\)\\.$#" - count: 3 - path: src/Bundle/ChillActivityBundle/Entity/ActivityType.php - - message: "#^Foreach overwrites \\$key with its key variable\\.$#" count: 1 @@ -20,11 +15,6 @@ parameters: count: 1 path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php - - - message: "#^Variable method call on object\\.$#" - count: 2 - path: src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php - - message: "#^Cannot unset offset '_token' on array\\{formatter\\: mixed, export\\: mixed, centers\\: mixed, alias\\: string\\}\\.$#" count: 1 @@ -50,46 +40,11 @@ parameters: count: 1 path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php - - - message: "#^Variable \\$message on left side of \\?\\? always exists and is not nullable\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/Templating/ChillTwigHelper.php - - - - message: "#^Variable \\$sqls on left side of \\?\\? always exists and is not nullable\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php - - - - message: "#^Class Chill\\\\PersonBundle\\\\Entity\\\\Person constructor invoked with 1 parameter, 0 required\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php - - - - message: "#^Variable \\$street1Value might not be defined\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php - - - - message: "#^Variable method call on mixed\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php - - message: "#^Foreach overwrites \\$value with its value variable\\.$#" count: 1 path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php - - - message: "#^Foreach overwrites \\$action with its value variable\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Repository/SocialWork/GoalRepository.php - - - - message: "#^Foreach overwrites \\$action with its value variable\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Repository/SocialWork/ResultRepository.php - - message: "#^Foreach overwrites \\$value with its value variable\\.$#" count: 1 diff --git a/phpstan-critical.neon b/phpstan-critical.neon index bfbb2dc7c..158c7384b 100644 --- a/phpstan-critical.neon +++ b/phpstan-critical.neon @@ -1,76 +1,6 @@ parameters: ignoreErrors: - - - message: "#^Implicit array creation is not allowed \\- variable \\$centers might not exist\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php - - - - message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Entity\\\\AccompanyingPeriod\\:\\:\\$work\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php - - - - message: "#^Undefined variable\\: \\$person$#" - count: 1 - path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php - - - - message: "#^Variable variables are not allowed\\.$#" - count: 4 - path: src/Bundle/ChillPersonBundle/Search/PersonSearch.php - - - - message: "#^Function Chill\\\\PersonBundle\\\\Serializer\\\\Normalizer\\\\·\\\\is_array not found\\.$#" - count: 1 - path: src/Bundle/ChillPersonBundle/Serializer/Normalizer/MembersEditorNormalizer.php - - - - message: "#^Undefined variable\\: \\$choiceSlug$#" - count: 1 - path: src/Bundle/ChillReportBundle/Export/Export/ReportList.php - - - - message: "#^Undefined variable\\: \\$type$#" - count: 1 - path: src/Bundle/ChillTaskBundle/Controller/TaskController.php - - - - message: "#^Call to an undefined method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:getRoleFor\\(\\)\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php - - message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Controller\\\\UserController\\:\\:createEditForm\\(\\)\\.$#" count: 1 path: src/Bundle/ChillMainBundle/Controller/UserController.php - - - - message: "#^Undefined variable\\: \\$current$#" - count: 1 - path: src/Bundle/ChillMainBundle/Pagination/PageGenerator.php - - - - message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AbstractChillVoter\\:\\:getSupportedAttributes\\(\\)\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php - - - - message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AbstractChillVoter\\:\\:getSupportedClasses\\(\\)\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php - - - - message: "#^Call to an undefined method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AbstractChillVoter\\:\\:isGranted\\(\\)\\.$#" - count: 1 - path: src/Bundle/ChillMainBundle/Security/Authorization/AbstractChillVoter.php - - - - message: "#^Access to an undefined property Chill\\\\PersonBundle\\\\Controller\\\\PersonController\\:\\:\\$security\\.$#" - count: 3 - path: src/Bundle/ChillPersonBundle/Controller/PersonController.php - - - - message: "#^Call to an undefined method Chill\\\\ThirdPartyBundle\\\\Form\\\\Type\\\\PickThirdPartyTypeCategoryType\\:\\:transform\\(\\)\\.$#" - count: 1 - path: src/Bundle/ChillThirdPartyBundle/Form/Type/PickThirdPartyTypeCategoryType.php diff --git a/phpstan-deprecations.neon b/phpstan-deprecations.neon index aa8506411..c83feeb59 100644 --- a/phpstan-deprecations.neon +++ b/phpstan-deprecations.neon @@ -32,14 +32,6 @@ parameters: path: src/Bundle/ChillActivityBundle/Form/ActivityType.php - - - message: """ - #^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\: - since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$# - """ - count: 1 - path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php - - message: """ #^Parameter \\$centerResolverDispatcher of method Chill\\\\ActivityBundle\\\\Repository\\\\ActivityACLAwareRepository\\:\\:__construct\\(\\) has typehint with deprecated interface Chill\\\\MainBundle\\\\Security\\\\Resolver\\\\CenterResolverDispatcherInterface\\: @@ -199,14 +191,6 @@ parameters: count: 2 path: src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLanguages.php - - - message: """ - #^Class Chill\\\\MainBundle\\\\Entity\\\\User implements deprecated interface Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\AdvancedUserInterface\\: - since Symfony 4\\.1$# - """ - count: 1 - path: src/Bundle/ChillMainBundle/Entity/User.php - - message: """ #^Return type of method Chill\\\\MainBundle\\\\Entity\\\\User\\:\\:getRoles\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\: @@ -329,22 +313,6 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Actions/ActionEvent.php - - - message: """ - #^Call to deprecated method getCurrentAccompanyingPeriod\\(\\) of class Chill\\\\PersonBundle\\\\Entity\\\\Person\\: - since 1\\.1 use `getOpenedAccompanyingPeriod instead$# - """ - count: 1 - path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php - - - - message: """ - #^Instantiation of deprecated class Symfony\\\\Component\\\\EventDispatcher\\\\Event\\: - since Symfony 4\\.3, use "Symfony\\\\Contracts\\\\EventDispatcher\\\\Event" instead$# - """ - count: 1 - path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php - - message: """ #^Class Chill\\\\PersonBundle\\\\Controller\\\\AccompanyingCourseController extends deprecated class Symfony\\\\Bundle\\\\FrameworkBundle\\\\Controller\\\\Controller\\: @@ -541,11 +509,3 @@ parameters: count: 3 path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php - - - message: """ - #^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\: - since Symfony 4\\.3, to be removed in 5\\.0\\. Use strings as roles instead\\.$# - """ - count: 1 - path: src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php - diff --git a/phpstan-types.neon b/phpstan-types.neon index 1aae06880..3368c94d2 100644 --- a/phpstan-types.neon +++ b/phpstan-types.neon @@ -100,11 +100,6 @@ parameters: count: 1 path: src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php - - - message: "#^Method Chill\\\\EventBundle\\\\Entity\\\\Participation\\:\\:offsetGet\\(\\) should return mixed but return statement is missing\\.$#" - count: 1 - path: src/Bundle/ChillEventBundle/Entity/Participation.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 1 @@ -315,11 +310,6 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Command/ChillPersonMoveCommand.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 6 - path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" count: 1 @@ -340,21 +330,11 @@ parameters: count: 1 path: src/Bundle/ChillPersonBundle/Form/Type/PersonPhoneType.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 3 - path: src/Bundle/ChillPersonBundle/Search/PersonSearch.php - - message: "#^Method Chill\\\\PersonBundle\\\\Search\\\\PersonSearch\\:\\:renderResult\\(\\) should return string but return statement is missing\\.$#" count: 1 path: src/Bundle/ChillPersonBundle/Search/PersonSearch.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 2 - path: src/Bundle/ChillPersonBundle/Templating/Entity/ClosingMotiveRender.php - - message: "#^Method Chill\\\\ReportBundle\\\\DataFixtures\\\\ORM\\\\LoadReports\\:\\:getRandomChoice\\(\\) should return array\\\\|string but return statement is missing\\.$#" count: 1 @@ -400,16 +380,6 @@ parameters: count: 1 path: src/Bundle/ChillTaskBundle/Timeline/TaskLifeCycleEventTimelineProvider.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 1 - path: src/Bundle/ChillThirdPartyBundle/Form/ChoiceLoader/ThirdPartyChoiceLoader.php - - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 1 - path: src/Bundle/ChillThirdPartyBundle/Repository/ThirdPartyRepository.php - - message: "#^Method Chill\\\\ThirdPartyBundle\\\\Search\\\\ThirdPartySearch\\:\\:renderResult\\(\\) should return string but return statement is missing\\.$#" count: 1 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3322f9539..56b7c2228 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,7 +1,9 @@ parameters: - level: 1 + level: 5 paths: - src/ + tmpDir: .cache/ + reportUnmatchedIgnoredErrors: false excludePaths: - .php_cs* - docs/ @@ -24,4 +26,8 @@ includes: - phpstan-critical.neon - phpstan-deprecations.neon - phpstan-types.neon + - phpstan-baseline-level-2.neon + - phpstan-baseline-level-3.neon + - phpstan-baseline-level-4.neon + - phpstan-baseline-level-5.neon diff --git a/psalm.xml b/psalm.xml index 40e5d78e8..77193f05b 100644 --- a/psalm.xml +++ b/psalm.xml @@ -9,9 +9,10 @@ cacheDirectory="./.psalm" > - + - + + @@ -20,9 +21,27 @@ - + + + + + + + diff --git a/rector.php b/rector.php new file mode 100644 index 000000000..ec9a0c684 --- /dev/null +++ b/rector.php @@ -0,0 +1,60 @@ +paths([ + __DIR__ . '/docs', + __DIR__ . '/src', + ]); + + //$rectorConfig->cacheClass(\Rector\Caching\ValueObject\Storage\FileCacheStorage::class); + //$rectorConfig->cacheDirectory(__DIR__ . '/.cache/rector'); + + // register a single rule + $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); + $rectorConfig->disableParallel(); + + //define sets of rules + $rectorConfig->sets([ + LevelSetList::UP_TO_PHP_74 + ]); + + // skip some path... + $rectorConfig->skip([ + // make rector stuck for some files + \Rector\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector::class, + + // we need to discuss this: are we going to have FALSE in tests instead of an error ? + \Rector\Php71\Rector\FuncCall\CountOnNullRector::class, + + // must merge MR500 and review a typing of "ArrayCollection" in entities + \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class, + + // remove all PHP80 rules, in order to activate them one by one + \Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector::class, + \Rector\Php80\Rector\Class_\AnnotationToAttributeRector::class, + \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class, + \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class, + \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class, + \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class, + \Rector\Php80\Rector\Class_\DoctrineAnnotationClassToAttributeRector::class, + \Rector\Php80\Rector\ClassMethod\FinalPrivateToPrivateVisibilityRector::class, + \Rector\Php80\Rector\Ternary\GetDebugTypeRector::class, + \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class, + \Rector\Php80\Rector\Property\NestedAnnotationToAttributeRector::class, + \Rector\Php80\Rector\FuncCall\Php8ResourceReturnToObjectRector::class, + \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class, + \Rector\Php80\Rector\ClassMethod\SetStateToStaticRector::class, + \Rector\Php80\Rector\NotIdentical\StrContainsRector::class, + \Rector\Php80\Rector\Identical\StrEndsWithRector::class, + \Rector\Php80\Rector\Identical\StrStartsWithRector::class, + \Rector\Php80\Rector\Class_\StringableForToStringRector::class, + \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class, + \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class + ]); +}; diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 11db2dcb3..97678af50 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -41,8 +41,8 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use function array_key_exists; final class ActivityController extends AbstractController @@ -73,6 +73,8 @@ final class ActivityController extends AbstractController private ThirdPartyRepository $thirdPartyRepository; + private TranslatorInterface $translator; + private UserRepositoryInterface $userRepository; public function __construct( @@ -89,7 +91,8 @@ final class ActivityController extends AbstractController LoggerInterface $logger, SerializerInterface $serializer, UserRepositoryInterface $userRepository, - CenterResolverManagerInterface $centerResolver + CenterResolverManagerInterface $centerResolver, + TranslatorInterface $translator ) { $this->activityACLAwareRepository = $activityACLAwareRepository; $this->activityTypeRepository = $activityTypeRepository; @@ -105,6 +108,7 @@ final class ActivityController extends AbstractController $this->serializer = $serializer; $this->userRepository = $userRepository; $this->centerResolver = $centerResolver; + $this->translator = $translator; } /** @@ -160,7 +164,7 @@ final class ActivityController extends AbstractController $this->entityManager->remove($activity); $this->entityManager->flush(); - $this->addFlash('success', $this->get('translator') + $this->addFlash('success', $this->translator ->trans('The activity has been successfully removed.')); $params = $this->buildParamsToUrl($person, $accompanyingPeriod); @@ -208,7 +212,7 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null, - 'role' => new Role('CHILL_ACTIVITY_UPDATE'), + 'role' => 'CHILL_ACTIVITY_UPDATE', 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ]); @@ -245,7 +249,7 @@ final class ActivityController extends AbstractController ); } - $this->addFlash('success', $this->get('translator')->trans('Success : activity updated!')); + $this->addFlash('success', $this->translator->trans('Success : activity updated!')); return $this->redirectToRoute('chill_activity_activity_show', $params); } @@ -363,6 +367,7 @@ final class ActivityController extends AbstractController if ($person instanceof Person) { $entity->setPerson($person); + $entity->getPersons()->add($person); } if ($accompanyingPeriod instanceof AccompanyingPeriod) { @@ -436,7 +441,7 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null, - 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'role' => 'CHILL_ACTIVITY_CREATE', 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ]); @@ -472,7 +477,7 @@ final class ActivityController extends AbstractController ); } - $this->addFlash('success', $this->get('translator')->trans('Success : activity created!')); + $this->addFlash('success', $this->translator->trans('Success : activity created!')); $params = $this->buildParamsToUrl($person, $accompanyingPeriod); @@ -645,8 +650,8 @@ final class ActivityController extends AbstractController throw $this->createNotFoundException('Accompanying Period not found'); } - // TODO Add permission - // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); + // TODO Add permission + // $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); } else { throw $this->createNotFoundException('Person or Accompanying Period not found'); } diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php index 6af42a53c..95a49d0ba 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php @@ -13,15 +13,24 @@ namespace Chill\ActivityBundle\Controller; use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Form\ActivityReasonType; +use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * ActivityReason controller. */ class ActivityReasonController extends AbstractController { + private ActivityReasonRepository $activityReasonRepository; + + public function __construct(ActivityReasonRepository $activityReasonRepository) + { + $this->activityReasonRepository = $activityReasonRepository; + } + /** * Creates a new ActivityReason entity. */ @@ -56,8 +65,8 @@ class ActivityReasonController extends AbstractController $entity = $em->getRepository(\Chill\ActivityBundle\Entity\ActivityReason::class)->find($id); - if (!$entity) { - throw $this->createNotFoundException('Unable to find ActivityReason entity.'); + if (null === $entity) { + throw new NotFoundHttpException('Unable to find ActivityReason entity.'); } $editForm = $this->createEditForm($entity); @@ -75,7 +84,7 @@ class ActivityReasonController extends AbstractController { $em = $this->getDoctrine()->getManager(); - $entities = $em->getRepository(\Chill\ActivityBundle\Entity\ActivityReason::class)->findAll(); + $entities = $this->activityReasonRepository->findAll(); return $this->render('ChillActivityBundle:ActivityReason:index.html.twig', [ 'entities' => $entities, diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php index 8c53ca2d9..82949d635 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php @@ -50,7 +50,7 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface ->findAll(); foreach ($persons as $person) { - $activityNbr = mt_rand(0, 3); + $activityNbr = random_int(0, 3); for ($i = 0; $i < $activityNbr; ++$i) { $activity = $this->newRandomActivity($person); @@ -75,7 +75,7 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface // ->setAttendee($this->faker->boolean()) - for ($i = 0; mt_rand(0, 4) > $i; ++$i) { + for ($i = 0; random_int(0, 4) > $i; ++$i) { $reason = $this->getRandomActivityReason(); if (null !== $reason) { diff --git a/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php index e22f6242c..57a1ec578 100644 --- a/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php @@ -26,7 +26,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_activity'); - $rootNode = $treeBuilder->getRootNode('chill_activity'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() @@ -59,9 +59,7 @@ class Configuration implements ConfigurationInterface ->info('The number of seconds of this duration. Must be an integer.') ->cannotBeEmpty() ->validate() - ->ifTrue(static function ($data) { - return !is_int($data); - })->thenInvalid('The value %s is not a valid integer') + ->ifTrue(static fn ($data) => !is_int($data))->thenInvalid('The value %s is not a valid integer') ->end() ->end() ->scalarNode('label') diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 8fcae3e0b..32ceb2e74 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -195,7 +195,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") * @Groups({"docgen:read"}) */ - private User $user; + private ?User $user = null; /** * @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User") @@ -257,12 +257,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * Add a social issue. * - * Note: the social issue consistency (the fact that only yougest social issues + * Note: the social issue consistency (the fact that only youngest social issues * are kept) is processed by an entity listener: * * @see{\Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodSocialIssueConsistencyEntityListener} - * - * @return $this */ public function addSocialIssue(SocialIssue $socialIssue): self { @@ -270,6 +268,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac $this->socialIssues[] = $socialIssue; } + if ($this->getAccompanyingPeriod() !== null) { + $this->getAccompanyingPeriod()->addSocialIssue($socialIssue); + } + return $this; } @@ -492,7 +494,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this->activityType; } - public function getUser(): User + public function getUser(): ?User { return $this->user; } @@ -550,6 +552,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $this->accompanyingPeriod = $accompanyingPeriod; + foreach ($this->getSocialIssues() as $issue) { + $this->accompanyingPeriod->addSocialIssue($issue); + } + return $this; } @@ -675,14 +681,14 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this; } - public function setUser(UserInterface $user): self + public function setUser(?User $user): self { $this->user = $user; return $this; } - public function setUsers(?Collection $users): self + public function setUsers(Collection $users): self { $this->users = $users; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php index 95b3c95d2..b0154e509 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php @@ -34,7 +34,7 @@ class ActivityPresence * @ORM\GeneratedValue(strategy="AUTO") * @Serializer\Groups({"docgen:read"}) */ - private ?int $id; + private ?int $id = null; /** * @ORM\Column(type="json") diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php index c0cc21209..e6da6b7e0 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php @@ -63,10 +63,8 @@ class ActivityReason /** * Get category. - * - * @return ActivityReasonCategory */ - public function getCategory() + public function getCategory(): ?ActivityReasonCategory { return $this->category; } @@ -107,6 +105,11 @@ class ActivityReason return $this->name; } + public function isActiveAndParentActive(): bool + { + return $this->active && null !== $this->getCategory() && $this->getCategory()->getActive(); + } + /** * Set active. * diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index 1f44a1af0..ed8260a4d 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -122,7 +122,7 @@ class ActivityType * @ORM\GeneratedValue(strategy="AUTO") * @Groups({"docgen:read"}) */ - private ?int $id; + private ?int $id = null; /** * @ORM\Column(type="string", nullable=false, options={"default": ""}) @@ -380,6 +380,7 @@ class ActivityType throw new InvalidArgumentException('Field "' . $field . '" not found'); } + /** @phpstan-ignore-next-line */ return $this->{$property}; } @@ -538,6 +539,7 @@ class ActivityType throw new InvalidArgumentException('Field "' . $field . '" not found'); } + /** @phpstan-ignore-next-line */ return self::FIELD_REQUIRED === $this->{$property}; } @@ -549,6 +551,7 @@ class ActivityType throw new InvalidArgumentException('Field "' . $field . '" not found'); } + /** @phpstan-ignore-next-line */ return self::FIELD_INVISIBLE !== $this->{$property}; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php index c09685e4e..69149737b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByCreatorAggregator.php @@ -60,7 +60,7 @@ class ByCreatorAggregator implements AggregatorInterface return 'Created by'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index 58c824adc..89732412d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -65,7 +65,7 @@ class BySocialActionAggregator implements AggregatorInterface return 'Social action'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index fe07fd23f..158e87664 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -65,7 +65,7 @@ class BySocialIssueAggregator implements AggregatorInterface return 'Social issues'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php index 5eab4cae3..c3ca6d59c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByThirdpartyAggregator.php @@ -65,7 +65,7 @@ class ByThirdpartyAggregator implements AggregatorInterface return 'Accepted thirdparty'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php index 2041fcbb4..2c7ec1483 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/CreatorScopeAggregator.php @@ -65,7 +65,7 @@ class CreatorScopeAggregator implements AggregatorInterface return 'Scope'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php index dbbeb2715..b4b23dc0b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/DateAggregator.php @@ -58,7 +58,8 @@ class DateAggregator implements AggregatorInterface break; case 'year': - $fmt = 'YYYY'; $order = 'DESC'; + $fmt = 'YYYY'; + $order = 'DESC'; break; // order DESC does not works ! diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php index b648fcf83..ec4ce6315 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/LocationTypeAggregator.php @@ -65,11 +65,13 @@ class LocationTypeAggregator implements AggregatorInterface return 'Accepted locationtype'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } - $lt = $this->locationTypeRepository->find($value); + if (null === $lt = $this->locationTypeRepository->find($value)) { + return ''; + } return $this->translatableStringHelper->localize( $lt->getTitle() diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index 071ccd232..7cd16718e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -71,7 +71,7 @@ class ActivityTypeAggregator implements AggregatorInterface return 'Activity type'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 2b1ac57b5..9bde692c6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -66,7 +66,7 @@ class ActivityUserAggregator implements AggregatorInterface return 'Activity user'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php index ccccc48a0..139f2743e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php @@ -64,7 +64,7 @@ class ActivityUsersAggregator implements AggregatorInterface return 'Activity users'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php index a0a6a439b..5741a0e58 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php @@ -63,7 +63,7 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI return 'Users \'s job'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php index 975c5df27..15da300be 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php @@ -63,7 +63,7 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato return 'Users \'s scope'; } - if (null === $value) { + if (null === $value || '' === $value) { return ''; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index bfd785554..eaccf95cb 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -134,6 +134,10 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali return 'reasons' === $data['level'] ? 'Group by reasons' : 'Group by categories of reason'; } + if (null === $value || '' === $value) { + return ''; + } + switch ($data['level']) { case 'reasons': $r = $this->activityReasonRepository->find($value); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index 7d77a7c69..5f772e156 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -57,6 +57,7 @@ class SentReceivedAggregator implements AggregatorInterface switch ($value) { case null: + case '': return ''; case 'sent': diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index 2b6919340..34771d077 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -86,9 +86,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->repository->createQueryBuilder('activity'); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index 359593059..df21362cd 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -87,9 +87,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->repository->createQueryBuilder('activity'); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index 2dc844aa2..6b7b1562d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -86,9 +86,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->repository ->createQueryBuilder('activity') diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php index 77444e414..026e16f90 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php @@ -73,7 +73,7 @@ class ListActivity implements ListInterface, GroupedExportInterface }; case 'scopesNames': - return $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, ListActivityHelper::MSG_KEY . 'course circles'); + return $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, ListActivityHelper::MSG_KEY . 'course circles'); default: return $this->helper->getLabels($key, $values, $data); @@ -109,9 +109,7 @@ class ListActivity implements ListInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->entityManager->createQueryBuilder(); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index 1cf20dc5f..e916cab54 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -87,9 +87,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->repository ->createQueryBuilder('activity') diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index 2c160f3cf..18a47289c 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -87,9 +87,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->repository ->createQueryBuilder('activity') diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index 5d438d3a5..60110c9a8 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -137,13 +137,11 @@ class ListActivity implements ListInterface, GroupedExportInterface $activity = $activityRepository->find($value); - return implode(', ', array_map(function (ActivityReason $r) { - return '"' . - $this->translatableStringHelper->localize($r->getCategory()->getName()) - . ' > ' . - $this->translatableStringHelper->localize($r->getName()) - . '"'; - }, $activity->getReasons()->toArray())); + return implode(', ', array_map(fn (ActivityReason $r) => '"' . + $this->translatableStringHelper->localize($r->getCategory()->getName()) + . ' > ' . + $this->translatableStringHelper->localize($r->getName()) + . '"', $activity->getReasons()->toArray())); }; case 'circle_name': @@ -152,7 +150,7 @@ class ListActivity implements ListInterface, GroupedExportInterface return 'circle'; } - return $this->translatableStringHelper->localize(json_decode($value, true)); + return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); }; case 'type_name': @@ -161,7 +159,7 @@ class ListActivity implements ListInterface, GroupedExportInterface return 'activity type'; } - return $this->translatableStringHelper->localize(json_decode($value, true)); + return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); }; default: @@ -197,9 +195,7 @@ class ListActivity implements ListInterface, GroupedExportInterface public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); // throw an error if any fields are present if (!array_key_exists('fields', $data)) { diff --git a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php index 0e8b28ab4..fae6ea6a6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php @@ -179,7 +179,7 @@ class ListActivityHelper } } - $decoded = json_decode($value); + $decoded = json_decode($value, null, 512, JSON_THROW_ON_ERROR); return implode( '|', diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index 575d11815..c6616a4c6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -17,11 +17,9 @@ use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Export\Declarations; -use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class ActivityTypeFilter implements FilterInterface { @@ -44,14 +42,13 @@ class ActivityTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('activity', $qb->getAllAliases(), true)) { - $qb->join(Activity::class, 'activity', Expr\Join::WITH, 'activity.accompanyingPeriod = acp'); - } - - $clause = $qb->expr()->in('activity.activityType', ':selected_activity_types'); - - $qb->andWhere($clause); - $qb->setParameter('selected_activity_types', $data['types']); + $qb->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . Activity::class . ' act_type_filter_activity + WHERE act_type_filter_activity.activityType IN (:act_type_filter_activity_types) AND act_type_filter_activity.accompanyingPeriod = acp' + ) + ); + $qb->setParameter('act_type_filter_activity_types', $data['accepted_activitytypes']); } public function applyOn() @@ -64,12 +61,9 @@ class ActivityTypeFilter implements FilterInterface $builder->add('accepted_activitytypes', EntityType::class, [ 'class' => ActivityType::class, 'choices' => $this->activityTypeRepository->findAllActive(), - 'choice_label' => function (ActivityType $aty) { - return - ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') - . - $this->translatableStringHelper->localize($aty->getName()); - }, + 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + . + $this->translatableStringHelper->localize($aty->getName()), 'multiple' => true, 'expanded' => true, ]); diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php new file mode 100644 index 000000000..3d69d1633 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php @@ -0,0 +1,67 @@ +andWhere( + $qb->expr()->in('activity.location', ':location') + ); + + $qb->setParameter('location', $data['accepted_location']); + } + + public function applyOn(): string + { + return Declarations::ACTIVITY_ACP; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_location', PickUserLocationType::class, [ + 'multiple' => true, + 'label' => 'pick location', + ]); + } + + public function describeAction($data, $format = 'string'): array + { + $locations = []; + + foreach ($data['accepted_location'] as $location) { + $locations[] = $location->getName(); + } + + return ['Filtered activity by location: only %locations%', [ + '%locations%' => implode(', ', $locations), + ]]; + } + + public function getTitle(): string + { + return 'Filter activity by location'; + } +} diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php index 1906db75e..4319c100a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/UserScopeFilter.php @@ -64,11 +64,9 @@ class UserScopeFilter implements FilterInterface { $builder->add('accepted_userscope', EntityType::class, [ 'class' => Scope::class, - 'choice_label' => function (Scope $s) { - return $this->translatableStringHelper->localize( - $s->getName() - ); - }, + 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( + $s->getName() + ), 'multiple' => true, 'expanded' => true, ]); diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index d1758039a..b9d39c3ce 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -61,12 +61,9 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter $builder->add('types', EntityType::class, [ 'choices' => $this->activityTypeRepository->findAllActive(), 'class' => ActivityType::class, - 'choice_label' => function (ActivityType $aty) { - return - ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') - . - $this->translatableStringHelper->localize($aty->getName()); - }, + 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + . + $this->translatableStringHelper->localize($aty->getName()), 'group_by' => function (ActivityType $type) { if (!$type->hasCategory()) { return null; diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php b/src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php index b8e03d2c7..3a0f2a318 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityReasonCategoryType.php @@ -32,7 +32,7 @@ class ActivityReasonCategoryType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\ActivityBundle\Entity\ActivityReasonCategory', + 'data_class' => \Chill\ActivityBundle\Entity\ActivityReasonCategory::class, ]); } diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityReasonType.php b/src/Bundle/ChillActivityBundle/Form/ActivityReasonType.php index 84a3e08ed..f47a101bd 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityReasonType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityReasonType.php @@ -11,7 +11,8 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Form; -use Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategory; +use Chill\ActivityBundle\Entity\ActivityReason; +use Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategoryType; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; @@ -25,13 +26,13 @@ class ActivityReasonType extends AbstractType $builder ->add('name', TranslatableStringFormType::class) ->add('active', CheckboxType::class, ['required' => false]) - ->add('category', TranslatableActivityReasonCategory::class); + ->add('category', TranslatableActivityReasonCategoryType::class); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\ActivityBundle\Entity\ActivityReason', + 'data_class' => ActivityReason::class, ]); } diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityType.php b/src/Bundle/ChillActivityBundle/Form/ActivityType.php index cabfc0e76..a74178afd 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityType.php @@ -13,7 +13,7 @@ namespace Chill\ActivityBundle\Form; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityPresence; -use Chill\ActivityBundle\Entity\ActivityReason; +use Chill\ActivityBundle\Form\Type\PickActivityReasonType; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\DocStoreBundle\Form\StoredObjectType; use Chill\MainBundle\Entity\Center; @@ -211,13 +211,9 @@ class ActivityType extends AbstractType 'required' => $activityType->isRequired('attendee'), 'expanded' => true, 'class' => ActivityPresence::class, - 'choice_label' => function (ActivityPresence $activityPresence) { - return $this->translatableStringHelper->localize($activityPresence->getName()); - }, - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('a') - ->where('a.active = true'); - }, + 'choice_label' => fn (ActivityPresence $activityPresence) => $this->translatableStringHelper->localize($activityPresence->getName()), + 'query_builder' => static fn (EntityRepository $er) => $er->createQueryBuilder('a') + ->where('a.active = true'), ]); } @@ -225,23 +221,15 @@ class ActivityType extends AbstractType $builder->add('user', PickUserDynamicType::class, [ 'label' => $activityType->getLabel('user'), 'required' => $activityType->isRequired('user'), + 'multiple' => false, ]); } if ($activityType->isVisible('reasons')) { - $builder->add('reasons', EntityType::class, [ + $builder->add('reasons', PickActivityReasonType::class, [ 'label' => $activityType->getLabel('reasons'), 'required' => $activityType->isRequired('reasons'), - 'class' => ActivityReason::class, 'multiple' => true, - 'choice_label' => function (ActivityReason $activityReason) { - return $this->translatableStringHelper->localize($activityReason->getName()); - }, - 'attr' => ['class' => 'select2 '], - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('a') - ->where('a.active = true'); - }, ]); } @@ -365,9 +353,7 @@ class ActivityType extends AbstractType return (string) $location->getId(); }, - function (?string $id): ?Location { - return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]); - } + fn (?string $id): ?Location => $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]) )); } @@ -409,9 +395,7 @@ class ActivityType extends AbstractType // the datetimetransformer will then handle timezone as GMT $timezoneUTC = new DateTimeZone('GMT'); /** @var DateTime $data */ - $data = $formEvent->getData() === null ? - DateTime::createFromFormat('U', '300') : - $formEvent->getData(); + $data = $formEvent->getData() ?? DateTime::createFromFormat('U', '300'); $seconds = $data->getTimezone()->getOffset($data); $data->setTimeZone($timezoneUTC); $data->add(new DateInterval('PT' . $seconds . 'S')); diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php index b27fa883e..073b8099f 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php @@ -45,9 +45,7 @@ class ActivityTypeType extends AbstractType ]) ->add('category', EntityType::class, [ 'class' => ActivityTypeCategory::class, - 'choice_label' => function (ActivityTypeCategory $activityTypeCategory) { - return $this->translatableStringHelper->localize($activityTypeCategory->getName()); - }, + 'choice_label' => fn (ActivityTypeCategory $activityTypeCategory) => $this->translatableStringHelper->localize($activityTypeCategory->getName()), ]) ->add('ordering', NumberType::class, [ 'required' => true, diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReason.php b/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php similarity index 62% rename from src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReason.php rename to src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php index d8ac89963..35da7e02f 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReason.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php @@ -12,9 +12,9 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Form\Type; use Chill\ActivityBundle\Entity\ActivityReason; +use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\ActivityBundle\Templating\Entity\ActivityReasonRender; -use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\EntityRepository; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -22,34 +22,30 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** * FormType to choose amongst activity reasons. */ -class TranslatableActivityReason extends AbstractType +class PickActivityReasonType extends AbstractType { - /** - * @var ActivityReasonRender - */ - protected $reasonRender; + private ActivityReasonRepository $activityReasonRepository; - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; + private ActivityReasonRender $reasonRender; + + private TranslatableStringHelperInterface $translatableStringHelper; public function __construct( - TranslatableStringHelper $translatableStringHelper, - ActivityReasonRender $reasonRender + ActivityReasonRepository $activityReasonRepository, + ActivityReasonRender $reasonRender, + TranslatableStringHelperInterface $translatableStringHelper ) { - $this->translatableStringHelper = $translatableStringHelper; + $this->activityReasonRepository = $activityReasonRepository; $this->reasonRender = $reasonRender; + $this->translatableStringHelper = $translatableStringHelper; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults( [ - 'class' => 'ChillActivityBundle:ActivityReason', - 'choice_label' => function (ActivityReason $choice) { - return $this->reasonRender->renderString($choice, []); - }, + 'class' => ActivityReason::class, + 'choice_label' => fn (ActivityReason $choice) => $this->reasonRender->renderString($choice, []), 'group_by' => function (ActivityReason $choice): ?string { if (null !== $category = $choice->getCategory()) { return $this->translatableStringHelper->localize($category->getName()); @@ -57,10 +53,7 @@ class TranslatableActivityReason extends AbstractType return null; }, - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('r') - ->where('r.active = true'); - }, + 'choices' => $this->activityReasonRepository->findAll(), 'attr' => ['class' => ' select2 '], ] ); diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategory.php b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategory.php deleted file mode 100644 index bac4822e6..000000000 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategory.php +++ /dev/null @@ -1,59 +0,0 @@ -requestStack = $requestStack; - } - - public function configureOptions(OptionsResolver $resolver) - { - $locale = $this->requestStack->getCurrentRequest()->getLocale(); - $resolver->setDefaults( - [ - 'class' => 'ChillActivityBundle:ActivityReasonCategory', - 'choice_label' => 'name[' . $locale . ']', - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('c') - ->where('c.active = true'); - }, - ] - ); - } - - public function getBlockPrefix() - { - return 'translatable_activity_reason_category'; - } - - public function getParent() - { - return EntityType::class; - } -} diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php new file mode 100644 index 000000000..4aa259097 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php @@ -0,0 +1,56 @@ +translatableStringHelper = $translatableStringHelper; + $this->translator = $translator; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults( + [ + 'class' => ActivityReasonCategory::class, + 'choice_label' => fn (ActivityReasonCategory $category) => $this->translatableStringHelper->localize($category->getName()) + . (!$category->getActive() ? ' (' . $this->translator->trans('inactive') . ')' : ''), + ] + ); + } + + public function getBlockPrefix() + { + return 'translatable_activity_reason_category'; + } + + public function getParent() + { + return EntityType::class; + } +} diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php index 4a1d4bfa7..d4807b82d 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php @@ -39,9 +39,7 @@ class TranslatableActivityType extends AbstractType 'class' => ActivityType::class, 'active_only' => true, 'choices' => $this->activityTypeRepository->findAllActive(), - 'choice_label' => function (ActivityType $type) { - return $this->translatableStringHelper->localize($type->getName()); - }, + 'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()), ] ); } diff --git a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php index a177a717c..9884450ec 100644 --- a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -18,6 +18,9 @@ use Knp\Menu\MenuItem; use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; +/** + * @implements LocalMenuBuilderInterface + */ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface { protected Security $security; diff --git a/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php index 5e10c9a14..4b2d348d7 100644 --- a/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php @@ -15,6 +15,9 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Knp\Menu\MenuItem; use Symfony\Component\Security\Core\Security; +/** + * @implements LocalMenuBuilderInterface + */ final class AdminMenuBuilder implements LocalMenuBuilderInterface { private Security $security; @@ -36,7 +39,6 @@ final class AdminMenuBuilder implements LocalMenuBuilderInterface ->setAttribute('class', 'list-group-item-header') ->setExtras([ 'order' => 5000, - 'icons' => ['exchange'], ]); $menu->addChild('Activity Reasons', [ diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php index 89dff9b2b..03a1b09ab 100644 --- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php @@ -13,11 +13,15 @@ namespace Chill\ActivityBundle\Menu; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; +use Chill\PersonBundle\Entity\Person; use Knp\Menu\MenuItem; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Contracts\Translation\TranslatorInterface; -class PersonMenuBuilder implements LocalMenuBuilderInterface +/** + * @implements LocalMenuBuilderInterface + */ +final class PersonMenuBuilder implements LocalMenuBuilderInterface { /** * @var AuthorizationCheckerInterface @@ -44,7 +48,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) { $menu->addChild( - $this->translator->trans('Activity list'), + $this->translator->trans('Activities'), [ 'route' => 'chill_activity_activity_list', 'routeParameters' => ['person_id' => $person->getId()], diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php index fa36c8d07..1f2039a2c 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php @@ -225,10 +225,9 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte $personToCenter = $metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name']; // acls: - $role = new Role(ActivityVoter::SEE); $reachableCenters = $this->authorizationHelper->getReachableCenters( $this->tokenStorage->getToken()->getUser(), - $role + ActivityVoter::SEE ); if (count($reachableCenters) === 0) { @@ -239,7 +238,7 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte if ('person' === $context) { // we start with activities having the person_id linked to person $where .= sprintf('%s = ? AND ', $activityToPerson); - $parameters[] = $person->getId(); + $parameters[] = $args['context']->getId(); } // we add acl (reachable center and scopes) @@ -252,12 +251,10 @@ final class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInte continue; } // we get all the reachable scopes for this center - $reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), $role, $center); + $reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), ActivityVoter::SEE, $center); // we get the ids for those scopes $reachablesScopesId = array_map( - static function (Scope $scope) { - return $scope->getId(); - }, + static fn (Scope $scope) => $scope->getId(), $reachableScopes ); diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php index 275c49b2c..c6b69319e 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php @@ -14,17 +14,38 @@ namespace Chill\ActivityBundle\Repository; use Chill\ActivityBundle\Entity\ActivityReason; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Component\HttpFoundation\RequestStack; /** * @method ActivityReason|null find($id, $lockMode = null, $lockVersion = null) * @method ActivityReason|null findOneBy(array $criteria, array $orderBy = null) - * @method ActivityReason[] findAll() * @method ActivityReason[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class ActivityReasonRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) - { + private RequestStack $requestStack; + + public function __construct( + ManagerRegistry $registry, + RequestStack $requestStack + ) { parent::__construct($registry, ActivityReason::class); + + $this->requestStack = $requestStack; + } + + /** + * @return ActivityReason[] + */ + public function findAll(): array + { + $qb = $this->createQueryBuilder('ar'); + $qb->select(['ar']) + ->leftJoin('ar.category', 'category') + ->addOrderBy('JSON_EXTRACT(category.name, :lang)') + ->addOrderBy('JSON_EXTRACT(ar.name, :lang)') + ->setParameter('lang', $this->requestStack->getCurrentRequest()->getLocale() ?? 'fr'); + + return $qb->getQuery()->getResult(); } } diff --git a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss index 5c1c83d06..d70bd28c3 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss +++ b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss @@ -88,3 +88,11 @@ div.flex-bloc.concerned-groups { font-size: 120%; } } + +/// DOCUMENT LIST IN ACTIVITY ITEM +li.document-list-item { + display: flex; + width: 100%; + justify-content: space-between; + margin-bottom: 0.3rem; +} diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 6a6289875..568c8747a 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -117,7 +117,8 @@ export default { target: { //name, id }, edit: false, - addressId: null + addressId: null, + defaults: window.addaddress } } } diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index ca56a5dae..9f710abeb 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -30,7 +30,7 @@ const store = createStore({ }, getters: { suggestedEntities(state) { - if (typeof state.activity.accompanyingPeriod === "undefined") { + if (typeof state.activity.accompanyingPeriod === "undefined" || state.activity.accompanyingPeriod === null) { return []; } const allEntities = [ diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.locations.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.locations.js index 056dc129d..7a216f628 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.locations.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.locations.js @@ -39,6 +39,9 @@ const makeConcernedThirdPartiesLocation = (locationType, store) => { return locations; }; const makeAccompanyingPeriodLocation = (locationType, store) => { + if (store.state.activity.accompanyingPeriod === null) { + return {}; + } const accPeriodLocation = store.state.activity.accompanyingPeriod.location; return { type: 'location', diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig index 3a4749f3c..8d1aba2b3 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig @@ -63,12 +63,12 @@ {% endif %} - {% if activity.user and t.userVisible %} + {% if activity.user is not null and t.userVisible %}

{{ 'Referrer'|trans }}

- {{ activity.user|chill_entity_render_box }} + {{ activity.user|chill_entity_render_box }}

@@ -137,19 +137,42 @@ {{ activity.comment|chill_entity_render_box({ 'disable_markdown': false, 'limit_lines': 3, - 'metadata': false + 'metadata': false, }) }} {% endif %} - {# Only if ACL SEE_DETAILS AND/OR only on template SHOW ?? - durationTime - travelTime - comment - documents - attendee - #} + {% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) and activity.privateComment.hasCommentForUser(app.user) %} +
+
+

{{ 'Private comment'|trans }}

+
+
+
+
+ {{ activity.privateComment.comments[app.user.id]|chill_markdown_to_html }} +
+
+
+
+ {% endif %} + + {% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) and activity.documents|length > 0 %} +
+
+

{{ 'Documents'|trans }}

+
+
+
    + {% for d in activity.documents %} +
  • {{ d.title|chill_print_or_message('document.Any title') }} {{ d|chill_document_button_group(d.title, is_granted('CHILL_ACTIVITY_UPDATE', activity), {small: true}) }}
  • + {% endfor %} +
+
+
+ {% endif %} + diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig index 96cfef39b..48eb839d7 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig @@ -5,7 +5,7 @@ Maybe should we think about abstracting this file a bit more ? Moving it to PersonBundle ? #} -{% if context == 'calendar_accompanyingCourse' %} +{% if context == 'calendar_accompanyingCourse' or context == 'calendar_person' %} {% import "@ChillCalendar/_invite.html.twig" as invite %} {% endif %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig index a666f183d..bdf55d86f 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig @@ -8,11 +8,13 @@ {% block js %} {{ parent() }} {{ encore_entry_script_tags('mod_notification_toggle_read_status') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} {{ encore_entry_link_tags('mod_notification_toggle_read_status') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig index 0514284a2..0c1afdac9 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig @@ -23,11 +23,13 @@ {% block js %} {{ parent() }} {{ encore_entry_script_tags('mod_notification_toggle_read_status') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} {{ encore_entry_link_tags('mod_notification_toggle_read_status') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list_recent.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list_recent.html.twig index e4184da36..aa0bbea0c 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list_recent.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list_recent.html.twig @@ -41,7 +41,7 @@ {% if activity.user and t.userVisible %}
  • {{ 'Referrer'|trans ~ ': ' }} - {{ activity.user|chill_entity_render_box}} + {{ activity.user|chill_entity_render_box }}
  • {% endif %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig index 49e71bfad..fca6a7658 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig @@ -34,8 +34,12 @@
    -
    {{ 'Referrer'|trans|capitalize }}
    -
    {{ entity.user|chill_entity_render_box }}
    + {%- if entity.user is not null %} +
    {{ 'Referrer'|trans|capitalize }}
    +
    + {{ entity.user|chill_entity_render_box }} +
    + {% endif %} {%- if entity.scope -%}
    {{ 'Scope'|trans }}
    @@ -156,7 +160,7 @@
    - {{ entity.privateComment.comments[userId] }} + {{ entity.privateComment.comments[userId]|chill_markdown_to_html }}
    @@ -168,11 +172,11 @@ {% if entity.documents|length > 0 %}
      {% for d in entity.documents %} -
    • {{ d.title }}{{ m.download_button(d) }}
    • +
    • {{ d.title|chill_print_or_message('document.Any title') }} {{ d|chill_document_button_group(d.title, is_granted('CHILL_ACTIVITY_UPDATE', entity), {small: true}) }}
    • {% endfor %}
    {% else %} - {{ 'Any document found'|trans }} + {{ 'No document found'|trans }} {% endif %} {% endif %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig index fbd7b20b4..3486f47bc 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig @@ -8,12 +8,14 @@ {{ parent() }} {{ encore_entry_script_tags('mod_notification_toggle_read_status') }} {{ encore_entry_script_tags('mod_async_upload') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} {{ encore_entry_link_tags('mod_notification_toggle_read_status') }} {{ encore_entry_link_tags('mod_async_upload') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig index 5776eddb5..43a8eb86b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig @@ -7,13 +7,13 @@ {% block js %} {{ parent() }} {{ encore_entry_script_tags('mod_notification_toggle_read_status') }} - {{ encore_entry_link_tags('mod_async_upload') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} {{ encore_entry_link_tags('mod_notification_toggle_read_status') }} - {{ encore_entry_link_tags('mod_async_upload') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/ActivityReason/index.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/ActivityReason/index.html.twig index 7d9e5f71d..855c9386d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/ActivityReason/index.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/ActivityReason/index.html.twig @@ -7,22 +7,34 @@ {{ 'Name'|trans }} + {{ 'Active'|trans }} {{ 'Actions'|trans }} {% for entity in entities %} - {{ entity.name|localize_translatable_string }} -
      -
    • - -
    • -
    • - -
    • -
    + {% if entity.category is not null -%} + {{ entity.category.name|localize_translatable_string }} > + {% endif -%} + {{ entity.name|localize_translatable_string }} + + + + {% if entity.active and not entity.isActiveAndParentActive %} + {{ 'Associated activity reason category is inactive'|trans }} + {% endif %} + + +
      +
    • + +
    • +
    • + +
    • +
    {% endfor %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/ActivityReasonCategory/index.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/ActivityReasonCategory/index.html.twig index 473059124..5f48180b3 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/ActivityReasonCategory/index.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/ActivityReasonCategory/index.html.twig @@ -7,6 +7,7 @@ {{ 'Name'|trans }} + {{ 'Active'|trans }} {{ 'Actions'|trans }} @@ -14,7 +15,11 @@ {% for entity in entities %} - {{ entity.name|localize_translatable_string }} + {{ entity.name|localize_translatable_string }} + + + +
    • diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php index 4e2970138..624859eda 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php @@ -22,6 +22,7 @@ use Chill\DocStoreBundle\Repository\DocumentCategoryRepository; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Templating\Entity\PersonRenderInterface; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; @@ -31,6 +32,9 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Contracts\Translation\TranslatorInterface; +/** + * @implements DocGeneratorContextWithPublicFormInterface + */ class ActivityContext implements DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface @@ -45,6 +49,8 @@ class ActivityContext implements private PersonRenderInterface $personRender; + private PersonRepository $personRepository; + private TranslatableStringHelperInterface $translatableStringHelper; private TranslatorInterface $translator; @@ -55,6 +61,7 @@ class ActivityContext implements TranslatableStringHelperInterface $translatableStringHelper, EntityManagerInterface $em, PersonRenderInterface $personRender, + PersonRepository $personRepository, TranslatorInterface $translator, BaseContextData $baseContextData ) { @@ -63,6 +70,7 @@ class ActivityContext implements $this->translatableStringHelper = $translatableStringHelper; $this->em = $em; $this->personRender = $personRender; + $this->personRepository = $personRepository; $this->translator = $translator; $this->baseContextData = $baseContextData; } @@ -126,9 +134,7 @@ class ActivityContext implements $builder->add($key, EntityType::class, [ 'class' => Person::class, 'choices' => $persons, - 'choice_label' => function (Person $p) { - return $this->personRender->renderString($p, []); - }, + 'choice_label' => fn (Person $p) => $this->personRender->renderString($p, []), 'multiple' => false, 'required' => false, 'expanded' => true, @@ -139,6 +145,32 @@ class ActivityContext implements } } + public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array + { + $denormalized = []; + + foreach (['mainPerson', 'person1', 'person2'] as $k) { + if (null !== ($id = ($data[$k] ?? null))) { + $denormalized[$k] = $this->personRepository->find($id); + } else { + $denormalized[$k] = null; + } + } + + return $denormalized; + } + + public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array + { + $normalized = []; + + foreach (['mainPerson', 'person1', 'person2'] as $k) { + $normalized[$k] = null === $data[$k] ? null : $data[$k]->getId(); + } + + return $normalized; + } + public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array { if (!$entity instanceof Activity) { @@ -147,7 +179,7 @@ class ActivityContext implements $options = $template->getOptions(); $data = []; - $data = array_merge($data, $this->baseContextData->getData()); + $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null)); $data['activity'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => Activity::class, 'groups' => 'docgen:read']); $data['course'] = $this->normalizer->normalize($entity->getAccompanyingPeriod(), 'docgen', ['docgen:expects' => AccompanyingPeriod::class, 'groups' => 'docgen:read']); @@ -206,9 +238,6 @@ class ActivityContext implements return $options['mainPerson'] || $options['person1'] || $options['person2']; } - /** - * @param Activity $entity - */ public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void { $storedObject->setTitle($this->translatableStringHelper->localize($template->getName())); diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php index 3189307f9..3da451f2e 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php @@ -34,10 +34,16 @@ use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use DateTime; use libphonenumber\PhoneNumber; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use function in_array; +/** + * @implements DocGeneratorContextWithPublicFormInterface + * @implements DocGeneratorContextWithAdminFormInterface + */ class ListActivitiesByAccompanyingPeriodContext implements DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface @@ -69,7 +75,7 @@ class ListActivitiesByAccompanyingPeriodContext implements SocialIssueRepository $socialIssueRepository, ThirdPartyRepository $thirdPartyRepository, TranslatableStringHelperInterface $translatableStringHelper, - UserRepository $userRepository + UserRepository $userRepository, ) { $this->accompanyingPeriodContext = $accompanyingPeriodContext; $this->activityACLAwareRepository = $activityACLAwareRepository; @@ -100,14 +106,81 @@ class ListActivitiesByAccompanyingPeriodContext implements public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void { $this->accompanyingPeriodContext->buildPublicForm($builder, $template, $entity); + + $builder + ->add('myActivitiesOnly', CheckboxType::class, [ + 'required' => false, + 'label' => 'docgen.myActivitiesOnly', + ]) + ->add('myWorksOnly', CheckboxType::class, [ + 'required' => false, + 'label' => 'docgen.myWorksOnly', + ]); } - public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array + public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array + { + $denormalized = $this->accompanyingPeriodContext->contextGenerationDataDenormalize($template, $entity, $data); + + foreach (['myActivitiesOnly', 'myWorksOnly'] as $k) { + $denormalized[$k] = $data[$k]; + } + + return $denormalized; + } + + public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array + { + $normalized = $this->accompanyingPeriodContext->contextGenerationDataNormalize($template, $entity, $data); + + foreach (['myActivitiesOnly', 'myWorksOnly'] as $k) { + $normalized[$k] = $data[$k] ?? false; + } + + return $normalized; + } + + private function filterActivitiesByUser(array $activities, User $user): array + { + return array_filter( + $activities, + function ($activity) use ($user) { + $activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []); + return in_array($user->getUsername(), $activityUsernames, true); + } + ); + } + + private function filterWorksByUser(array $works, User $user): array + { + return array_filter( + $works, + function ($work) use ($user) { + $workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []); + + return in_array($user->getUsername(), $workUsernames, true); + } + ); + } + + public function getData(DocGeneratorTemplate $template, object $entity, array $contextGenerationData = []): array { $data = $this->accompanyingPeriodContext->getData($template, $entity, $contextGenerationData); - $data['activities'] = $this->getActivitiesSimplified($entity); + $activities = $this->getActivitiesSimplified($entity); + $myActivitiesOnly = $contextGenerationData['myActivitiesOnly']; + if ($myActivitiesOnly && isset($contextGenerationData['creator'])) { + $activities = $this->filterActivitiesByUser($activities, $contextGenerationData['creator']); + } + + $data['activities'] = $activities; + + $myWorksOnly = $contextGenerationData['myWorksOnly']; + + if ($myWorksOnly && isset($contextGenerationData['creator'])) { + $data['course']['works'] = $this->filterWorksByUser($data['course']['works'], $contextGenerationData['creator']); + } return $data; } @@ -143,7 +216,7 @@ class ListActivitiesByAccompanyingPeriodContext implements public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool { - return $this->accompanyingPeriodContext->hasPublicForm($template, $entity); + return true; } public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void diff --git a/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php b/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php index 991591141..c60a8d286 100644 --- a/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php +++ b/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php @@ -13,13 +13,18 @@ namespace Chill\ActivityBundle\Templating\Entity; use Chill\ActivityBundle\Entity\ActivityReason; use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender; +use Chill\MainBundle\Templating\Entity\BoxUtilsChillEntityRenderTrait; +use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; /** * Render activity reason. + * + * @implements ChillEntityRenderInterface */ -class ActivityReasonRender extends AbstractChillEntityRender +class ActivityReasonRender implements ChillEntityRenderInterface { + use BoxUtilsChillEntityRenderTrait; /** * @var TranslatableStringHelper */ @@ -51,9 +56,6 @@ class ActivityReasonRender extends AbstractChillEntityRender $this->getDefaultClosingBox(); } - /** - * @param ActivityReason $entity - */ public function renderString($entity, array $options): string { $category = ''; diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php index 8a30a6c9b..04301afae 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php @@ -121,14 +121,14 @@ final class ActivityControllerTest extends WebTestCase $client->getResponse()->getStatusCode(), 'Unexpected HTTP status code for GET /activity/' ); - $crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité') + $crawler = $client->click($crawler->selectLink('Ajouter un nouvel échange') ->link()); $reason1 = $this->getRandomActivityReason(); $reason2 = $this->getRandomActivityReason([$reason1->getId()]); // Fill in the form and submit it - $form = $crawler->selectButton('Ajouter une nouvelle activité')->form([ + $form = $crawler->selectButton('Ajouter un nouvel échange')->form([ 'chill_activitybundle_activity' => [ 'date' => '15-01-2015', 'durationTime' => 600, @@ -152,9 +152,9 @@ final class ActivityControllerTest extends WebTestCase ); // Edit the entity - $crawler = $client->click($crawler->selectLink("Modifier l'activité")->link()); + $crawler = $client->click($crawler->selectLink("Modifier l'échange")->link()); - $form = $crawler->selectButton("Sauver l'activité")->form([ + $form = $crawler->selectButton("Sauver l'échange")->form([ 'chill_activitybundle_activity' => [ 'date' => '25-01-2015', // 'remark' => 'Foo' @@ -234,7 +234,7 @@ final class ActivityControllerTest extends WebTestCase $user = new \Chill\MainBundle\Entity\User(); $user ->setPassword($container->get('security.password_encoder') - ->encodePassword($user, 'password')) + ->encodePassword($user, 'password')) ->setUsername($username) ->addGroupCenter($groupCenter); @@ -369,12 +369,8 @@ final class ActivityControllerTest extends WebTestCase $center ); $reachableScopesId = array_intersect( - array_map(static function ($s) { - return $s->getId(); - }, $reachableScopesDelete), - array_map(static function ($s) { - return $s->getId(); - }, $reachableScopesUpdate) + array_map(static fn ($s) => $s->getId(), $reachableScopesDelete), + array_map(static fn ($s) => $s->getId(), $reachableScopesUpdate) ); if (count($reachableScopesId) === 0) { diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php index b6cb6fc7b..3ed6b4409 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php @@ -112,9 +112,9 @@ final class ActivityTypeTest extends KernelTestCase 'attendee' => true, ]]); -// var_dump($form->getErrors()->count()); var_dump($form->isValid()); -// foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); } -// var_dump($form->getErrors()); + // var_dump($form->getErrors()->count()); var_dump($form->isValid()); + // foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); } + // var_dump($form->getErrors()); $this->assertTrue($form->isSynchronized(), 'Test the form is synchronized'); $this->assertTrue($form->isValid(), 'test the form is valid'); @@ -188,9 +188,7 @@ final class ActivityTypeTest extends KernelTestCase // map all the values in an array $values = array_map( - static function ($choice) { - return $choice->value; - }, + static fn ($choice) => $choice->value, $view['activity']['durationTime']->vars['choices'] ); diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php index 59659e40f..a8d85daa6 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Form\Type; -use Chill\ActivityBundle\Form\Type\TranslatableActivityReason; +use Chill\ActivityBundle\Form\Type\PickActivityReasonType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Component\Form\PreloadedExtension; use Symfony\Component\Form\Test\TypeTestCase; @@ -36,7 +36,7 @@ final class TranslatableActivityReasonTest extends TypeTestCase public function testSimple() { - $translatableActivityReasonType = new TranslatableActivityReason( + $translatableActivityReasonType = new PickActivityReasonType( $this->getTranslatableStringHelper() ); @@ -79,15 +79,13 @@ final class TranslatableActivityReasonTest extends TypeTestCase $request = $prophet->prophesize(); $translator = $prophet->prophesize(); - $request->willExtend('Symfony\Component\HttpFoundation\Request'); + $request->willExtend(\Symfony\Component\HttpFoundation\Request::class); $request->getLocale()->willReturn($fallbackLocale); - $requestStack->willExtend('Symfony\Component\HttpFoundation\RequestStack'); - $requestStack->getCurrentRequest()->will(static function () use ($request) { - return $request; - }); + $requestStack->willExtend(\Symfony\Component\HttpFoundation\RequestStack::class); + $requestStack->getCurrentRequest()->will(static fn () => $request); - $translator->willExtend('Symfony\Component\Translation\Translator'); + $translator->willExtend(\Symfony\Component\Translation\Translator::class); $translator->getFallbackLocales()->willReturn($locale); return new TranslatableStringHelper( diff --git a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php index a9b9e2ec7..1fb90a4ae 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php @@ -160,7 +160,7 @@ final class ActivityVoterTest extends KernelTestCase { $token = $this->prophet->prophesize(); $token - ->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + ->willImplement('\\' . \Symfony\Component\Security\Core\Authentication\Token\TokenInterface::class); if (null === $user) { $token->getUser()->willReturn(null); diff --git a/src/Bundle/ChillActivityBundle/config/services/controller.yaml b/src/Bundle/ChillActivityBundle/config/services/controller.yaml index 96ace0a64..c14c40475 100644 --- a/src/Bundle/ChillActivityBundle/config/services/controller.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/controller.yaml @@ -1,4 +1,11 @@ services: - Chill\ActivityBundle\Controller\ActivityController: + _defaults: autowire: true + autoconfigure: true + + Chill\ActivityBundle\Controller\: + resource: '../../Controller/' + tags: ['controller.service_arguments'] + + Chill\ActivityBundle\Controller\ActivityController: tags: ['controller.service_arguments'] diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 16addd2a3..09817d80e 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -79,6 +79,11 @@ services: tags: - { name: chill.export_filter, alias: 'accompanyingcourse_activitytype_filter' } + chill.activity.export.location_filter: + class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationFilter + tags: + - { name: chill.export_filter, alias: 'activity_location_filter' } + chill.activity.export.locationtype_filter: class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter tags: diff --git a/src/Bundle/ChillActivityBundle/config/services/form.yaml b/src/Bundle/ChillActivityBundle/config/services/form.yaml index fd034b2da..f4945d8ce 100644 --- a/src/Bundle/ChillActivityBundle/config/services/form.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/form.yaml @@ -1,19 +1,12 @@ --- services: - chill.activity.form.type.translatableactivityreasoncategory: - class: Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategory - arguments: - - "@request_stack" - tags: - - { name: form.type, alias: translatable_activity_reason_category } + Chill\ActivityBundle\Form\Type\TranslatableActivityReasonCategoryType: + autowire: true + autoconfigure: true - chill.activity.form.type.translatableactivityreason: - class: Chill\ActivityBundle\Form\Type\TranslatableActivityReason - arguments: - $translatableStringHelper: "@chill.main.helper.translatable_string" - $reasonRender: '@Chill\ActivityBundle\Templating\Entity\ActivityReasonRender' - tags: - - { name: form.type, alias: translatable_activity_reason } + Chill\ActivityBundle\Form\Type\PickActivityReasonType: + autowire: true + autoconfigure: true chill.activity.form.type.translatableactivitytype: class: Chill\ActivityBundle\Form\Type\TranslatableActivityType diff --git a/src/Bundle/ChillActivityBundle/config/services/repositories.yaml b/src/Bundle/ChillActivityBundle/config/services/repositories.yaml index c9fe8d843..096528221 100644 --- a/src/Bundle/ChillActivityBundle/config/services/repositories.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/repositories.yaml @@ -1,5 +1,8 @@ --- services: + Chill\ActivityBundle\Repository\ActivityReasonRepository: + autowire: true + chill_activity.repository.activity_type: '@Chill\ActivityBundle\Repository\ActivityTypeRepository' chill_activity.repository.reason: '@Chill\ActivityBundle\Repository\ActivityReasonRepository' chill_activity.repository.reason_category: '@Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository' diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index 2f7aee6ac..042fccc69 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -1,41 +1,41 @@ #general -Show the activity: Voir l'activité -Edit the activity: Modifier l'activité -Activity: Activité +Show the activity: Voir l'échange +Edit the activity: Modifier l'échange +Activity: Échange Duration time: Durée Duration Time: Durée durationTime: durée Travel time: Durée de déplacement -Attendee: Présence de la personne -attendee: présence de la personne +Attendee: Présence de l'usager +attendee: présence de l'usager list_reasons: liste des sujets user_username: nom de l'utilisateur circle_name: nom du cercle Remark: Commentaire No comments: Aucun commentaire -Add a new activity: Ajouter une nouvelle activité -Activity list: Liste des activités +Add a new activity: Ajouter une nouvel échange +Activity list: Liste des échanges present: présent not present: absent Delete: Supprimer Update: Mettre à jour -Update activity: Modifier l'activité +Update activity: Modifier l'échange Scope: Cercle -Activity data: Données de l'activité -Activity location: Localisation de l'activité +Activity data: Données de l'échange +Activity location: Localisation de l'échange No reason associated: Aucun sujet No social issues associated: Aucune problématique sociale No social actions associated: Aucune action d'accompagnement -There isn't any activities.: Aucune activité enregistrée. -type_name: type de l'activité +There isn't any activities.: Aucun échange enregistré. +type_name: type de l'échange person_firstname: prénom person_lastname: nom de famille -person_id: identifiant de la personne +person_id: identifiant de l'usager Type: Type Invisible: Invisible Optional: Optionnel Required: Obligatoire -Persons: Personnes +Persons: Usagers Users: Utilisateurs Emergency: Urgent Sent received: Entrant / Sortant @@ -50,10 +50,10 @@ received: Reçu #forms -Activity creation: Nouvelle activité +Activity creation: Nouvel échange Create: Créer Back to the list: Retour à la liste -Save activity: Sauver l'activité +Save activity: Sauver l'échange Reset form: Remise à zéro du formulaire Choose the duration: Choisir la durée Choose a type: Choisir un type @@ -77,7 +77,7 @@ Choose a type: Choisir un type 4 hours: 4 heures 4 hours 30: 4 heures 30 5 hours: 5 heures -Concerned groups: Parties concernées +Concerned groups: Parties concernées par l'échange Persons in accompanying course: Usagers du parcours Third persons: Tiers non-pro. Others persons: Usagers @@ -90,46 +90,50 @@ activity: No documents: Aucun document #timeline -'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"' +'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' #controller -'Success : activity created!': L'activité a été créée. -'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'activité n'a pas été créée. -'Success : activity updated!': L'activité a été mise à jour. -'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'activité n'a pas été mise à jour. +'Success : activity created!': L'échange a été créé. +'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé. +'Success : activity updated!': L'échange a été mis à jour. +'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour. # ROLES -CHILL_ACTIVITY_CREATE: Créer une activité -CHILL_ACTIVITY_UPDATE: Modifier une activité -CHILL_ACTIVITY_SEE: Voir une activité -CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des activités -CHILL_ACTIVITY_DELETE: Supprimer une activité -CHILL_ACTIVITY_STATS: Statistique des activités -CHILL_ACTIVITY_LIST: Liste des activités +CHILL_ACTIVITY_CREATE: Créer un échange +CHILL_ACTIVITY_UPDATE: Modifier un échange +CHILL_ACTIVITY_SEE: Voir un échange +CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges +CHILL_ACTIVITY_DELETE: Supprimer un échange +CHILL_ACTIVITY_STATS: Statistique des échanges +CHILL_ACTIVITY_LIST: Liste des échanges +CHILL_ACTIVITY_CREATE_PERSON: Créer un échange lié à un usager +CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE: Créer un échange lié à un parcours +CHILL_ACTIVITY_FULL: Voir les détails, créer, supprimer et mettre à jour un échange # admin -Activities: Activités -Activity configuration: Configuration des activités -Activity configuration menu: Configuration des activités -Activity types: Types d'activité -Activity type configuration: Configuration des categories d'activités -Activity Reasons: Sujets d'une activité -Activity Reasons Category: Catégories de sujet d'activités -Activity Types Categories: Catégories des types d'activité -Activity Presences: Presences aux activités +Activities: Échanges +Activity configuration: Configuration des échanges +Activity configuration menu: Configuration des échanges +Activity types: Types d'échange +Activity type configuration: Configuration des catégories d'échanges +Activity Reasons: Sujets d'un échange +Activity Reasons Category: Catégories de sujet d'échanges +Activity Types Categories: Catégories des types d'échange +Activity Presences: Présences aux échanges +Associated activity reason category is inactive: La catégorie de sujet attachée est inactive # Crud crud: activity_type: - title_new: Nouveau type d'activité - title_edit: Edition d'un type d'activité + title_new: Nouveau type d'échange + title_edit: Édition d'un type d'échange activity_type_category: - title_new: Nouvelle catégorie de type d'activité - title_edit: Edition d'une catégorie de type d'activité + title_new: Nouvelle catégorie de type d'échange + title_edit: Édition d'une catégorie de type d'échange activity_presence: - title_new: Nouvelle Présence aux activités - title_edit: Edition d'une Présence aux activités + title_new: Nouvelle présence aux échanges + title_edit: Édition d'une présence aux échanges # activity reason admin ActivityReason list: Liste des sujets @@ -138,7 +142,7 @@ Active: Actif Category: Catégorie ActivityReason creation: Nouveau sujet ActivityReason edit: Modification d'un sujet -ActivityReason: Sujet d'activité +ActivityReason: Sujet d'échange The entity is inactive and won't be proposed: Le sujet est inactif et ne sera pas proposé The entity is active and will be proposed: Le sujet est actif et sera proposé @@ -147,19 +151,19 @@ ActivityReasonCategory list: Catégories de sujets Create a new activity category reason: Créer une nouvelle catégorie ActivityReasonCategory creation: Nouvelle catégorie de sujet ActivityReasonCategory edit: Modification d'une catégorie de sujet -ActivityReasonCategory: Catégorie de sujet d'activité +ActivityReasonCategory: Catégorie de sujet d'échange ActivityReasonCategory is active and will be proposed: La catégorie est active et sera proposée ActivityReasonCategory is inactive and won't be proposed: La catégorie est inactive et ne sera pas proposée #activity presence admin -ActivityPresence list: Liste des Présences aux activités -Create a new activity presence: Créer une nouvelle "Présence aux activités" +ActivityPresence list: Liste des présences aux échanges +Create a new activity presence: Créer une nouvelle "Présence aux échanges" # activity type type admin -ActivityType list: Types d'activités -Create a new activity type: Créer un nouveau type d'activité -Persons visible: Visibilité du champ Personnes -Persons label: Libellé du champ Personnes +ActivityType list: Types d'échanges +Create a new activity type: Créer un nouveau type d'échange +Persons visible: Visibilité du champ Usagers +Persons label: Libellé du champ Usagers User visible: Visibilité du champ Utilisateur User label: Libellé du champ Utilisateur Date visible: Visibilité du champ Date @@ -182,8 +186,8 @@ Private comment visible: Visibilité du champ Commentaire Privé Private comment label: Libellé du champ Commentaire Privé Emergency visible: Visibilité du champ Urgent Emergency label: Libellé du champ Urgent -Accompanying period visible: Visibilité du champ Période d'accompagnement -Accompanying period label: Libellé du champ Période d'accompagnement +Accompanying period visible: Visibilité du champ parcours d'accompagnement +Accompanying period label: Libellé du champ parcours d'accompagnement Social issues visible: Visibilité du champ Problématiques sociales Social issues label: Libellé du champ Problématiques sociales Social actions visible: Visibilité du champ Action sociale @@ -196,136 +200,140 @@ Documents visible: Visibilité du champ Documents Documents label: Libellé du champ Documents # activity type category admin -ActivityTypeCategory list: Liste des catégories des types d'activité -Create a new activity type category: Créer une nouvelle catégorie de type d'activité +ActivityTypeCategory list: Liste des catégories des types d'échange +Create a new activity type category: Créer une nouvelle catégorie de type d'échange # activity delete -Remove activity: Supprimer une activité -Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer une activité qui concerne "%name%" ? -The activity has been successfully removed.: L'activité a été supprimée. +Remove activity: Supprimer un échange +Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer un échange qui concerne "%name%" ? +The activity has been successfully removed.: L'échange a été supprimé. # exports -Exports of activities linked to a person: Exports des activités liées à une personne -Number of activities linked to a person: Nombre d'activités liées à une personne -Count activities linked to a person: Nombre d'activités -Count activities linked to a person by various parameters.: Compte le nombre d'activités enregistrées et liées à une personne en fonction de différents paramètres. -Sum activity linked to a person duration: Durée des activités -Sum activities linked to a person duration: Durée des activités liés à un usager -Sum activities linked to a person duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. -List activity linked to a person: Liste les activités -List activities linked to a person: Liste des activités liés à un usager -List activities linked to a person description: Crée la liste des activités en fonction de différents paramètres. +Exports of activities linked to a person: Exports des échanges liés à un usager +Number of activities linked to a person: Nombre d'échanges liés à un usager +Count activities linked to a person: Nombre d'échanges +Count activities linked to a person by various parameters.: Compte le nombre d'échanges enregistrés et liés à un usager en fonction de différents paramètres. +Sum activity linked to a person duration: Durée des échanges +Sum activities linked to a person duration: Durée des échanges liés à un usager +Sum activities linked to a person duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres. +List activity linked to a person: Liste les échanges +List activities linked to a person: Liste des échanges liés à un usager +List activities linked to a person description: Crée la liste des échanges en fonction de différents paramètres. -Exports of activities linked to an accompanying period: Exports des activités liées à un parcours -Number of activities linked to an accompanying period: Nombre d'activités liées à un parcours -Count activities linked to an accompanying period: Nombre d'activités -Count activities linked to an accompanying period by various parameters.: Compte le nombre d'activités enregistrées et liées à un parcours en fonction de différents paramètres. -Sum activity linked to an accompanying period duration: Somme de la durée des activités -Sum activities linked to an accompanying period duration: Somme de la durée des activités liées à un parcours -Sum activities linked to an accompanying period duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. -Sum activity linked to an accompanying period visit duration: Somme de la durée de déplacement des activités -Sum activities linked to an accompanying period visit duration: Somme de la durée de déplacement des activités liées à un parcours -Sum activities linked to an accompanying period visit duration by various parameters.: Additionne la durée de déplacement des activités en fonction de différents paramètres. -Average activity linked to an accompanying period duration: Moyenne de la durée des activités -Average activities linked to an accompanying period duration: Moyenne de la durée des activités liées à un parcours -Average activities linked to an accompanying period duration by various parameters.: Moyenne de la durée des activités en fonction de différents paramètres. -Average activity linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités -Average activities linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités liées à un parcours -Average activities linked to an accompanying period visit duration by various parameters.: Moyenne de la durée de déplacement des activités en fonction de différents paramètres. +Exports of activities linked to an accompanying period: Exports des échanges liés à un parcours +Number of activities linked to an accompanying period: Nombre d'échanges liés à un parcours +Count activities linked to an accompanying period: Nombre d'échanges +Count activities linked to an accompanying period by various parameters.: Compte le nombre d'échanges enregistrés et liées à un parcours en fonction de différents paramètres. +Sum activity linked to an accompanying period duration: Somme de la durée des échanges +Sum activities linked to an accompanying period duration: Somme de la durée des échanges liés à un parcours +Sum activities linked to an accompanying period duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres. +Sum activity linked to an accompanying period visit duration: Somme de la durée de déplacement des échanges +Sum activities linked to an accompanying period visit duration: Somme de la durée de déplacement des échanges liés à un parcours +Sum activities linked to an accompanying period visit duration by various parameters.: Additionne la durée de déplacement des échanges en fonction de différents paramètres. +Average activity linked to an accompanying period duration: Moyenne de la durée des échanges +Average activities linked to an accompanying period duration: Moyenne de la durée des échanges liés à un parcours +Average activities linked to an accompanying period duration by various parameters.: Moyenne de la durée des échanges en fonction de différents paramètres. +Average activity linked to an accompanying period visit duration: Moyenne de la durée de déplacement des échanges +Average activities linked to an accompanying period visit duration: Moyenne de la durée de déplacement des échanges liés à un parcours +Average activities linked to an accompanying period visit duration by various parameters.: Moyenne de la durée de déplacement des échanges en fonction de différents paramètres. #filters -Filter by reason: Filtrer les activités par sujet +Filter by reason: Filtrer les échanges par sujet 'Filtered by reasons: only %list%': 'Filtré par sujet: seulement %list%' -'Filtered by activity type: only %list%': "Filtré par type d'activité: uniquement %list%" -Filtered by date activity: Filtrer les activités par date -Activities after this date: Activités après cette date -Activities before this date: Activités avant cette date -"Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'activité: uniquement entre %date_from% et %date_to%" -This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "activités après cette date" +'Filtered by activity type: only %list%': "Filtré par type d'échange: uniquement %list%" +Filtered by date activity: Filtrer les échanges par date +Activities after this date: Échanges après cette date +Activities before this date: Échanges avant cette date +"Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'échange: uniquement entre %date_from% et %date_to%" +This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "échanges après cette date" -Filtered by person having an activity in a period: Uniquement les personnes ayant eu une activité dans la période donnée -Implied in an activity after this date: Impliqué dans une activité après cette date -Implied in an activity before this date: Impliqué dans une activité avant cette date -Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par personnes associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name% -Activity reasons for those activities: Sujets de ces activités +Filtered by person having an activity in a period: Uniquement les usagers ayant eu un échange dans la période donnée +Implied in an activity after this date: Impliqué dans un échange après cette date +Implied in an activity before this date: Impliqué dans un échange avant cette date +Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par usager associées à un échange entre %date_from% et %date_to% avec les sujets %reasons_name% +Activity reasons for those activities: Sujets de ces échanges -Filter by activity type: Filtrer les activités par type +Filter by activity type: Filtrer les échanges par type -Filter activity by locationtype: Filtrer les activités par type de localisation +Filter activity by location: Filtrer les échanges par localisation +'Filtered activity by location: only %locations%': "Filtré par localisation: uniquement %locations%" +Filter activity by locationtype: Filtrer les échanges par type de localisation 'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%" Accepted locationtype: Types de localisation Accepted users: TMS(s) -Filter activity by emergency: Filtrer les activités par urgence +Filter activity by emergency: Filtrer les échanges par urgence 'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%" -activity is emergency: l'activité est urgente -activity is not emergency: l'activité n'est pas urgente -Filter activity by sentreceived: Filtrer les activités par envoyé/reçu +activity is emergency: l'échange est urgent +activity is not emergency: l'échange n'est pas urgent +Filter activity by sentreceived: Filtrer les échanges par envoyé/reçu 'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%" Accepted sentreceived: '' -Filter activity by linked socialaction: Filtrer les activités par action liée +Filter activity by linked socialaction: Filtrer les échanges par action liée 'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%" -Filter activity by linked socialissue: Filtrer les activités par problématique liée +Filter activity by linked socialissue: Filtrer les échanges par problématique liée 'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%" -Filter activity by user: Filtrer les activités par créateur -Filter activity by users: Filtrer les activités par utilisateur participant -Filter activity by creator: Filtrer les activités par créateur de l'échange +Filter activity by user: Filtrer les échanges par créateur +Filter activity by users: Filtrer les échanges par utilisateur participant +Filter activity by creator: Filtrer les échanges par créateur de l'échange 'Filtered activity by user: only %users%': "Filtré par référent: uniquement %users%" 'Filtered activity by users: only %users%': "Filtré par utilisateurs participants: uniquement %users%" 'Filtered activity by creator: only %users%': "Filtré par créateur: uniquement %users%" Creators: Créateurs -Filter activity by userscope: Filtrer les activités par service du créateur +Filter activity by userscope: Filtrer les échanges par service du créateur 'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%" Accepted userscope: Services - -Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’activité -Filtered acp which has no activities: Filtrer les parcours sans activité associée -Group acp by activity number: Grouper les parcours par nombre d’activité + +Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’échange +Filtered acp which has no activities: Filtrer les parcours sans échange associé +Group acp by activity number: Grouper les parcours par nombre d’échange #aggregators -Activity type: Type d'activité -Activity user: Utilisateur lié à l'activité +Activity type: Type d'échange +Activity user: Utilisateur lié à l'échange By reason: Par sujet By category of reason: Par catégorie de sujet Reason's level: Niveau du sujet -Group by reasons: Sujet d'activité -Aggregate by activity user: Grouper les activités par référent -Aggregate by activity users: Grouper les activités par utilisateurs participants -Aggregate by activity type: Grouper les activités par type -Aggregate by activity reason: Grouper les activités par sujet -Aggregate by users scope: Grouper les activités par service principal de l'utilisateur -Users 's scope: Service principal des utilisateurs participants à l'activité -Aggregate by users job: Grouper les activités par métier des utilisateurs participants -Users 's job: Métier des utilisateurs participants à l'activité +Group by reasons: Sujet d'échange +Aggregate by activity user: Grouper les échanges par référent +Aggregate by activity users: Grouper les échanges par utilisateurs participants +Aggregate by activity type: Grouper les échanges par type +Aggregate by activity reason: Grouper les échanges par sujet +Aggregate by users scope: Grouper les échanges par service principal de l'utilisateur +Users 's scope: Service principal des utilisateurs participants à l'échange +Aggregate by users job: Grouper les échanges par métier des utilisateurs participants +Users 's job: Métier des utilisateurs participants à l'échange -Group activity by locationtype: Grouper les activités par type de localisation -Group activity by date: Grouper les activités par date +Group activity by locationtype: Grouper les échanges par type de localisation +Group activity by date: Grouper les échanges par date Frequency: Fréquence by month: Par mois by week: Par semaine for week: Semaine by year: Par année in year: En -Group activity by creator: Grouper les activités par créateur de l'échange -Group activity by creator scope: Grouper les activités par service du créateur de l'échange -Group activity by linked thirdparties: Grouper les activités par tiers impliqué +Group activity by creator: Grouper les échanges par créateur de l'échange +Group activity by creator scope: Grouper les échanges par service du créateur de l'échange +Group activity by linked thirdparties: Grouper les échanges par tiers impliqué Accepted thirdparty: Tiers impliqué -Group activity by linked socialaction: Grouper les activités par action liée -Group activity by linked socialissue: Grouper les activités par problématique liée -Group activity by userscope: Grouper les activités par service du créateur +Group activity by linked socialaction: Grouper les échanges par action liée +Group activity by linked socialissue: Grouper les échanges par problématique liée +Group activity by userscope: Grouper les échanges par service du créateur -Last activities: Les dernières activités +Last activities: Les derniers échanges -See activity in accompanying course context: Voir l'activité dans le contexte du parcours d'accompagnement +See activity in accompanying course context: Voir l'échange dans le contexte du parcours d'accompagnement -You get notified of an activity which does not exists any more: Cette notification ne correspond pas à une activité valide. -you are not allowed to see it details: La notification fait référence à une activité à laquelle vous n'avez pas accès. -This is the minimal activity data: Activité n° +You get notified of an activity which does not exists any more: Cette notification ne correspond pas à un échange valide. +you are not allowed to see it details: La notification fait référence à un échange auquel vous n'avez pas accès. +This is the minimal activity data: Échange n° docgen: - Activity basic: Echange - A basic context for activity: Contexte pour les activités - Accompanying period with a list of activities: Parcours d'accompagnement avec liste des activités - Accompanying period with a list of activities description: Ce contexte reprend les informations du parcours, et tous les activités pour un parcours. Les activités ne sont pas filtrés. + Activity basic: Échange + A basic context for activity: Contexte pour les échanges + Accompanying period with a list of activities: Parcours d'accompagnement avec liste des échanges + Accompanying period with a list of activities description: Ce contexte reprend les informations du parcours, et tous les échanges pour un parcours. Les échanges ne sont pas filtrés. + myActivitiesOnly: Prendre en compte uniquement les échanges dans lesquels je suis intervenu + myWorksOnly: Prendre en compte uniquement les actions d'accompagnement dont je suis référent export: list: @@ -333,10 +341,10 @@ export: users name: Nom des utilisateurs users ids: Identifiant des utilisateurs third parties ids: Identifiant des tiers - persons ids: Identifiant des personnes - persons name: Nom des personnes + persons ids: Identifiant des usagers + persons name: Nom des usagers thirds parties: Tiers - date: Date de l'activité + date: Date de l'échange locationName: Localisation sent received: Envoyé ou reçu emergency: Urgence @@ -345,17 +353,17 @@ export: travelTime: Durée de déplacement durationTime: Durée id: Identifiant - List activities linked to an accompanying course: Liste les activités liées à un parcours en fonction de différents filtres. - List activity linked to a course: Liste des activités liées à un parcours + List activities linked to an accompanying course: Liste les échanges liés à un parcours en fonction de différents filtres. + List activity linked to a course: Liste des échanges liés à un parcours filter: activity: by_usersjob: - Filter by users job: Filtrer les activités par métier d'au moins un utilisateur participant + Filter by users job: Filtrer les échanges par métier d'au moins un utilisateur participant 'Filtered activity by users job: only %jobs%': 'Filtré par métier d''au moins un utilisateur participant: seulement %jobs%' by_usersscope: - Filter by users scope: Filtrer les activités par services d'au moins un utilisateur participant + Filter by users scope: Filtrer les échanges par services d'au moins un utilisateur participant 'Filtered activity by users scope: only %scopes%': 'Filtré par service d''au moins un utilisateur participant: seulement %scopes%' aggregator: activity: @@ -363,4 +371,4 @@ export: Sent or received: Envoyé ou reçu is sent: envoyé is received: reçu - Group activity by sentreceived: Grouper les activités par envoyé / reçu + Group activity by sentreceived: Grouper les échanges par envoyé / reçu diff --git a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml index dac37fc7d..c7dc05f2b 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml +++ b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml @@ -47,10 +47,10 @@ Reasons: Onderwerpen #forms -Activity creation: Nouvelle activité +Activity creation: Nouvel échange Create: Créer Back to the list: Retour à la liste -Save activity: Sauver l'activité +Save activity: Sauver l'échange Reset form: Remise à zéro du formulaire Choose the duration: Choisir la durée Choose a type: Choisir un type @@ -79,43 +79,43 @@ activity: No documents: Aucun document #timeline -'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"' +'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"' #controller -'Success : activity created!': L'activité a été créée. -'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'activité n'a pas été créée. -'Success : activity updated!': L'activité a été mise à jour. -'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'activité n'a pas été mise à jour. +'Success : activity created!': L'échange a été créé. +'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé. +'Success : activity updated!': L'échange a été mis à jour. +'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mis à jour. # ROLES -CHILL_ACTIVITY_CREATE: Créer une activité -CHILL_ACTIVITY_UPDATE: Modifier une activité -CHILL_ACTIVITY_SEE: Voir une activité -CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des activités -CHILL_ACTIVITY_DELETE: Supprimer une activité -CHILL_ACTIVITY_STATS: Statistique des activités -CHILL_ACTIVITY_LIST: Liste des activités +CHILL_ACTIVITY_CREATE: Créer un échange +CHILL_ACTIVITY_UPDATE: Modifier un échange +CHILL_ACTIVITY_SEE: Voir un échange +CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges +CHILL_ACTIVITY_DELETE: Supprimer un échange +CHILL_ACTIVITY_STATS: Statistique des échanges +CHILL_ACTIVITY_LIST: Liste des échanges # admin -Activities: Activités -Activity configuration: Configuration des activités -Activity configuration menu: Configuration des activités -Activity types: Types d'activité -Activity type configuration: Configuration des categories d'activités -Activity Reasons: Sujets d'une activité -Activity Reasons Category: Catégories de sujet d'activités -Activity Types Categories: Catégories des types d'activité -Activity Presences: Presences des activités +Activities: Échanges +Activity configuration: Configuration des échanges +Activity configuration menu: Configuration des échanges +Activity types: Types d'échange +Activity type configuration: Configuration des categories d'échanges +Activity Reasons: Sujets d'un échange +Activity Reasons Category: Catégories de sujet d'échanges +Activity Types Categories: Catégories des types d'échanges +Activity Presences: Presences des échanges # Crud crud: activity_type: - title_new: Nouveau type d'activité - title_edit: Edition d'un type d'activité + title_new: Nouveau type d'échange + title_edit: Edition d'un type d'échange activity_type_category: - title_new: Nouvelle catégorie de type d'activité - title_edit: Edition d'une catégorie de type d'activité + title_new: Nouvelle catégorie de type d'échange + title_edit: Edition d'une catégorie de type d'échange # activity reason admin ActivityReason list: Liste des sujets @@ -124,7 +124,7 @@ Active: Actif Category: Catégorie ActivityReason creation: Nouveau sujet ActivityReason edit: Modification d'un sujet -ActivityReason: Sujet d'activité +ActivityReason: Sujet d'échange The entity is inactive and won't be proposed: Le sujet est inactif et ne sera pas proposé The entity is active and will be proposed: Le sujet est actif et sera proposé @@ -133,13 +133,13 @@ ActivityReasonCategory list: Catégories de sujets Create a new activity category reason: Créer une nouvelle catégorie ActivityReasonCategory creation: Nouvelle catégorie de sujet ActivityReasonCategory edit: Modification d'une catégorie de sujet -ActivityReasonCategory: Catégorie de sujet d'activité +ActivityReasonCategory: Catégorie de sujet d'échange ActivityReasonCategory is active and will be proposed: La catégorie est active et sera proposée ActivityReasonCategory is inactive and won't be proposed: La catégorie est inactive et ne sera pas proposée # activity type type admin -ActivityType list: Types d'activités -Create a new activity type: Créer un nouveau type d'activité +ActivityType list: Types d'échanges +Create a new activity type: Créer un nouveau type d'échange Persons visible: Visibilité du champ Personnes Persons label: Libellé du champ Personnes User visible: Visibilité du champ Utilisateur @@ -177,20 +177,20 @@ Documents label: Libellé du champ Documents # activity type category admin ActivityTypeCategory list: Liste des catégories des types d'activité -Create a new activity type category: Créer une nouvelle catégorie de type d'activité +Create a new activity type category: Créer une nouvelle catégorie de type d'échange # activity delete -Remove activity: Supprimer une activité -Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer une activité qui concerne "%name%" ? -The activity has been successfully removed.: L'activité a été supprimée. +Remove activity: Supprimer un échange +Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer un échange qui concerne "%name%" ? +The activity has been successfully removed.: L'échange a été supprimée. # exports -Count activities: Nombre d'activités -Count activities by various parameters.: Compte le nombre d'activités enregistrées en fonction de différents paramètres. -Sum activity duration: Total de la durée des activités -Sum activities duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. -List activities: Liste les activités -Number of activities: Nombre d'activités +Count activities: Nombre d'échanges +Count activities by various parameters.: Compte le nombre d'échanges enregistrées en fonction de différents paramètres. +Sum activity duration: Total de la durée des échanges +Sum activities duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres. +List activities: Liste les échanges +Number of activities: Nombre d'échanges #filters Filter by reason: Filtrer par sujet d'activité diff --git a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml index f2c104828..053752854 100644 --- a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml @@ -1,22 +1,22 @@ The reasons's level should not be empty: Le niveau du sujet ne peut pas être vide At least one reason must be choosen: Au moins un sujet doit être choisi -For this type of activity, you must add at least one person: Pour ce type d'activité, vous devez ajouter au moins un usager -For this type of activity, you must add at least one user: Pour ce type d'activité, vous devez ajouter au moins un utilisateur -For this type of activity, you must add at least one third party: Pour ce type d'activité, vous devez ajouter au moins un tiers -For this type of activity, user is required: Pour ce type d'activité, l'utilisateur est requis -For this type of activity, date is required: Pour ce type d'activité, la date est requise -For this type of activity, location is required: Pour ce type d'activité, la localisation est requise -For this type of activity, attendee is required: Pour ce type d'activité, le champ "Présence de la personne" est requis -For this type of activity, duration time is required: Pour ce type d'activité, la durée est requise -For this type of activity, travel time is required: Pour ce type d'activité, la durée du trajet est requise -For this type of activity, reasons is required: Pour ce type d'activité, le champ "sujet" est requis -For this type of activity, comment is required: Pour ce type d'activité, un commentaire est requis -For this type of activity, sent/received is required: Pour ce type d'activité, le champ Entrant/Sortant est requis -For this type of activity, document is required: Pour ce type d'activité, un document est requis -For this type of activity, emergency is required: Pour ce type d'activité, le champ "Urgent" est requis -For this type of activity, accompanying period is required: Pour ce type d'activité, le parcours d'accompagnement est requis -For this type of activity, you must add at least one social issue: Pour ce type d'activité, vous devez ajouter au moins une problématique sociale -For this type of activity, you must add at least one social action: Pour ce type d'activité, vous devez indiquer au moins une action sociale +For this type of activity, you must add at least one person: Pour ce type d'échange, vous devez ajouter au moins un usager +For this type of activity, you must add at least one user: Pour ce type d'échange, vous devez ajouter au moins un utilisateur +For this type of activity, you must add at least one third party: Pour ce type d'échange, vous devez ajouter au moins un tiers +For this type of activity, user is required: Pour ce type d'échange, l'utilisateur est requis +For this type of activity, date is required: Pour ce type d'échange, la date est requise +For this type of activity, location is required: Pour ce type d'échange, la localisation est requise +For this type of activity, attendee is required: Pour ce type d'échange, le champ "Présence de l'usager" est requis +For this type of activity, duration time is required: Pour ce type d'échange, la durée est requise +For this type of activity, travel time is required: Pour ce type d'échange, la durée du trajet est requise +For this type of activity, reasons is required: Pour ce type d'échange, le champ "sujet" est requis +For this type of activity, comment is required: Pour ce type d'échange, un commentaire est requis +For this type of activity, sent/received is required: Pour ce type d'échange, le champ Entrant/Sortant est requis +For this type of activity, document is required: Pour ce type d'échange, un document est requis +For this type of activity, emergency is required: Pour ce type d'échange, le champ "Urgent" est requis +For this type of activity, accompanying period is required: Pour ce type d'échange, le parcours d'accompagnement est requis +For this type of activity, you must add at least one social issue: Pour ce type d'échange, vous devez ajouter au moins une problématique sociale +For this type of activity, you must add at least one social action: Pour ce type d'échange, vous devez indiquer au moins une action sociale # admin This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales" diff --git a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php index d1ac55f40..6f6a11390 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php @@ -55,7 +55,7 @@ class LoadAsideActivity extends Fixture implements DependentFixtureInterface $this->getReference('aside_activity_category_0') ) ->setDate((new DateTimeImmutable('today')) - ->sub(new DateInterval('P' . random_int(1, 100) . 'D'))); + ->sub(new DateInterval('P' . random_int(1, 100) . 'D'))); $manager->persist($activity); } diff --git a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php index d01998358..2e2398c3e 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php @@ -22,7 +22,7 @@ class Configuration implements ConfigurationInterface { $treeBuilder = new TreeBuilder('chill_aside_activity'); - $treeBuilder->getRootNode('chill_aside_activity') + $treeBuilder->getRootNode() ->children() ->arrayNode('form') ->canBeEnabled() @@ -132,9 +132,7 @@ class Configuration implements ConfigurationInterface ->info('The number of seconds of this duration. Must be an integer.') ->cannotBeEmpty() ->validate() - ->ifTrue(static function ($data) { - return !is_int($data); - })->thenInvalid('The value %s is not a valid integer') + ->ifTrue(static fn ($data) => !is_int($data))->thenInvalid('The value %s is not a valid integer') ->end() ->end() ->scalarNode('label') diff --git a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php index 598988cfb..3dc205f09 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php @@ -57,7 +57,7 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface * @ORM\GeneratedValue * @ORM\Column(type="integer") */ - private ?int $id; + private ?int $id = null; /** * @ORM\Column(type="string", length=100, nullable=true) diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php index 6c91c9336..32418e3c3 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php @@ -53,19 +53,15 @@ class ByActivityTypeAggregator implements AggregatorInterface public function getLabels($key, array $values, $data) { - $this->asideActivityCategoryRepository->findBy(['id' => $values]); - return function ($value): string { if ('_header' === $value) { return 'export.aggregator.Aside activity type'; } - if (null === $value) { + if (null === $value || null === $t = $this->asideActivityCategoryRepository->find($value)) { return ''; } - $t = $this->asideActivityCategoryRepository->find($value); - return $this->translatableStringHelper->localize($t->getTitle()); }; } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php new file mode 100644 index 000000000..d2fe7c2f2 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php @@ -0,0 +1,89 @@ +userJobRepository = $userJobRepository; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('aside_user', $qb->getAllAliases(), true)) { + $qb->leftJoin('aside.agent', 'aside_user'); + } + + $qb + ->addSelect('IDENTITY(aside_user.userJob) AS aside_activity_user_job_aggregator') + ->addGroupBy('aside_activity_user_job_aggregator'); + } + + public function applyOn() + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + // nothing to add in the form + } + + public function getLabels($key, array $values, $data) + { + return function ($value): string { + if ('_header' === $value) { + return 'Users \'s job'; + } + + if (null === $value || '' === $value) { + return ''; + } + + $j = $this->userJobRepository->find($value); + + return $this->translatableStringHelper->localize( + $j->getLabel() + ); + }; + } + + public function getQueryKeys($data): array + { + return ['aside_activity_user_job_aggregator']; + } + + public function getTitle() + { + return 'export.aggregator.Aggregate by user job'; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php new file mode 100644 index 000000000..6c06ee756 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php @@ -0,0 +1,89 @@ +scopeRepository = $scopeRepository; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + if (!in_array('aside_user', $qb->getAllAliases(), true)) { + $qb->leftJoin('aside.agent', 'aside_user'); + } + + $qb + ->addSelect('IDENTITY(aside_user.mainScope) AS aside_activity_user_scope_aggregator') + ->addGroupBy('aside_activity_user_scope_aggregator'); + } + + public function applyOn() + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + // nothing to add in the form + } + + public function getLabels($key, array $values, $data) + { + return function ($value): string { + if ('_header' === $value) { + return 'Users \'s scope'; + } + + if (null === $value || '' === $value) { + return ''; + } + + $s = $this->scopeRepository->find($value); + + return $this->translatableStringHelper->localize( + $s->getName() + ); + }; + } + + public function getQueryKeys($data): array + { + return ['aside_activity_user_scope_aggregator']; + } + + public function getTitle() + { + return 'export.aggregator.Aggregate by user scope'; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php new file mode 100644 index 000000000..f3db629cb --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php @@ -0,0 +1,102 @@ +repository = $repository; + } + + public function buildForm(FormBuilderInterface $builder) + { + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.Average aside activities duration'; + } + + public function getGroup(): string + { + return 'export.Exports of aside activities'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_avg_aside_activity_duration' !== $key) { + throw new LogicException("the key {$key} is not used by this export"); + } + + return static fn ($value) => '_header' === $value ? 'Average duration aside activities' : $value; + } + + public function getQueryKeys($data): array + { + return ['export_avg_aside_activity_duration']; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(Query::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.Average aside activities duration'; + } + + public function getType(): string + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $qb = $this->repository->createQueryBuilder('aside'); + + $qb + ->select('AVG(aside.duration) as export_avg_aside_activity_duration') + ->andWhere($qb->expr()->isNotNull('aside.duration')); + + return $qb; + } + + public function requiredRole(): string + { + return AsideActivityVoter::STATS; + } + + public function supportsModifiers(): array + { + return [Declarations::ASIDE_ACTIVITY_TYPE]; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php index c3e99f129..9204fad4b 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php @@ -11,12 +11,12 @@ declare(strict_types=1); namespace Chill\AsideActivityBundle\Export\Export; +use Chill\AsideActivityBundle\Export\Declarations; use Chill\AsideActivityBundle\Repository\AsideActivityRepository; use Chill\AsideActivityBundle\Security\AsideActivityVoter; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; -use ChillAsideActivityBundle\Export\Declarations; use Doctrine\ORM\Query; use LogicException; use Symfony\Component\Form\FormBuilderInterface; @@ -59,9 +59,7 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface $labels = array_combine($values, $values); $labels['_header'] = $this->getTitle(); - return static function ($value) use ($labels) { - return $labels[$value]; - }; + return static fn ($value) => $labels[$value]; } public function getQueryKeys($data): array @@ -100,6 +98,8 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface public function supportsModifiers(): array { - return []; + return [ + Declarations::ASIDE_ACTIVITY_TYPE, + ]; } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php new file mode 100644 index 000000000..aee168174 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php @@ -0,0 +1,239 @@ +em = $em; + $this->dateTimeHelper = $dateTimeHelper; + $this->userHelper = $userHelper; + $this->scopeRepository = $scopeRepository; + $this->centerRepository = $centerRepository; + $this->asideActivityCategoryRepository = $asideActivityCategoryRepository; + $this->categoryRender = $categoryRender; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function buildForm(FormBuilderInterface $builder) + { + } + + public function getAllowedFormattersTypes() + { + return [FormatterInterface::TYPE_LIST]; + } + + public function getDescription() + { + return 'export.aside_activity.List of aside activities'; + } + + public function getGroup(): string + { + return 'export.Exports of aside activities'; + } + + public function getLabels($key, array $values, $data) + { + switch ($key) { + case 'id': + case 'note': + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.aside_activity.' . $key; + } + + return $value ?? ''; + }; + + case 'duration': + return static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.aside_activity.' . $key; + } + + if (null === $value) { + return ''; + } + + if ($value instanceof DateTimeInterface) { + return $value->format('H:i:s'); + } + + return $value; + }; + + case 'createdAt': + case 'updatedAt': + case 'date': + return $this->dateTimeHelper->getLabel('export.aside_activity.' . $key); + + case 'agent_id': + case 'creator_id': + return $this->userHelper->getLabel($key, $values, 'export.aside_activity.' . $key); + + case 'aside_activity_type': + return function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.aside_activity_type'; + } + + if (null === $value || '' === $value || null === $c = $this->asideActivityCategoryRepository->find($value)) { + return ''; + } + + return $this->categoryRender->renderString($c, []); + }; + + case 'main_scope': + return function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.main_scope'; + } + + if (null === $value || '' === $value || null === $c = $this->scopeRepository->find($value)) { + return ''; + } + + return $this->translatableStringHelper->localize($c->getName()); + }; + + case 'main_center': + return function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.main_center'; + } + + if (null === $value || '' === $value || null === $c = $this->centerRepository->find($value)) { + /** @var Center $c */ + return ''; + } + + return $c->getName(); + }; + + default: + throw new LogicException('this key is not supported : ' . $key); + } + } + + public function getQueryKeys($data) + { + return [ + 'id', + 'createdAt', + 'updatedAt', + 'agent_id', + 'creator_id', + 'main_scope', + 'main_center', + 'aside_activity_type', + 'date', + 'duration', + 'note', + ]; + } + + public function getResult($query, $data): array + { + return $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY); + } + + public function getTitle() + { + return 'export.aside_activity.List of aside activities'; + } + + public function getType(): string + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $qb = $this->em->createQueryBuilder() + ->from(AsideActivity::class, 'aside') + ->leftJoin('aside.agent', 'agent'); + + $qb + ->addSelect('aside.id AS id') + ->addSelect('aside.createdAt AS createdAt') + ->addSelect('aside.updatedAt AS updatedAt') + ->addSelect('IDENTITY(aside.agent) AS agent_id') + ->addSelect('IDENTITY(aside.createdBy) AS creator_id') + ->addSelect('IDENTITY(agent.mainScope) AS main_scope') + ->addSelect('IDENTITY(agent.mainCenter) AS main_center') + ->addSelect('IDENTITY(aside.type) AS aside_activity_type') + ->addSelect('aside.date') + ->addSelect('aside.duration') + ->addSelect('aside.note'); + + return $qb; + } + + public function requiredRole(): string + { + return AsideActivityVoter::STATS; + } + + public function supportsModifiers() + { + return [Declarations::ASIDE_ACTIVITY_TYPE]; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php new file mode 100644 index 000000000..af17a2591 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php @@ -0,0 +1,102 @@ +repository = $repository; + } + + public function buildForm(FormBuilderInterface $builder) + { + } + + public function getAllowedFormattersTypes(): array + { + return [FormatterInterface::TYPE_TABULAR]; + } + + public function getDescription(): string + { + return 'export.Sum aside activities duration'; + } + + public function getGroup(): string + { + return 'export.Exports of aside activities'; + } + + public function getLabels($key, array $values, $data) + { + if ('export_sum_aside_activity_duration' !== $key) { + throw new LogicException("the key {$key} is not used by this export"); + } + + return static fn ($value) => '_header' === $value ? 'Sum duration aside activities' : $value; + } + + public function getQueryKeys($data): array + { + return ['export_sum_aside_activity_duration']; + } + + public function getResult($query, $data) + { + return $query->getQuery()->getResult(Query::HYDRATE_SCALAR); + } + + public function getTitle(): string + { + return 'export.Sum aside activities duration'; + } + + public function getType(): string + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) + { + $qb = $this->repository + ->createQueryBuilder('aside'); + + $qb->select('SUM(aside.duration) as export_sum_aside_activity_duration') + ->andWhere($qb->expr()->isNotNull('aside.duration')); + + return $qb; + } + + public function requiredRole(): string + { + return AsideActivityVoter::STATS; + } + + public function supportsModifiers(): array + { + return [Declarations::ASIDE_ACTIVITY_TYPE]; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php index 85b327795..3ad8e0e93 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php @@ -80,8 +80,8 @@ class ByActivityTypeFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { $types = array_map( - fn (AsideActivityCategory $t): string => $this->translatableStringHelper->localize($t->getName()), - $this->asideActivityTypeRepository->findBy(['id' => $data['types']->toArray()]) + fn (AsideActivityCategory $t): string => $this->translatableStringHelper->localize($t->getTitle()), + $data['types']->toArray() ); return ['export.filter.Filtered by aside activity type: only %type%', [ diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php index 099c87fc0..7a1b6f4dc 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php @@ -17,7 +17,6 @@ use Chill\MainBundle\Form\Type\Export\FilterType; use Chill\MainBundle\Form\Type\PickRollingDateType; use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface; -use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormError; @@ -46,25 +45,18 @@ class ByDateFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $where = $qb->getDQLPart('where'); $clause = $qb->expr()->between( 'aside.date', ':date_from', ':date_to' ); - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } + $qb->andWhere($clause); - $qb->add('where', $where); $qb->setParameter( 'date_from', $this->rollingDateConverter->convert($data['date_from']) - ); - $qb->setParameter( + )->setParameter( 'date_to', $this->rollingDateConverter->convert($data['date_to']) ); diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php new file mode 100644 index 000000000..795c813cd --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php @@ -0,0 +1,74 @@ +userRender = $userRender; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $clause = $qb->expr()->in('aside.agent', ':users'); + + $qb + ->andWhere($clause) + ->setParameter('users', $data['accepted_users']); + } + + public function applyOn(): string + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('accepted_users', PickUserDynamicType::class, [ + 'multiple' => true, + 'label' => 'Creators', + ]); + } + + public function describeAction($data, $format = 'string'): array + { + $users = []; + + foreach ($data['accepted_users'] as $u) { + $users[] = $this->userRender->renderString($u, []); + } + + return ['export.filter.Filtered aside activity by user: only %users%', [ + '%users%' => implode(', ', $users), + ]]; + } + + public function getTitle(): string + { + return 'export.filter.Filter aside activity by user'; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php new file mode 100644 index 000000000..86194b123 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php @@ -0,0 +1,81 @@ +translatableStringHelper = $translatableStringHelper; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . AsideActivity::class . ' aside_activity_user_job_filter_act + JOIN aside_activity_user_job_filter_act.agent aside_activity_user_job_filter_user WHERE aside_activity_user_job_filter_user.userJob IN (:aside_activity_user_job_filter_jobs) AND aside_activity_user_job_filter_act = aside' + ) + ) + ->setParameter('aside_activity_user_job_filter_jobs', $data['jobs']); + } + + public function applyOn() + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('jobs', EntityType::class, [ + 'class' => UserJob::class, + 'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize($j->getLabel()), + 'multiple' => true, + 'expanded' => true, + ]); + } + + public function describeAction($data, $format = 'string') + { + return ['export.filter.Filtered aside activities by user jobs: only %jobs%', [ + '%jobs%' => implode( + ', ', + array_map( + fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()), + $data['jobs']->toArray() + ) + ), + ]]; + } + + public function getTitle() + { + return 'export.filter.Filter by user jobs'; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php new file mode 100644 index 000000000..4342e11eb --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php @@ -0,0 +1,88 @@ +scopeRepository = $scopeRepository; + $this->translatableStringHelper = $translatableStringHelper; + } + + public function addRole(): ?string + { + return null; + } + + public function alterQuery(QueryBuilder $qb, $data) + { + $qb + ->andWhere( + $qb->expr()->exists( + 'SELECT 1 FROM ' . AsideActivity::class . ' aside_activity_user_scope_filter_act + JOIN aside_activity_user_scope_filter_act.agent aside_activity_user_scope_filter_user WHERE aside_activity_user_scope_filter_user.mainScope IN (:aside_activity_user_scope_filter_scopes) AND aside_activity_user_scope_filter_act = aside ' + ) + ) + ->setParameter('aside_activity_user_scope_filter_scopes', $data['scopes']); + } + + public function applyOn() + { + return Declarations::ASIDE_ACTIVITY_TYPE; + } + + public function buildForm(FormBuilderInterface $builder) + { + $builder->add('scopes', EntityType::class, [ + 'class' => Scope::class, + 'choices' => $this->scopeRepository->findAllActive(), + 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()), + 'multiple' => true, + 'expanded' => true, + ]); + } + + public function describeAction($data, $format = 'string') + { + return ['export.filter.Filtered aside activities by user scope: only %scopes%', [ + '%scopes%' => implode( + ', ', + array_map( + fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()), + $data['scopes']->toArray() + ) + ), + ]]; + } + + public function getTitle() + { + return 'export.filter.Filter by user scope'; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php index 5c438bd0a..727287972 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php @@ -12,8 +12,7 @@ declare(strict_types=1); namespace Chill\AsideActivityBundle\Form; use Chill\AsideActivityBundle\Entity\AsideActivity; -use Chill\AsideActivityBundle\Entity\AsideActivityCategory; -use Chill\AsideActivityBundle\Templating\Entity\CategoryRender; +use Chill\AsideActivityBundle\Form\Type\PickAsideActivityCategoryType; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillTextareaType; use Chill\MainBundle\Form\Type\PickUserDynamicType; @@ -21,8 +20,6 @@ use DateInterval; use DateTime; use DateTimeImmutable; use DateTimeZone; -use Doctrine\ORM\EntityRepository; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; @@ -31,26 +28,17 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use function in_array; final class AsideActivityFormType extends AbstractType { - private CategoryRender $categoryRender; - - private TokenStorageInterface $storage; - private array $timeChoices; public function __construct( ParameterBagInterface $parameterBag, - TokenStorageInterface $storage, - CategoryRender $categoryRender ) { $this->timeChoices = $parameterBag->get('chill_aside_activity.form.time_duration'); - $this->storage = $storage; - $this->categoryRender = $categoryRender; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -81,28 +69,10 @@ final class AsideActivityFormType extends AbstractType 'required' => true, ] ) - ->add( - 'type', - EntityType::class, - [ - 'label' => 'Type', - 'required' => true, - 'class' => AsideActivityCategory::class, - 'placeholder' => 'Choose the activity category', - 'query_builder' => static function (EntityRepository $er) { - $qb = $er->createQueryBuilder('ac'); - $qb->where($qb->expr()->eq('ac.isActive', 'TRUE')) - ->addOrderBy('ac.ordering', 'ASC'); - - return $qb; - }, - 'choice_label' => function (AsideActivityCategory $asideActivityCategory) { - $options = []; - - return $this->categoryRender->renderString($asideActivityCategory, $options); - }, - ] - ) + ->add('type', PickAsideActivityCategoryType::class, [ + 'label' => 'Type', + 'required' => true, + ]) ->add('duration', ChoiceType::class, $durationTimeOptions) ->add('note', ChillTextareaType::class, [ 'label' => 'Note', @@ -125,9 +95,7 @@ final class AsideActivityFormType extends AbstractType // the datetimetransformer will then handle timezone as GMT $timezoneUTC = new DateTimeZone('GMT'); /** @var DateTimeImmutable $data */ - $data = $formEvent->getData() === null ? - DateTime::createFromFormat('U', '300') : - $formEvent->getData(); + $data = $formEvent->getData() ?? DateTime::createFromFormat('U', '300'); $seconds = $data->getTimezone()->getOffset($data); $data->setTimeZone($timezoneUTC); $data->add(new DateInterval('PT' . $seconds . 'S')); diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php new file mode 100644 index 000000000..3ee392517 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php @@ -0,0 +1,57 @@ +categoryRender = $categoryRender; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefaults([ + 'class' => AsideActivityCategory::class, + 'placeholder' => 'Choose the activity category', + 'query_builder' => static function (EntityRepository $er) { + $qb = $er->createQueryBuilder('ac'); + $qb->where($qb->expr()->eq('ac.isActive', 'TRUE')) + ->addOrderBy('ac.ordering', 'ASC'); + + return $qb; + }, + 'choice_label' => function (AsideActivityCategory $asideActivityCategory) { + $options = []; + + return $this->categoryRender->renderString($asideActivityCategory, $options); + }, + 'attr' => ['class' => 'select2'], + ]); + } + + public function getParent(): string + { + return EntityType::class; + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php index d4ed7dbf9..f23fcdc8a 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php @@ -44,17 +44,6 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface 'order' => 11, 'icons' => ['plus'], ]); - $menu->addChild($this->translator->trans('Phonecall'), [ - 'route' => 'chill_crud_aside_activity_new', - 'routeParameters' => [ - 'type' => 1, - 'duration' => 900, - ], - ]) - ->setExtras([ - 'order' => 12, - 'icons' => ['plus'], - ]); } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/_delete.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/_delete.html.twig index 2f30b14cf..79c2e6919 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/_delete.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/_delete.html.twig @@ -1,4 +1,4 @@ -
      + {% block crud_content_header %}

      {{ ('crud.'~crud_name~'.title_delete')|trans({ '%as_string%': 'Aside Activity' }) }}

      {% endblock crud_content_header %} @@ -27,4 +27,4 @@
    {{ form_end(form) }} -
    + diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig index 4dd12e042..5ffc73684 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig @@ -87,5 +87,5 @@ {% endif %} - + {% endblock %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig index 09acf9859..99ff217b1 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/new.html.twig @@ -1,4 +1,4 @@ -{% extends '@ChillMain/Admin/layout.html.twig' %} +{% extends '@ChillMain/layout.html.twig' %} {% block js %} {{ parent() }} @@ -14,7 +14,7 @@ {% include('@ChillMain/CRUD/_new_title.html.twig') %} {% endblock %} -{% block admin_content %} +{% block content %} {% embed '@ChillMain/CRUD/_new_content.html.twig' %} {% block content_form_actions_save_and_show %}{% endblock %} {% endembed %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php index 7940b42e7..066a0ca52 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php @@ -16,6 +16,9 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Component\Templating\EngineInterface; +/** + * @implements ChillEntityRenderInterface + */ final class CategoryRender implements ChillEntityRenderInterface { public const DEFAULT_ARGS = [ @@ -45,9 +48,6 @@ final class CategoryRender implements ChillEntityRenderInterface return $parents; } - /** - * @param AsideActivityCategory $asideActivityCategory - */ public function renderBox($asideActivityCategory, array $options): string { $options = array_merge(self::DEFAULT_ARGS, $options); @@ -63,9 +63,6 @@ final class CategoryRender implements ChillEntityRenderInterface ); } - /** - * @param AsideActivityCategory $asideActivityCategory - */ public function renderString($asideActivityCategory, array $options): string { $options = array_merge(self::DEFAULT_ARGS, $options); @@ -84,9 +81,6 @@ final class CategoryRender implements ChillEntityRenderInterface return implode($options[self::SEPERATOR_KEY], $titles); } - /** - * @param AsideActivityCategory $asideActivityCategory - */ public function supports($asideActivityCategory, array $options): bool { return $asideActivityCategory instanceof AsideActivityCategory; diff --git a/src/Bundle/ChillAsideActivityBundle/src/config/services.yaml b/src/Bundle/ChillAsideActivityBundle/src/config/services.yaml index 2a7c30d7c..34bb6da33 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/config/services.yaml +++ b/src/Bundle/ChillAsideActivityBundle/src/config/services.yaml @@ -20,33 +20,3 @@ services: resource: "../Controller" autowire: true autoconfigure: true - - - ## Exports - - # indicators - Chill\AsideActivityBundle\Export\Export\CountAsideActivity: - autowire: true - autoconfigure: true - tags: - - { name: chill.export, alias: count_asideactivity } - - # filters - Chill\AsideActivityBundle\Export\Filter\ByDateFilter: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: asideactivity_bydate_filter } - - Chill\AsideActivityBundle\Export\Filter\ByActivityTypeFilter: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_filter, alias: asideactivity_activitytype_filter } - - # aggregators - Chill\AsideActivityBundle\Export\Aggregator\ByActivityTypeAggregator: - autowire: true - autoconfigure: true - tags: - - { name: chill.export_aggregator, alias: asideactivity_activitytype_aggregator } diff --git a/src/Bundle/ChillAsideActivityBundle/src/config/services/export.yaml b/src/Bundle/ChillAsideActivityBundle/src/config/services/export.yaml index 1b6b05e1c..a29413e15 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/config/services/export.yaml +++ b/src/Bundle/ChillAsideActivityBundle/src/config/services/export.yaml @@ -3,11 +3,23 @@ services: autowire: true autoconfigure: true + Chill\AsideActivityBundle\Export\Export\ListAsideActivity: + tags: + - { name: chill.export, alias: 'list_aside_activity' } + ## Indicators Chill\AsideActivityBundle\Export\Export\CountAsideActivity: tags: - { name: chill.export, alias: 'count_aside_activity' } + Chill\AsideActivityBundle\Export\Export\SumAsideActivityDuration: + tags: + - { name: chill.export, alias: 'sum_aside_activity_duration' } + + Chill\AsideActivityBundle\Export\Export\AvgAsideActivityDuration: + tags: + - { name: chill.export, alias: 'avg_aside_activity_duration' } + ## Filters chill.aside_activity.export.date_filter: class: Chill\AsideActivityBundle\Export\Filter\ByDateFilter @@ -19,9 +31,34 @@ services: tags: - { name: chill.export_filter, alias: 'aside_activity_type_filter' } + chill.aside_activity.export.user_job_filter: + class: Chill\AsideActivityBundle\Export\Filter\ByUserJobFilter + tags: + - { name: chill.export_filter, alias: 'aside_activity_user_job_filter' } + + chill.aside_activity.export.user_scope_filter: + class: Chill\AsideActivityBundle\Export\Filter\ByUserScopeFilter + tags: + - { name: chill.export_filter, alias: 'aside_activity_user_scope_filter' } + + chill.aside_activity.export.user_filter: + class: Chill\AsideActivityBundle\Export\Filter\ByUserFilter + tags: + - { name: chill.export_filter, alias: 'aside_activity_user_filter' } + ## Aggregators chill.aside_activity.export.type_aggregator: class: Chill\AsideActivityBundle\Export\Aggregator\ByActivityTypeAggregator tags: - - { name: chill.export_aggregator, alias: activity_type_aggregator } \ No newline at end of file + - { name: chill.export_aggregator, alias: activity_type_aggregator } + + chill.aside_activity.export.user_job_aggregator: + class: Chill\AsideActivityBundle\Export\Aggregator\ByUserJobAggregator + tags: + - { name: chill.export_aggregator, alias: aside_activity_user_job_aggregator } + + chill.aside_activity.export.user_scope_aggregator: + class: Chill\AsideActivityBundle\Export\Aggregator\ByUserScopeAggregator + tags: + - { name: chill.export_aggregator, alias: aside_activity_user_scope_aggregator } diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml index 35a4d6a22..cc428390c 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml @@ -21,7 +21,7 @@ Type: Type Invisible: Invisible Optional: Optionnel Required: Obligatoire -Persons: Personnes +Persons: Usagers Users: Utilisateurs Emergency: Urgent by: "Par " @@ -29,16 +29,16 @@ location: Lieu # Crud crud: - aside_activity: - title_view: Détail de l'activité annexe - title_new: Nouvelle activité annexe - title_edit: Édition d'une activité annexe - title_delete: Supprimer une activité annexe - button_delete: Supprimer - confirm_message_delete: Êtes-vous sûr de vouloir supprimer cette activité annexe? - aside_activity_category: - title_new: Nouvelle catégorie d'activité annexe - title_edit: Édition d'une catégorie de type d'activité + aside_activity: + title_view: Détail de l'activité annexe + title_new: Nouvelle activité annexe + title_edit: Édition d'une activité annexe + title_delete: Supprimer une activité annexe + button_delete: Supprimer + confirm_message_delete: Êtes-vous sûr de vouloir supprimer cette activité annexe? + aside_activity_category: + title_new: Nouvelle catégorie d'activité annexe + title_edit: Édition d'une catégorie de type d'activité #forms Create a new aside activity type: Nouvelle categorie d'activité annexe @@ -50,7 +50,7 @@ For agent: Pour l'utilisateur date: Date Duration: Durée Note: Note -Choose the agent for whom this activity is created: Choisissez l'agent pour qui l'activité est créée +Choose the agent for whom this activity is created: Choisissez l'agent pour qui l'échange est créé Choose the activity category: Choisir la catégorie #Duration @@ -169,18 +169,43 @@ Aside activity configuration: Configuration des activités annexes # exports export: - Exports of aside activities: Exports des activités annexes - Count aside activities: Nombre d'activités annexes - Count aside activities by various parameters.: Compte le nombre d'activités annexes selon divers critères - filter: - Filter by aside activity date: Filtrer les activités annexes par date - Filter by aside activity type: Filtrer les activités annexes par type d'activité - 'Filtered by aside activity type: only %type%': "Filtré par type d'activité annexe: uniquement %type%" - This date should be after the date given in "Implied in an aside activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "activités annexes après cette date" - Aside activities after this date: Actvitités annexes après cette date - Aside activities before this date: Actvitités annexes avant cette date - aggregator: - Group by aside activity type: Grouper les activités annexes par type d'activité - Aside activity type: Type d'activité annexe + aside_activity: + List of aside activities: Liste des activités annexes + createdAt: Création + updatedAt: Dernière mise à jour + agent_id: Utilisateur + creator_id: Créateur + main_scope: Service principal de l'utilisateur + main_center: Centre principal de l'utilisteur + aside_activity_type: Catégorie d'activité annexe + date: Date + duration: Durée + note: Note + Exports of aside activities: Exports des activités annexes + Count aside activities: Nombre d'activités annexes + Count aside activities by various parameters.: Compte le nombre d'activités annexes selon divers critères + Average aside activities duration: Durée moyenne des activités annexes + Sum aside activities duration: Durée des activités annexes + filter: + Filter by aside activity date: Filtrer les activités annexes par date + Filter by aside activity type: Filtrer les activités annexes par type d'activité + 'Filtered by aside activity type: only %type%': "Filtré par type d'activité annexe: uniquement %type%" + Filtered by aside activities between %dateFrom% and %dateTo%: Filtré par date d'activité annexe, entre %dateFrom% et %dateTo% + This date should be after the date given in "Implied in an aside activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "activités annexes après cette date" + Aside activities after this date: Actvitités annexes après cette date + Aside activities before this date: Actvitités annexes avant cette date + 'Filtered aside activity by user: only %users%': "Filtré par utilisateur: uniquement %users%" + Filter aside activity by user: Filtrer par utilisateur + 'Filtered aside activities by user jobs: only %jobs%': "Filtré par métier des utilisateurs: uniquement %jobs%" + Filter by user jobs: Filtrer les activités annexes par métier des utilisateurs + 'Filtered aside activities by user scope: only %scopes%': "Filtré par service des utilisateur: uniquement %scopes%" + Filter by user scope: Filtrer les activités annexes par service d'utilisateur + aggregator: + Group by aside activity type: Grouper les activités annexes par type d'activité + Aside activity type: Type d'activité annexe + Aggregate by user job: Grouper les activités annexes par métier des utilisateurs + Aggregate by user scope: Grouper les activités annexes par service des utilisateurs +# ROLES +CHILL_ASIDE_ACTIVITY_STATS: Statistiques pour les activités annexes diff --git a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php index 63b4c7294..2662b896a 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php @@ -11,12 +11,13 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Calculator; -use Chill\BudgetBundle\Entity\AbstractElement; +use Chill\BudgetBundle\Entity\Charge; +use Chill\BudgetBundle\Entity\Resource; interface CalculatorInterface { /** - * @param AbstractElement[] $elements + * @param array $elements */ public function calculate(array $elements): ?CalculatorResult; diff --git a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php index a37ac68dc..7987bdfdf 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Calculator; use Chill\BudgetBundle\Entity\AbstractElement; +use Chill\BudgetBundle\Entity\Charge; +use Chill\BudgetBundle\Entity\Resource; use OutOfBoundsException; use function array_key_exists; @@ -21,23 +23,26 @@ use function implode; class CalculatorManager { /** - * @var CalculatorInterface[] + * @var array */ - protected $calculators = []; + private array $calculators = []; - protected $defaultCalculator = []; + /** + * @var string[] + */ + private array $defaultCalculator = []; public function addCalculator(CalculatorInterface $calculator, bool $default) { - $this->calculators[$calculator::getAlias()] = $calculator; + $this->calculators[$calculator->getAlias()] = $calculator; if ($default) { - $this->defaultCalculator[] = $calculator::getAlias(); + $this->defaultCalculator[] = $calculator->getAlias(); } } /** - * @param AbstractElement[] $elements + * @param array $elements * * @return CalculatorResult[] */ @@ -46,23 +51,17 @@ class CalculatorManager $results = []; foreach ($this->defaultCalculator as $alias) { - $calculator = $this->calculators[$alias]; - $result = $calculator->calculate($elements); + $result = $this->getCalculator($alias)->calculate($elements); if (null !== $result) { - $results[$calculator::getAlias()] = $result; + $results[$alias] = $result; } } return $results; } - /** - * @param string $alias - * - * @return CalculatorInterface - */ - public function getCalculator($alias) + public function getCalculator(string $alias): CalculatorInterface { if (false === array_key_exists($alias, $this->calculators)) { throw new OutOfBoundsException("The calculator with alias '{$alias}' does " diff --git a/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php b/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php deleted file mode 100644 index f28a83a4d..000000000 --- a/src/Bundle/ChillBudgetBundle/Config/ConfigRepository.php +++ /dev/null @@ -1,102 +0,0 @@ -resources = $resources; - $this->charges = $charges; - } - - public function getChargesKeys(bool $onlyActive = false): array - { - return array_map(static function ($element) { - return $element['key']; - }, $this->getCharges($onlyActive)); - } - - /** - * @return array where keys are the resource'key and label the ressource label - */ - public function getChargesLabels(bool $onlyActive = false) - { - $charges = []; - - foreach ($this->getCharges($onlyActive) as $definition) { - $charges[$definition['key']] = $this->normalizeLabel($definition['labels']); - } - - return $charges; - } - - public function getResourcesKeys(bool $onlyActive = false): array - { - return array_map(static function ($element) { - return $element['key']; - }, $this->getResources($onlyActive)); - } - - /** - * @return array where keys are the resource'key and label the ressource label - */ - public function getResourcesLabels(bool $onlyActive = false) - { - $resources = []; - - foreach ($this->getResources($onlyActive) as $definition) { - $resources[$definition['key']] = $this->normalizeLabel($definition['labels']); - } - - return $resources; - } - - private function getCharges(bool $onlyActive = false): array - { - return $onlyActive ? - array_filter($this->charges, static function ($el) { - return $el['active']; - }) - : $this->charges; - } - - private function getResources(bool $onlyActive = false): array - { - return $onlyActive ? - array_filter($this->resources, static function ($el) { - return $el['active']; - }) - : $this->resources; - } - - private function normalizeLabel($labels) - { - $normalizedLabels = []; - - foreach ($labels as $labelDefinition) { - $normalizedLabels[$labelDefinition['lang']] = $labelDefinition['label']; - } - - return $normalizedLabels; - } -} diff --git a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php index badccf3b3..125c72ce4 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php @@ -116,7 +116,7 @@ abstract class AbstractElementController extends AbstractController $indexPage = 'chill_budget_elements_household_index'; } - $entity = null !== $element->getPerson() ? $element->getPerson() : $element->getHousehold(); + $entity = $element->getPerson() ?? $element->getHousehold(); $form = $this->createForm($this->getType(), $element); $form->add('submit', SubmitType::class); diff --git a/src/Bundle/ChillBudgetBundle/Controller/Admin/AdminController.php b/src/Bundle/ChillBudgetBundle/Controller/Admin/AdminController.php new file mode 100644 index 000000000..998775fbe --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Controller/Admin/AdminController.php @@ -0,0 +1,26 @@ +render('@ChillBudget/Admin/index.html.twig'); + } +} diff --git a/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php b/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php new file mode 100644 index 000000000..e1989176d --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php @@ -0,0 +1,28 @@ +addOrderBy('e.ordering', 'ASC'); + + return $query; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php b/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php new file mode 100644 index 000000000..90b8e750a --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php @@ -0,0 +1,28 @@ +addOrderBy('e.ordering', 'ASC'); + + return $query; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php index 148afbd35..b5db3cd30 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php @@ -14,6 +14,8 @@ namespace Chill\BudgetBundle\Controller; use Chill\BudgetBundle\Calculator\CalculatorManager; use Chill\BudgetBundle\Entity\Charge; use Chill\BudgetBundle\Entity\Resource; +use Chill\BudgetBundle\Repository\ChargeRepository; +use Chill\BudgetBundle\Repository\ResourceRepository; use Chill\BudgetBundle\Security\Authorization\BudgetElementVoter; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; @@ -29,24 +31,20 @@ use function count; class ElementController extends AbstractController { - protected CalculatorManager $calculator; + private CalculatorManager $calculator; - protected LoggerInterface $chillMainLogger; + private ResourceRepository $resourceRepository; - protected EntityManagerInterface $em; - - protected TranslatorInterface $translator; + private ChargeRepository $chargeRepository; public function __construct( - EntityManagerInterface $em, - TranslatorInterface $translator, - LoggerInterface $chillMainLogger, - CalculatorManager $calculator + CalculatorManager $calculator, + ResourceRepository $resourceRepository, + ChargeRepository $chargeRepository, ) { - $this->em = $em; - $this->translator = $translator; - $this->chillMainLogger = $chillMainLogger; $this->calculator = $calculator; + $this->resourceRepository = $resourceRepository; + $this->chargeRepository = $chargeRepository; } /** @@ -59,24 +57,10 @@ class ElementController extends AbstractController { $this->denyAccessUnlessGranted(BudgetElementVoter::SEE, $person); - $charges = $this->em - ->getRepository(Charge::class) - ->findByPerson($person); + $charges = $this->chargeRepository->findAllByEntity($person); + $resources = $this->resourceRepository->findAllByEntity($person); - $ressources = $this->em - ->getRepository(Resource::class) - ->findByPerson($person); - - $now = new DateTime('now'); - - $actualCharges = $this->em - ->getRepository(Charge::class) - ->findByEntityAndDate($person, $now); - $actualResources = $this->em - ->getRepository(Resource::class) - ->findByEntityAndDate($person, $now); - - $elements = array_merge($actualCharges, $actualResources); + $elements = array_merge($charges, $resources); if (count($elements) > 0) { $results = $this->calculator->calculateDefault($elements); @@ -85,7 +69,7 @@ class ElementController extends AbstractController return $this->render('ChillBudgetBundle:Person:index.html.twig', [ 'person' => $person, 'charges' => $charges, - 'resources' => $ressources, + 'resources' => $resources, 'results' => $results ?? [], ]); } @@ -100,60 +84,19 @@ class ElementController extends AbstractController { $this->denyAccessUnlessGranted(BudgetElementVoter::SEE, $household); - $charges = $this->em - ->getRepository(Charge::class) - ->findByHousehold($household); + $charges = $this->chargeRepository->findAllByEntity($household); + $resources = $this->resourceRepository->findAllByEntity($household); - $ressources = $this->em - ->getRepository(Resource::class) - ->findByHousehold($household); - - $now = new DateTime('now'); - - $actualCharges = $this->em - ->getRepository(Charge::class) - ->findByEntityAndDate($household, $now); - $actualResources = $this->em - ->getRepository(Resource::class) - ->findByEntityAndDate($household, $now); - - $elements = array_merge($actualCharges, $actualResources); + $elements = array_merge($charges, $resources); if (count($elements) > 0) { $results = $this->calculator->calculateDefault($elements); } - // quick solution to calculate the sum, difference and amount from - // controller. This should be done from the calculators - // TODO replace this by calculators - $wholeCharges = $actualCharges; - $wholeResources = $actualResources; - - foreach ($household->getCurrentPersons() as $person) { - $wholeCharges = array_merge( - $wholeCharges, - $this->em - ->getRepository(Charge::class) - ->findByEntityAndDate($person, $now) - ); - $wholeResources = array_merge( - $wholeResources, - $this->em - ->getRepository(Resource::class) - ->findByEntityAndDate($person, $now) - ); - } - return $this->render('ChillBudgetBundle:Household:index.html.twig', [ 'household' => $household, 'charges' => $charges, - 'resources' => $ressources, - 'wholeResources' => array_filter($wholeResources, static function (Resource $r) use ($now) { - return $r->getStartDate() <= $now && ($r->getEndDate() === null || $r->getEndDate() >= $now); - }), - 'wholeCharges' => array_filter($wholeCharges, static function (Charge $c) use ($now) { - return $c->getStartDate() <= $now && ($c->getEndDate() === null || $c->getEndDate() >= $now); - }), + 'resources' => $resources, 'results' => $results ?? [], ]); } diff --git a/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php b/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php index b5cb3a9c1..57976f846 100644 --- a/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php +++ b/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php @@ -11,6 +11,10 @@ declare(strict_types=1); namespace Chill\BudgetBundle\DependencyInjection; +use Chill\BudgetBundle\Controller\Admin\ChargeKindController; +use Chill\BudgetBundle\Controller\Admin\ResourceKindController; +use Chill\BudgetBundle\Entity\ChargeKind; +use Chill\BudgetBundle\Entity\ResourceKind; use Chill\BudgetBundle\Security\Authorization\BudgetElementVoter; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -31,8 +35,8 @@ class ChillBudgetExtension extends Extension implements PrependExtensionInterfac $config = $this->processConfiguration($configuration, $configs); $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); - $loader->load('services/config.yaml'); $loader->load('services/form.yaml'); + $loader->load('services/repository.yaml'); $loader->load('services/security.yaml'); $loader->load('services/controller.yaml'); $loader->load('services/templating.yaml'); @@ -48,6 +52,7 @@ class ChillBudgetExtension extends Extension implements PrependExtensionInterfac { $this->prependAuthorization($container); $this->prependRoutes($container); + $this->prependCruds($container); } /** (non-PHPdoc). @@ -75,6 +80,56 @@ class ChillBudgetExtension extends Extension implements PrependExtensionInterfac ]); } + protected function prependCruds(ContainerBuilder $container) + { + $container->prependExtensionConfig('chill_main', [ + 'cruds' => [ + [ + 'class' => ChargeKind::class, + 'name' => 'charge_kind', + 'base_path' => '/admin/budget/charge-kind', + 'form_class' => \Chill\BudgetBundle\Form\Admin\ChargeKindType::class, + 'controller' => ChargeKindController::class, + 'actions' => [ + 'index' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Charge/index.html.twig', + ], + 'new' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Charge/new.html.twig', + ], + 'edit' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Charge/edit.html.twig', + ], + ], + ], + [ + 'class' => ResourceKind::class, + 'name' => 'resource_kind', + 'base_path' => '/admin/budget/resource-kind', + 'form_class' => \Chill\BudgetBundle\Form\Admin\ResourceKindType::class, + 'controller' => ResourceKindController::class, + 'actions' => [ + 'index' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Resource/index.html.twig', + ], + 'new' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Resource/new.html.twig', + ], + 'edit' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillBudget/Admin/Resource/edit.html.twig', + ], + ], + ], + ], + ]); + } + protected function storeConfig($position, array $config, ContainerBuilder $container) { $container diff --git a/src/Bundle/ChillBudgetBundle/DependencyInjection/Compiler/CalculatorCompilerPass.php b/src/Bundle/ChillBudgetBundle/DependencyInjection/Compiler/CalculatorCompilerPass.php index 64df79202..012c4eab5 100644 --- a/src/Bundle/ChillBudgetBundle/DependencyInjection/Compiler/CalculatorCompilerPass.php +++ b/src/Bundle/ChillBudgetBundle/DependencyInjection/Compiler/CalculatorCompilerPass.php @@ -19,7 +19,7 @@ class CalculatorCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - $manager = $container->getDefinition('Chill\BudgetBundle\Calculator\CalculatorManager'); + $manager = $container->getDefinition(\Chill\BudgetBundle\Calculator\CalculatorManager::class); foreach ($container->findTaggedServiceIds('chill_budget.calculator') as $id => $tags) { foreach ($tags as $tag) { diff --git a/src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php index cf8f72a16..ff9931f2d 100644 --- a/src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillBudgetBundle/DependencyInjection/Configuration.php @@ -19,13 +19,14 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_budget'); - $rootNode = $treeBuilder->getRootNode('chill_budget'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() // ressources ->arrayNode('resources')->defaultValue([]) + ->setDeprecated('Chill', '2.0', 'Since the introduction of budget admin entities, config is no longer used') ->arrayPrototype() ->children() ->scalarNode('key')->isRequired()->cannotBeEmpty() @@ -49,6 +50,7 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->arrayNode('charges')->defaultValue([]) + ->setDeprecated('Chill', '2.0', 'Since the introduction of budget admin entities, config is no longer used') ->arrayPrototype() ->children() ->scalarNode('key')->isRequired()->cannotBeEmpty() diff --git a/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php b/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php index 73060f40b..619a6cdd7 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php +++ b/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php @@ -41,7 +41,7 @@ abstract class AbstractElement /** * @ORM\Column(name="comment", type="text", nullable=true) */ - private ?string $comment; + private ?string $comment = null; /** * @ORM\Column(name="endDate", type="datetime_immutable", nullable=true) @@ -50,7 +50,7 @@ abstract class AbstractElement * message="The budget element's end date must be after the start date" * ) */ - private ?DateTimeImmutable $endDate; + private ?DateTimeImmutable $endDate = null; /** * @ORM\ManyToOne( @@ -75,7 +75,7 @@ abstract class AbstractElement /** * @ORM\Column(name="type", type="string", length=255) */ - private string $type; + private string $type = ''; /*Getters and Setters */ diff --git a/src/Bundle/ChillBudgetBundle/Entity/Charge.php b/src/Bundle/ChillBudgetBundle/Entity/Charge.php index dc03eef80..056e4abff 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/Charge.php +++ b/src/Bundle/ChillBudgetBundle/Entity/Charge.php @@ -11,8 +11,8 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Entity; -use Chill\MainBundle\Entity\Center; -use Chill\MainBundle\Entity\HasCenterInterface; +use Chill\MainBundle\Entity\HasCentersInterface; +use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; @@ -22,7 +22,7 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\Table(name="chill_budget.charge") * @ORM\Entity(repositoryClass="Chill\BudgetBundle\Repository\ChargeRepository") */ -class Charge extends AbstractElement implements HasCenterInterface +class Charge extends AbstractElement implements HasCentersInterface { public const HELP_ASKED = 'running'; @@ -39,6 +39,12 @@ class Charge extends AbstractElement implements HasCenterInterface self::HELP_NOT_RELEVANT, ]; + /** + * @ORM\ManyToOne(targetEntity=ChargeKind::class, inversedBy="AbstractElement") + * @ORM\JoinColumn + */ + private ?ChargeKind $charge = null; + /** * @var string * @ORM\Column(name="help", type="string", nullable=true) @@ -46,22 +52,29 @@ class Charge extends AbstractElement implements HasCenterInterface private $help = self::HELP_NOT_RELEVANT; /** - * @var int - * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; public function __construct() { $this->setStartDate(new DateTimeImmutable('today')); } - public function getCenter(): ?Center + public function getCenters(): array { - return $this->getPerson()->getCenter(); + if (null !== $this->getPerson()) { + return [$this->getPerson()->getCenter()]; + } + + return $this->getHousehold()->getCurrentPersons()->map(static fn (Person $p) => $p->getCenter())->toArray(); + } + + public function getCharge(): ?ChargeKind + { + return $this->charge; } public function getHelp() @@ -89,6 +102,13 @@ class Charge extends AbstractElement implements HasCenterInterface return false; } + public function setCharge(?ChargeKind $charge): self + { + $this->charge = $charge; + + return $this; + } + public function setHelp($help) { $this->help = $help; diff --git a/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php b/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php new file mode 100644 index 000000000..b6ebcf347 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php @@ -0,0 +1,115 @@ +id; + } + + public function getIsActive(): bool + { + return $this->isActive; + } + + public function getKind(): ?string + { + return $this->kind; + } + + public function getName(): ?array + { + return $this->name; + } + + public function getOrdering(): float + { + return $this->ordering; + } + + public function setIsActive(bool $isActive): self + { + $this->isActive = $isActive; + + return $this; + } + + public function setKind(?string $kind): self + { + $this->kind = $kind; + + return $this; + } + + public function setName(array $name): self + { + $this->name = $name; + + return $this; + } + + public function setOrdering(float $ordering): ChargeKind + { + $this->ordering = $ordering; + + return $this; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Entity/Resource.php b/src/Bundle/ChillBudgetBundle/Entity/Resource.php index 949872d6c..28b8645e0 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/Resource.php +++ b/src/Bundle/ChillBudgetBundle/Entity/Resource.php @@ -11,8 +11,8 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Entity; -use Chill\MainBundle\Entity\Center; -use Chill\MainBundle\Entity\HasCenterInterface; +use Chill\MainBundle\Entity\HasCentersInterface; +use Chill\PersonBundle\Entity\Person; use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; @@ -22,25 +22,33 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\Table(name="chill_budget.resource") * @ORM\Entity(repositoryClass="Chill\BudgetBundle\Repository\ResourceRepository") */ -class Resource extends AbstractElement implements HasCenterInterface +class Resource extends AbstractElement implements HasCentersInterface { /** - * @var int - * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; + + /** + * @ORM\ManyToOne(targetEntity=ResourceKind::class, inversedBy="AbstractElement") + * @ORM\JoinColumn + */ + private ?ResourceKind $resource = null; public function __construct() { $this->setStartDate(new DateTimeImmutable('today')); } - public function getCenter(): ?Center + public function getCenters(): array { - return $this->getPerson()->getCenter(); + if (null !== $this->getPerson()) { + return [$this->getPerson()->getCenter()]; + } + + return $this->getHousehold()->getCurrentPersons()->map(static fn (Person $p) => $p->getCenter())->toArray(); } /** @@ -53,6 +61,11 @@ class Resource extends AbstractElement implements HasCenterInterface return $this->id; } + public function getResource(): ?ResourceKind + { + return $this->resource; + } + public function isCharge(): bool { return false; @@ -62,4 +75,11 @@ class Resource extends AbstractElement implements HasCenterInterface { return true; } + + public function setResource(?ResourceKind $resource): self + { + $this->resource = $resource; + + return $this; + } } diff --git a/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php b/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php new file mode 100644 index 000000000..4b90be5e1 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php @@ -0,0 +1,115 @@ +id; + } + + public function getIsActive(): bool + { + return $this->isActive; + } + + public function getKind(): ?string + { + return $this->kind; + } + + public function getName(): ?array + { + return $this->name; + } + + public function getOrdering(): float + { + return $this->ordering; + } + + public function setIsActive(bool $isActive): self + { + $this->isActive = $isActive; + + return $this; + } + + public function setKind(?string $kind): self + { + $this->kind = $kind; + + return $this; + } + + public function setName(array $name): self + { + $this->name = $name; + + return $this; + } + + public function setOrdering(float $ordering): self + { + $this->ordering = $ordering; + + return $this; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Form/Admin/ChargeKindType.php b/src/Bundle/ChillBudgetBundle/Form/Admin/ChargeKindType.php new file mode 100644 index 000000000..c3c2a66bf --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Form/Admin/ChargeKindType.php @@ -0,0 +1,47 @@ +add('name', TranslatableStringFormType::class, [ + 'label' => 'Title', + ]) + ->add('kind', TextType::class, [ + 'label' => 'budget.admin.form.Charge_kind_key', + 'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document', + ]) + ->add('ordering', NumberType::class) + ->add('isActive', CheckboxType::class, [ + 'label' => 'Actif ?', + 'required' => false, + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefault('class', ChargeKind::class); + } +} diff --git a/src/Bundle/ChillBudgetBundle/Form/Admin/ResourceKindType.php b/src/Bundle/ChillBudgetBundle/Form/Admin/ResourceKindType.php new file mode 100644 index 000000000..41d3a8b53 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Form/Admin/ResourceKindType.php @@ -0,0 +1,47 @@ +add('name', TranslatableStringFormType::class, [ + 'label' => 'Title', + ]) + ->add('kind', TextType::class, [ + 'label' => 'budget.admin.form.Resource_kind_key', + 'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document', + ]) + ->add('ordering', NumberType::class) + ->add('isActive', CheckboxType::class, [ + 'label' => 'Actif ?', + 'required' => false, + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefault('class', ResourceKind::class); + } +} diff --git a/src/Bundle/ChillBudgetBundle/Form/ChargeType.php b/src/Bundle/ChillBudgetBundle/Form/ChargeType.php index 387c1e424..72863163f 100644 --- a/src/Bundle/ChillBudgetBundle/Form/ChargeType.php +++ b/src/Bundle/ChillBudgetBundle/Form/ChargeType.php @@ -11,41 +11,49 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Form; -use Chill\BudgetBundle\Config\ConfigRepository; use Chill\BudgetBundle\Entity\Charge; +use Chill\BudgetBundle\Entity\ChargeKind; +use Chill\BudgetBundle\Repository\ChargeKindRepository; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; - -use function array_flip; -use function asort; +use Symfony\Contracts\Translation\TranslatorInterface; class ChargeType extends AbstractType { - protected ConfigRepository $configRepository; - protected TranslatableStringHelperInterface $translatableStringHelper; + private ChargeKindRepository $repository; + + private TranslatorInterface $translator; + public function __construct( - ConfigRepository $configRepository, - TranslatableStringHelperInterface $translatableStringHelper + TranslatableStringHelperInterface $translatableStringHelper, + ChargeKindRepository $repository, + TranslatorInterface $translator ) { - $this->configRepository = $configRepository; $this->translatableStringHelper = $translatableStringHelper; + $this->repository = $repository; + $this->translator = $translator; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('type', ChoiceType::class, [ - 'choices' => $this->getTypes(), - 'placeholder' => 'Choose a charge type', - 'attr' => ['class' => ' select2 '], + ->add('charge', EntityType::class, [ + 'class' => ChargeKind::class, + 'choices' => $this->repository->findAllActive(), + 'label' => 'Charge type', + 'required' => true, + 'placeholder' => $this->translator->trans('admin.form.Choose the type of charge'), + 'choice_label' => fn (ChargeKind $resource) => $this->translatableStringHelper->localize($resource->getName()), + 'attr' => ['class' => 'select2'], ]) ->add('amount', MoneyType::class) ->add('comment', TextareaType::class, [ @@ -99,19 +107,4 @@ class ChargeType extends AbstractType { return 'chill_budgetbundle_charge'; } - - private function getTypes() - { - $charges = $this->configRepository - ->getChargesLabels(true); - - // rewrite labels to filter in language - foreach ($charges as $key => $labels) { - $charges[$key] = $this->translatableStringHelper->localize($labels); - } - - asort($charges); - - return array_flip($charges); - } } diff --git a/src/Bundle/ChillBudgetBundle/Form/ResourceType.php b/src/Bundle/ChillBudgetBundle/Form/ResourceType.php index 6239dace8..09dfd16f3 100644 --- a/src/Bundle/ChillBudgetBundle/Form/ResourceType.php +++ b/src/Bundle/ChillBudgetBundle/Form/ResourceType.php @@ -11,41 +11,48 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Form; -use Chill\BudgetBundle\Config\ConfigRepository; use Chill\BudgetBundle\Entity\Resource; +use Chill\BudgetBundle\Entity\ResourceKind; +use Chill\BudgetBundle\Repository\ResourceKindRepository; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; - -use function array_flip; +use Symfony\Contracts\Translation\TranslatorInterface; class ResourceType extends AbstractType { - protected ConfigRepository $configRepository; - protected TranslatableStringHelperInterface $translatableStringHelper; + private ResourceKindRepository $repository; + + private TranslatorInterface $translator; + public function __construct( - ConfigRepository $configRepository, - TranslatableStringHelperInterface $translatableStringHelper + TranslatableStringHelperInterface $translatableStringHelper, + ResourceKindRepository $repository, + TranslatorInterface $translator ) { - $this->configRepository = $configRepository; $this->translatableStringHelper = $translatableStringHelper; + $this->repository = $repository; + $this->translator = $translator; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('type', ChoiceType::class, [ - 'choices' => $this->getTypes(), - 'placeholder' => 'Choose a resource type', - 'label' => 'Resource element type', - 'attr' => ['class' => ' select2 '], + ->add('resource', EntityType::class, [ + 'class' => ResourceKind::class, + 'choices' => $this->repository->findAllActive(), + 'label' => 'Resource type', + 'required' => true, + 'placeholder' => $this->translator->trans('admin.form.Choose the type of resource'), + 'choice_label' => fn (ResourceKind $resource) => $this->translatableStringHelper->localize($resource->getName()), + 'attr' => ['class' => 'select2'], ]) ->add('amount', MoneyType::class) ->add('comment', TextareaType::class, [ @@ -83,19 +90,4 @@ class ResourceType extends AbstractType { return 'chill_budgetbundle_resource'; } - - private function getTypes() - { - $resources = $this->configRepository - ->getResourcesLabels(true); - - // rewrite labels to filter in language - foreach ($resources as $key => $labels) { - $resources[$key] = $this->translatableStringHelper->localize($labels); - } - - asort($resources); - - return array_flip($resources); - } } diff --git a/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php new file mode 100644 index 000000000..894230ad9 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php @@ -0,0 +1,62 @@ +security = $security; + } + + public function buildMenu($menuId, MenuItem $menu, array $parameters) + { + // all the entries below must have ROLE_ADMIN permissions + if (!$this->security->isGranted('ROLE_ADMIN')) { + return; + } + + $menu->addChild('Budget', [ + 'route' => 'chill_admin_budget', + ]) + ->setAttribute('class', 'list-group-item-header') + ->setExtras([ + 'order' => 7050, + 'explain' => 'Budget resource and charge type configuration', + ]); + $menu + ->addChild('admin.menu.Resource types', [ + 'route' => 'chill_crud_resource_kind_index', + ]) + ->setExtras([ + 'order' => 7060, + ]); + $menu + ->addChild('admin.menu.Charge types', [ + 'route' => 'chill_crud_charge_kind_index', + ]) + ->setExtras([ + 'order' => 7070, + ]); + } + + public static function getMenuIds(): array + { + return ['admin_section', 'admin_budget']; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php new file mode 100644 index 000000000..9aaf68ddf --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php @@ -0,0 +1,88 @@ +repository = $entityManager->getRepository(ChargeKind::class); + } + + public function find($id): ?ChargeKind + { + return $this->repository->find($id); + } + + /** + * @return array + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array + */ + public function findAllActive(): array + { + $qb = $this->repository->createQueryBuilder('c'); + + return $qb + ->select('c') + ->where($qb->expr()->eq('c.isActive', 'true')) + ->orderBy('c.ordering', 'ASC') + ->getQuery() + ->getResult(); + } + + /** + * @return array + */ + public function findAllByType(string $type): array + { + return $this->findBy(['elementType' => $type]); + } + + /** + * @param mixed|null $limit + * @param mixed|null $offset + * + * @return array + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?ChargeKind + { + return $this->repository->findOneBy($criteria); + } + + public function findOneByKind(string $kind): ?ChargeKind + { + return $this->repository->findOneBy(['kind' => $kind]); + } + + public function getClassName(): string + { + return ChargeKind::class; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php new file mode 100644 index 000000000..f92851eba --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php @@ -0,0 +1,49 @@ + + */ + public function findAll(): array; + + /** + * @return array + */ + public function findAllActive(): array; + + /** + * @return array + */ + public function findAllByType(string $type): array; + + /** + * @param int|null $limit + * @param int|null $offset + * + * @return array + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array; + + public function findOneBy(array $criteria): ?ChargeKind; + + public function findOneByKind(string $kind): ?ChargeKind; + + public function getClassName(): string; +} diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php index b2887bd4d..9b89010dc 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php @@ -11,9 +11,12 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Repository; +use Chill\BudgetBundle\Entity\Charge; +use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use DateTime; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; /** * ChargeRepository. @@ -21,24 +24,44 @@ use Doctrine\ORM\EntityRepository; * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ -class ChargeRepository extends EntityRepository +class ChargeRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Charge::class); + } + + /** + * @return Charge[] + */ + public function findAllByEntity(Person|Household $entity): array + { + $qb = $this->createQueryBuilder('c'); + + $property = $entity instanceof Person ? 'person' : 'household'; + + $qb->where("c.{$property} = :entity") + ->setParameter('entity', $entity); + + return $qb->getQuery()->getResult(); + } + public function findByEntityAndDate($entity, DateTime $date, $sort = null) { $qb = $this->createQueryBuilder('c'); $entityStr = $entity instanceof Person ? 'person' : 'household'; - $qb->where("c.{$entityStr} = :{$entityStr}") - ->andWhere('c.startDate < :date') - ->andWhere('c.startDate < :date OR c.startDate IS NULL'); + $qb->where("c.{$entityStr} = :entity") + ->andWhere('c.startDate <= :date') + ->andWhere('c.endDate > :date OR c.endDate IS NULL'); if (null !== $sort) { $qb->orderBy($sort); } $qb->setParameters([ - $entityStr => $entity, + 'entity' => $entity, 'date' => $date, ]); diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php new file mode 100644 index 000000000..1f9f99753 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php @@ -0,0 +1,88 @@ +repository = $entityManager->getRepository(ResourceKind::class); + } + + public function find($id): ?ResourceKind + { + return $this->repository->find($id); + } + + /** + * @return list + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return list + */ + public function findAllActive(): array + { + $qb = $this->repository->createQueryBuilder('r'); + + return $qb + ->select('r') + ->where($qb->expr()->eq('r.isActive', 'true')) + ->orderBy('r.ordering', 'ASC') + ->getQuery() + ->getResult(); + } + + public function findOneByKind(string $kind): ?ResourceKind + { + return $this->repository->findOneBy(['kind' => $kind]) ; + } + + /** + * @return list + */ + public function findAllByType(string $type): array + { + return $this->findBy(['elementType' => $type]); + } + + /** + * @param mixed|null $limit + * @param mixed|null $offset + * + * @return list + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?ResourceKind + { + return $this->repository->findOneBy($criteria); + } + + public function getClassName(): string + { + return ResourceKind::class; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php new file mode 100644 index 000000000..dac46ff35 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php @@ -0,0 +1,49 @@ + + */ + public function findAll(): array; + + /** + * @return list + */ + public function findAllActive(): array; + + /** + * @return list + */ + public function findAllByType(string $type): array; + + /** + * @param int|null $limit + * @param int|null $offset + * + * @return list + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array; + + public function findOneBy(array $criteria): ?ResourceKind; + + public function findOneByKind(string $kind): ?ResourceKind; + + public function getClassName(): string; +} diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php index 12f9fd52f..836f13e4b 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php @@ -11,9 +11,13 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Repository; +use Chill\BudgetBundle\Entity\Resource; +use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use DateTime; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\EntityRepository; +use Doctrine\Persistence\ManagerRegistry; /** * ResourceRepository. @@ -21,28 +25,45 @@ use Doctrine\ORM\EntityRepository; * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ -class ResourceRepository extends EntityRepository +class ResourceRepository extends ServiceEntityRepository { - public function findByEntityAndDate($entity, DateTime $date, $sort = null) + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Resource::class); + } + + /** + * @return Resource[] + */ + public function findAllByEntity(Person|Household $entity): array + { + $qb = $this->createQueryBuilder('r'); + + $property = $entity instanceof Person ? 'person' : 'household'; + + $qb->where("r.{$property} = :entity") + ->setParameter('entity', $entity); + + return $qb->getQuery()->getResult(); + } + + public function findByEntityAndDate(Person|Household $entity, DateTime $date, $sort = null) { $qb = $this->createQueryBuilder('c'); $entityStr = $entity instanceof Person ? 'person' : 'household'; - $qb->where("c.{$entityStr} = :{$entityStr}") - // TODO: in controller, the budget and charges asked are also for future and actual - //->andWhere('c.startDate < :date') - // TODO: there is a misconception here, the end date must be lower or null. startDate are never null - //->andWhere('c.startDate < :date OR c.startDate IS NULL'); -; + $qb->where("c.{$entityStr} = :entity") + ->andWhere('c.startDate <= :date') + ->andWhere('c.endDate > :date OR c.endDate IS NULL'); if (null !== $sort) { $qb->orderBy($sort); } $qb->setParameters([ - $entityStr => $entity, - //'date' => $date, + 'entity' => $entity, + 'date' => $date, ]); return $qb->getQuery()->getResult(); diff --git a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss index 20a87cce2..79f40dc76 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss +++ b/src/Bundle/ChillBudgetBundle/Resources/public/page/chillbudget.scss @@ -1,39 +1,42 @@ -.subtitle { +h3.subtitle { margin-top: 1rem; margin-bottom: 1rem; padding: 1rem; + &::before { + font: normal normal normal 20px/1 ForkAwesome; + margin-right: 0.5em; + content: "\f061"; + } } -.family-title { + +$col_charge: #e03851d7; +$col_resource: #6d9e63d8; + +h4.family-title { + margin-top: 1.5rem; margin-bottom: 1rem !important; + padding-left: 0.7em; + i { + margin-right: 0.4em; + } + &.charge i { color: $col_charge; } + &.resource i { color: $col_resource; } } .budget-table th { th { color: white; } } -.budget-table { - th.charge { - background-color: #e03851d7; - } -} -.budget-table { - th.resource { - background-color: #6d9e63d8; - } -} -.budget-table { + +table.budget-table { th, td { padding: 10px; text-align: right; } - td.column-wide { - width: 20%; - } - td.column-small { - width: 15%; - &.right { - align-items: right; - } + th.charge { background-color: $col_charge; } + th.resource { background-color: $col_resource; } + td.column-fixed { + width: 9.5em; } } @@ -58,4 +61,4 @@ button[aria-expanded="true"] > span.folded, button[aria-expanded="false"] > span.unfolded { display: none; } button[aria-expanded="false"] > span.folded, -button[aria-expanded="true"] > span.unfolded { display: inline; } \ No newline at end of file +button[aria-expanded="true"] > span.unfolded { display: inline; } diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/edit.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/edit.html.twig new file mode 100644 index 000000000..3a60d3e9c --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/edit.html.twig @@ -0,0 +1,12 @@ +{% extends '@ChillMain/CRUD/Admin/index.html.twig' %} + +{% block title %} + {% include('@ChillMain/CRUD/_edit_title.html.twig') %} +{% endblock %} + +{% block admin_content %} + {% embed '@ChillMain/CRUD/_edit_content.html.twig' %} + {% block content_form_actions_view %}{% endblock %} + {% block content_form_actions_save_and_show %}{% endblock %} + {% endembed %} +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/index.html.twig new file mode 100644 index 000000000..4f56c92cb --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/index.html.twig @@ -0,0 +1,54 @@ +{% extends '@ChillMain/Admin/layoutWithVerticalMenu.html.twig' %} + +{% block title %}{{ 'admin.title.Charge Type List'|trans }}{% endblock title %} + +{% block admin_content %} + +

    {{ 'admin.title.Charge Type List'|trans }}

    + + + + + + + + + + + + {% for entity in entities %} + + + + + + + {% endfor %} + +
    {{ 'Ordering'|trans }}{{ 'Name'|trans }}{{ 'Active'|trans }} 
    {{ entity.ordering }} + {{ entity|chill_entity_render_box }}
    + {{ 'budget.admin.form.Charge_kind_key'|trans }} : {{ entity.kind }} +
    + {%- if entity.isActive -%} + + {%- else -%} + + {%- endif -%} + +
      +
    • + +
    • +
    +
    + + {{ chill_pagination(paginator) }} + + +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/new.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/new.html.twig new file mode 100644 index 000000000..00ebd2938 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Charge/new.html.twig @@ -0,0 +1,11 @@ +{% extends '@ChillMain/CRUD/Admin/index.html.twig' %} + +{% block title %} + {% include('@ChillMain/CRUD/_new_title.html.twig') %} +{% endblock %} + +{% block admin_content %} + {% embed '@ChillMain/CRUD/_new_content.html.twig' %} + {% block content_form_actions_save_and_show %}{% endblock %} + {% endembed %} +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/edit.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/edit.html.twig new file mode 100644 index 000000000..3a60d3e9c --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/edit.html.twig @@ -0,0 +1,12 @@ +{% extends '@ChillMain/CRUD/Admin/index.html.twig' %} + +{% block title %} + {% include('@ChillMain/CRUD/_edit_title.html.twig') %} +{% endblock %} + +{% block admin_content %} + {% embed '@ChillMain/CRUD/_edit_content.html.twig' %} + {% block content_form_actions_view %}{% endblock %} + {% block content_form_actions_save_and_show %}{% endblock %} + {% endembed %} +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/index.html.twig new file mode 100644 index 000000000..62d25c0ca --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/index.html.twig @@ -0,0 +1,54 @@ +{% extends '@ChillMain/Admin/layoutWithVerticalMenu.html.twig' %} + +{% block title %}{{ 'admin.title.Resource Type List'|trans }}{% endblock title %} + +{% block admin_content %} + +

    {{ 'admin.title.Resource Type List'|trans }}

    + + + + + + + + + + + + {% for entity in entities %} + + + + + + + {% endfor %} + +
    {{ 'Ordering'|trans }}{{ 'Name'|trans }}{{ 'Active'|trans }} 
    {{ entity.ordering }} + {{ entity|chill_entity_render_box }}
    + {{ 'budget.admin.form.Resource_kind_key'|trans }} : {{ entity.kind }} +
    + {%- if entity.isActive -%} + + {%- else -%} + + {%- endif -%} + +
      +
    • + +
    • +
    +
    + + {{ chill_pagination(paginator) }} + + +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/new.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/new.html.twig new file mode 100644 index 000000000..00ebd2938 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/Resource/new.html.twig @@ -0,0 +1,11 @@ +{% extends '@ChillMain/CRUD/Admin/index.html.twig' %} + +{% block title %} + {% include('@ChillMain/CRUD/_new_title.html.twig') %} +{% endblock %} + +{% block admin_content %} + {% embed '@ChillMain/CRUD/_new_content.html.twig' %} + {% block content_form_actions_save_and_show %}{% endblock %} + {% endembed %} +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Admin/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/index.html.twig new file mode 100644 index 000000000..0e3beca04 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Admin/index.html.twig @@ -0,0 +1,14 @@ +{% extends "@ChillMain/Admin/layoutWithVerticalMenu.html.twig" %} + +{% block vertical_menu_content %} + {{ chill_menu('admin_budget', { + 'layout': '@ChillMain/Admin/menu_admin_section.html.twig', + }) }} +{% endblock %} + +{% block layout_wvm_content %} + {% block admin_content %} + +

    {{ 'admin.title.Budget configuration'|trans }}

    + {% endblock %} +{% endblock %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig index 6e248bf0c..e75b83ee8 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_budget.html.twig @@ -32,28 +32,21 @@ {% endif %} {% endfor %} -

    {{ 'Actual budget'|trans }}

    - {% if actualCharges|length > 0 or actualResources|length > 0 %} - {% include 'ChillBudgetBundle:Budget:_current_budget.html.twig' with { + {% include '@ChillBudget/Budget/_current_budget.html.twig' with { 'actualResources': actualResources, 'actualCharges': actualCharges, 'results': results, 'entity': entity } %} {% else %} -
    -
    -

    {{ "There isn't any element recorded"|trans }}

    -
    -
    +

    {{ "There isn't any element recorded"|trans }}

    {% endif %} {% if pastCharges|length > 0 or pastResources|length > 0 %} -

    {{ 'Past budget'|trans }}

    - - {% include 'ChillBudgetBundle:Budget:_past_budget.html.twig' with { +

    {{ 'Past budget'|trans }}

    + {% include '@ChillBudget/Budget/_past_budget.html.twig' with { 'pastCharges': pastCharges, 'pastResources': pastResources, 'entity': entity @@ -61,9 +54,8 @@ {% endif %} {% if futureCharges|length > 0 or futureResources|length > 0 %} -

    {{ 'Future budget'|trans }}

    - - {% include 'ChillBudgetBundle:Budget:_future_budget.html.twig' with { +

    {{ 'Future budget'|trans }}

    + {% include '@ChillBudget/Budget/_future_budget.html.twig' with { 'futureResources': futureResources, 'futureCharges': futureCharges, 'entity': entity diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig index b996da211..d8626aee2 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_current_budget.html.twig @@ -1,30 +1,17 @@ -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} - -{#

    {{ 'Actual budget'|trans }}

    #} - -
    -

    {{ 'Actual resources'|trans }}

    +{% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} +
    +

    {{ 'Actual resources'|trans }}

    {% if actualResources|length > 0 %} -
    {{ table_elements(actualResources, 'resource') }} -
    {% else %} -
    {{ 'No resources registered'|trans }} -
    {% endif %} -
    -
    -

    {{ 'Actual charges'|trans }}

    +

    {{ 'Actual charges'|trans }}

    {% if actualCharges|length > 0 %} -
    {{ table_elements(actualCharges, 'charge') }} -
    {% else %} -
    {{ 'No charges registered'|trans }} -
    {% endif %}
    diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig index 1547d8749..62f4e3e96 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig @@ -20,32 +20,23 @@ aria-labelledby="heading_future_{{ entity.id }}" data-bs-parent="#future_{{ entity.id }}"> -
    -

    {{ 'Future resources'|trans }}

    +
    +

    {{ 'Future resources'|trans }}

    {% if futureResources|length > 0 %} -
    - {{ table_elements(futureResources, 'resource') }} -
    + {{ table_elements(futureResources, 'resource') }} {% else %} -
    - {{ 'No future resources registered'|trans }} -
    + {{ 'No future resources registered'|trans }} {% endif %} -
    -
    -

    {{ 'Future charges'|trans }}

    + +

    {{ 'Future charges'|trans }}

    {% if futureCharges|length > 0 %} -
    - {{ table_elements(futureCharges, 'charge') }} -
    + {{ table_elements(futureCharges, 'charge') }} {% else %} -
    - {{ 'No future charges registered'|trans }} -
    + {{ 'No future charges registered'|trans }} {% endif %}
    - \ No newline at end of file + diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig index 41b6f36df..70e96d96c 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_macros.html.twig @@ -1,5 +1,5 @@ {% macro table_elements(elements, family) %} - +
    @@ -13,21 +13,22 @@ {% for f in elements %} {% set total = total + f.amount %} - - - + -
    {{ 'Budget element type'|trans }}
    - - - {{ f.type|budget_element_type_display(family) }} - + + {% if f.isResource %} + {{ f.resource.name|localize_translatable_string }} + {% else %} + {{ f.charge.name|localize_translatable_string }} + {% endif %} {{ f.amount|format_currency('EUR') }} + {{ f.amount|format_currency('EUR') }} {% if f.endDate is not null %} {{ f.startDate|format_date('short') ~ ' - ' ~ f.endDate|format_date('short') }} {% else %} - {{ f.startDate|format_date('short') ~ ' - ...' }} + {{ 'depuis le ' ~ f.startDate|format_date('short') }} {% endif %} +
      {% if is_granted('CHILL_BUDGET_ELEMENT_SEE', f) %}
    • @@ -76,10 +77,9 @@ {% set result = (totalResources - totalCharges) %} - +
      - @@ -87,7 +87,6 @@ - diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig index 14573048e..ad0a12755 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig @@ -20,34 +20,24 @@ aria-labelledby="heading_past_{{ entity.id }}" data-bs-parent="#past_{{ entity.id }}"> -
      -

      {{ 'Past resources'|trans }}

      +
      +

      {{ 'Past resources'|trans }}

      {% if pastResources|length > 0 %} -
      - {{ table_elements(pastResources, 'resource') }} -
      + {{ table_elements(pastResources, 'resource') }} {% else %} -
      - {{ 'No past resources registered'|trans }} -
      + {{ 'No past resources registered'|trans }} {% endif %} -
      -
      -

      {{ 'Past charges'|trans }}

      +

      {{ 'Past charges'|trans }}

      {% if pastCharges|length > 0 %} -
      - {{ table_elements(pastCharges, 'charge') }} -
      + {{ table_elements(pastCharges, 'charge') }} {% else %} -
      - {{ 'No past charges registered'|trans }} -
      + {{ 'No past charges registered'|trans }} {% endif %}
      - \ No newline at end of file + diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig index f64184d6f..7a97731da 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig @@ -3,13 +3,13 @@ {% set indexPage = 'chill_budget_elements_index' %} {% set activeRouteKey = '' %} {% set person = element.person %} - {% set confirm_question = 'Are you sure you want to remove the charge "%type%" associated to "%name%" ?'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname, '%type%': element.type|budget_element_type_display('charge') } ) %} + {% set confirm_question = 'Are you sure you want to remove the charge "%type%" associated to "%name%" ?'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname, '%type%': element.charge.getName | localize_translatable_string } ) %} {% else %} {% set template = '@ChillPerson/Household/layout.html.twig' %} {% set indexPage = 'chill_budget_elements_household_index' %} {% set activeRouteKey = '' %} {% set household = element.household %} - {% set confirm_question = 'Are you sure you want to remove the charge "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.type|budget_element_type_display('charge') } ) %} + {% set confirm_question = 'Are you sure you want to remove the charge "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.charge.getName | localize_translatable_string } ) %} {% endif %} {% extends template %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/edit.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/edit.html.twig index fed80a5c0..ab68314d6 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/edit.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/edit.html.twig @@ -21,7 +21,7 @@ {{ form_start(form) }} -{{ form_row(form.type) }} +{{ form_row(form.charge) }} {{ form_row(form.amount) }} {{ form_row(form.help) }} {{ form_row(form.comment) }} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/new.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/new.html.twig index 817d501ca..bdd7334bb 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/new.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/new.html.twig @@ -20,7 +20,7 @@ {{ form_start(form) }} -{{ form_row(form.type) }} +{{ form_row(form.charge) }} {{ form_row(form.amount) }} {{ form_row(form.help) }} {{ form_row(form.comment) }} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/view.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/view.html.twig index d3b9ef71b..509c421b0 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/view.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/view.html.twig @@ -25,7 +25,7 @@

      - {{ element.type|budget_element_type_display('charge') }} + {{ element.charge.getName | localize_translatable_string }}

      diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Entity/budget_element_type.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Entity/budget_element_type.html.twig new file mode 100644 index 000000000..f2187a8b8 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Entity/budget_element_type.html.twig @@ -0,0 +1 @@ +{{ entity.name|localize_translatable_string }} \ No newline at end of file diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig index c2533e4c0..1df92b297 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig @@ -24,16 +24,14 @@ } %} {# -
      -

      {{ 'Budget calculator'|trans }}

      -
      - {{ table_results(wholeCharges, wholeResources) }} -
      +
      +

      {{ 'Budget calculator'|trans }}

      + {{ table_results(wholeCharges, wholeResources) }}
      #} {% if household.getCurrentMembers|length > 0 %} -

      {{ 'Current budget household members'|trans }}

      +

      {{ 'Budget household members'|trans }}

      {% for hm in household.getCurrentMembers %} {% set member = hm.person %} @@ -57,6 +55,8 @@ aria-labelledby="heading_{{ member.id }}" data-bs-parent="#nonCurrent"> +

      {{ 'Budget for %name%'|trans({'%name%': member.firstName ~ " " ~ member.lastName }) }}

      + {% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { 'resources': member.getBudgetResources, 'charges': member.getBudgetCharges, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index 959df3d62..18d04b889 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -17,17 +17,15 @@ {% block content %}

      {{ title }}

      -{% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { +{% include '@ChillBudget/Budget/_budget.html.twig' with { 'resources': resources, 'charges': charges, 'person': person } %} -
      -

      {{ 'Budget calculator'|trans }}

      -
      - {{ table_results(charges, resources) }} -
      +
      +

      {{ 'Budget calculator'|trans }}

      + {{ table_results(charges, resources) }}
      {% if is_granted('CHILL_BUDGET_ELEMENT_CREATE', person) %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig index 73ae173ff..5c2e80e10 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig @@ -3,13 +3,13 @@ {% set indexPage = 'chill_budget_elements_index' %} {% set activeRouteKey = '' %} {% set person = element.person %} - {% set confirm_question = 'Are you sure you want to remove the ressource "%type%" associated to "%name%" ?'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname, '%type%': element.type|budget_element_type_display('resource') } ) %} + {% set confirm_question = 'Are you sure you want to remove the ressource "%type%" associated to "%name%" ?'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname, '%type%': element.resource.getName | localize_translatable_string } ) %} {% else %} {% set template = '@ChillPerson/Household/layout.html.twig' %} {% set indexPage = 'chill_budget_elements_household_index' %} {% set activeRouteKey = '' %} {% set household = element.household %} - {% set confirm_question = 'Are you sure you want to remove the ressource "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.type|budget_element_type_display('resource') } ) %} + {% set confirm_question = 'Are you sure you want to remove the resource "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.resource.getName | localize_translatable_string} ) %} {% endif %} {% extends template %} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/edit.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/edit.html.twig index 8b051eeaf..85cf7e8e4 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/edit.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/edit.html.twig @@ -23,7 +23,7 @@ {{ form_start(form) }} -{{ form_row(form.type) }} +{{ form_row(form.resource) }} {{ form_row(form.amount) }} {{ form_row(form.comment) }} {{ form_row(form.startDate) }} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/new.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/new.html.twig index 4ea71f4de..5c1b63d12 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/new.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/new.html.twig @@ -22,8 +22,7 @@

      {{ title }}

      {{ form_start(form) }} - -{{ form_row(form.type) }} +{{ form_row(form.resource) }} {{ form_row(form.amount) }} {{ form_row(form.comment) }} {{ form_row(form.startDate) }} diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/view.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/view.html.twig index 110aed9fe..c3618b498 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/view.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/view.html.twig @@ -25,7 +25,7 @@

      - {{ element.type|budget_element_type_display('resource') }} + {{ element.resource.getName | localize_translatable_string }}

      diff --git a/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php b/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php index 0a428d324..5203f9092 100644 --- a/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php +++ b/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php @@ -20,7 +20,7 @@ use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use function in_array; +use UnexpectedValueException; class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { @@ -68,12 +68,29 @@ class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierar protected function supports($attribute, $subject) { - return (in_array($attribute, self::ROLES, true) && $subject instanceof AbstractElement) - || (($subject instanceof Person || $subject instanceof Household) && in_array($attribute, [self::SEE, self::CREATE], true)); + return $this->voter->supports($attribute, $subject); } protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { - return $this->voter->voteOnAttribute($attribute, $subject, $token); + if ( + $subject instanceof Person + || ($subject instanceof AbstractElement && null !== $person = $subject->getPerson())) { + return $this->voter->voteOnAttribute($attribute, $person ?? $subject, $token); + } + + if ( + $subject instanceof Household + || ($subject instanceof AbstractElement && null !== $household = $subject->getHousehold())) { + foreach (($household ?? $subject)->getCurrentPersons() as $person) { + if ($this->voter->voteOnAttribute($attribute, $person, $token)) { + return true; + } + } + + return false; + } + + throw new UnexpectedValueException('This subject is not supported, or is an element not associated with person or household'); } } diff --git a/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php b/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php index f02d2e64a..1c66d4c1c 100644 --- a/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php +++ b/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php @@ -11,45 +11,50 @@ declare(strict_types=1); namespace Chill\BudgetBundle\Service\Summary; -use Chill\BudgetBundle\Config\ConfigRepository; +use Chill\BudgetBundle\Entity\ChargeKind; +use Chill\BudgetBundle\Entity\ResourceKind; +use Chill\BudgetBundle\Repository\ChargeKindRepositoryInterface; +use Chill\BudgetBundle\Repository\ResourceKindRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query\ResultSetMapping; use LogicException; +use RuntimeException; use function count; /** * Helps to find a summary of the budget: the sum of resources and charges. */ -class SummaryBudget implements SummaryBudgetInterface +final class SummaryBudget implements SummaryBudgetInterface { - private const QUERY_CHARGE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.charge WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; + private const QUERY_CHARGE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, charge_id AS kind_id FROM chill_budget.charge WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY charge_id'; - private const QUERY_CHARGE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.charge WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; + private const QUERY_CHARGE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, charge_id AS kind_id FROM chill_budget.charge WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY charge_id'; - private const QUERY_RESOURCE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.resource WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; + private const QUERY_RESOURCE_BY_HOUSEHOLD = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, resource_id AS kind_id FROM chill_budget.resource WHERE (person_id IN (_ids_) OR household_id = ?) AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY resource_id'; - private const QUERY_RESOURCE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, type FROM chill_budget.resource WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY type'; + private const QUERY_RESOURCE_BY_PERSON = 'select SUM(amount) AS sum, string_agg(comment, \'|\') AS comment, resource_id AS kind_id FROM chill_budget.resource WHERE person_id = ? AND NOW() BETWEEN startdate AND COALESCE(enddate, \'infinity\'::timestamp) GROUP BY resource_id'; - private array $chargeLabels; - - private ConfigRepository $configRepository; + private ChargeKindRepositoryInterface $chargeKindRepository; private EntityManagerInterface $em; - private array $resourcesLabels; + private ResourceKindRepositoryInterface $resourceKindRepository; private TranslatableStringHelperInterface $translatableStringHelper; - public function __construct(EntityManagerInterface $em, ConfigRepository $configRepository, TranslatableStringHelperInterface $translatableStringHelper) - { + public function __construct( + EntityManagerInterface $em, + TranslatableStringHelperInterface $translatableStringHelper, + ResourceKindRepositoryInterface $resourceKindRepository, + ChargeKindRepositoryInterface $chargeKindRepository + ) { $this->em = $em; - $this->configRepository = $configRepository; - $this->chargeLabels = $configRepository->getChargesLabels(); - $this->resourcesLabels = $configRepository->getResourcesLabels(); $this->translatableStringHelper = $translatableStringHelper; + $this->resourceKindRepository = $resourceKindRepository; + $this->chargeKindRepository = $chargeKindRepository; } public function getSummaryForHousehold(?Household $household): array @@ -61,9 +66,7 @@ class SummaryBudget implements SummaryBudgetInterface ]; } - $personIds = $household->getCurrentPersons()->map(static function (Person $p) { - return $p->getId(); - }); + $personIds = $household->getCurrentPersons()->map(static fn (Person $p) => $p->getId()); $ids = implode(', ', array_fill(0, count($personIds), '?')); $parameters = [...$personIds, $household->getId()]; @@ -112,7 +115,7 @@ class SummaryBudget implements SummaryBudgetInterface $rsm = new ResultSetMapping(); $rsm ->addScalarResult('sum', 'sum') - ->addScalarResult('type', 'type') + ->addScalarResult('kind_id', 'kind_id') ->addScalarResult('comment', 'comment'); return $rsm; @@ -120,51 +123,58 @@ class SummaryBudget implements SummaryBudgetInterface private function getEmptyChargeArray(): array { - $keys = $this->configRepository->getChargesKeys(); - $labels = $this->chargeLabels; + $keys = array_map(static fn (ChargeKind $kind) => $kind->getKind(), $this->chargeKindRepository->findAll()); - return array_combine($keys, array_map(function ($i) use ($labels) { - return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i]), 'comment' => '']; - }, $keys)); + return array_combine($keys, array_map(fn ($kind) => ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($this->chargeKindRepository->findOneByKind($kind)->getName()), 'comment' => ''], $keys)); } private function getEmptyResourceArray(): array { - $keys = $this->configRepository->getResourcesKeys(); - $labels = $this->resourcesLabels; + $keys = array_map(static fn (ResourceKind $kind) => $kind->getKind(), $this->resourceKindRepository->findAll()); - return array_combine($keys, array_map(function ($i) use ($labels) { - return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($labels[$i]), 'comment' => '']; - }, $keys)); + return array_combine($keys, array_map(fn ($kind) => ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($this->resourceKindRepository->findOneByKind($kind)->getName()), 'comment' => ''], $keys)); } private function rowToArray(array $rows, string $kind): array { + $result = []; + switch ($kind) { case 'charge': - $label = $this->chargeLabels; + foreach ($rows as $row) { + $chargeKind = $this->chargeKindRepository->find($row['kind_id']); - break; + if (null === $chargeKind) { + throw new RuntimeException('charge kind not found: ' . $row['kind_id']); + } + $result[$chargeKind->getKind()] = [ + 'sum' => (float) $row['sum'], + 'label' => $this->translatableStringHelper->localize($chargeKind->getName()), + 'comment' => (string) $row['comment'], + ]; + } + + return $result; case 'resource': - $label = $this->resourcesLabels; + foreach ($rows as $row) { + $resourceKind = $this->resourceKindRepository->find($row['kind_id']); - break; + if (null === $resourceKind) { + throw new RuntimeException('charge kind not found: ' . $row['kind_id']); + } + + $result[$resourceKind->getKind()] = [ + 'sum' => (float) $row['sum'], + 'label' => $this->translatableStringHelper->localize($resourceKind->getName()), + 'comment' => (string) $row['comment'], + ]; + } + + return $result; default: throw new LogicException(); } - - $result = []; - - foreach ($rows as $row) { - $result[$row['type']] = [ - 'sum' => (float) $row['sum'], - 'label' => $this->translatableStringHelper->localize($label[$row['type']]), - 'comment' => (string) $row['comment'], - ]; - } - - return $result; } } diff --git a/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php b/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php new file mode 100644 index 000000000..842e6be4e --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php @@ -0,0 +1,58 @@ + + */ +final class BudgetElementTypeRender implements ChillEntityRenderInterface +{ + private EngineInterface $engine; + + private TranslatableStringHelperInterface $translatableStringHelper; + + public function __construct(TranslatableStringHelperInterface $translatableStringHelper, EngineInterface $engine) + { + $this->translatableStringHelper = $translatableStringHelper; + $this->engine = $engine; + } + + public function renderBox($entity, array $options): string + { + return $this->engine->render('@ChillBudget/Entity/budget_element_type.html.twig', [ + 'entity' => $entity, + 'options' => $options, + ]); + } + + public function renderString($entity, array $options): string + { + $title = ''; + + if (null !== $entity->getName()) { + return $this->translatableStringHelper->localize($entity->getName()); + } + + return $title; + } + + public function supports($entity, array $options): bool + { + return $entity instanceof ChargeKind || $entity instanceof ResourceKind; + } +} diff --git a/src/Bundle/ChillBudgetBundle/Templating/Twig.php b/src/Bundle/ChillBudgetBundle/Templating/Twig.php deleted file mode 100644 index b4395f375..000000000 --- a/src/Bundle/ChillBudgetBundle/Templating/Twig.php +++ /dev/null @@ -1,65 +0,0 @@ -configRepository = $configRepository; - $this->translatableStringHelper = $translatableStringHelper; - } - - public function displayLink($link, $family) - { - switch ($family) { - case 'resource': - return $this->translatableStringHelper->localize( - $this->configRepository->getResourcesLabels()[$link] - ); - - case 'charge': - return $this->translatableStringHelper->localize( - $this->configRepository->getChargesLabels()[$link] - ); - - default: - throw new UnexpectedValueException("This family of element: {$family} is not " - . "supported. Supported families are 'resource', 'charge'"); - } - } - - public function getFilters() - { - return [ - new TwigFilter('budget_element_type_display', [$this, 'displayLink'], ['is_safe' => ['html']]), - ]; - } -} diff --git a/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php b/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php new file mode 100644 index 000000000..77017abc5 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php @@ -0,0 +1,153 @@ +prophesize(AbstractQuery::class); + $queryCharges->getResult()->willReturn([ + [ + 'sum' => 250.0, + 'comment' => '', + 'kind_id' => 1, // kind: rental + ], + ]); + $queryCharges->setParameters(Argument::type('array')) + ->will(static fn ($args, $query) => $query); + + $queryResources = $this->prophesize(AbstractQuery::class); + $queryResources->getResult()->willReturn([ + [ + 'sum' => 1500.0, + 'comment' => '', + 'kind_id' => 2, // kind: 'salary', + ], + ]); + $queryResources->setParameters(Argument::type('array')) + ->will(static fn ($args, $query) => $query); + + $em = $this->prophesize(EntityManagerInterface::class); + $em->createNativeQuery(Argument::type('string'), Argument::type(Query\ResultSetMapping::class)) + ->will(static function ($args) use ($queryResources, $queryCharges) { + if (false !== strpos($args[0], 'chill_budget.resource')) { + return $queryResources->reveal(); + } + + if (false !== strpos($args[0], 'chill_budget.charge')) { + return $queryCharges->reveal(); + } + + throw new RuntimeException('this query does not have a stub counterpart: ' . $args[0]); + }); + + $chargeRepository = $this->prophesize(ChargeKindRepositoryInterface::class); + $chargeRepository->findAll()->willReturn([ + $rental = (new ChargeKind())->setKind('rental')->setName(['fr' => 'Rental']), + $other = (new ChargeKind())->setKind('other')->setName(['fr' => 'Other']), + ]); + $chargeRepository->find(1)->willReturn($rental); + $chargeRepository->findOneByKind('rental')->willReturn($rental); + $chargeRepository->findOneByKind('other')->willReturn($other); + + $resourceRepository = $this->prophesize(ResourceKindRepositoryInterface::class); + $resourceRepository->findAll()->willReturn([ + $salary = (new ResourceKind())->setKind('salary')->setName(['fr' => 'Salary']), + $misc = (new ResourceKind())->setKind('misc')->setName(['fr' => 'Misc']), + ]); + $resourceRepository->find(2)->willReturn($salary); + $resourceRepository->findOneByKind('salary')->willReturn($salary); + $resourceRepository->findOneByKind('misc')->willReturn($misc); + + $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class); + $translatableStringHelper->localize(Argument::type('array'))->will(static fn ($arg) => $arg[0]['fr']); + + $person = new Person(); + $personReflection = new ReflectionClass($person); + $personIdReflection = $personReflection->getProperty('id'); + $personIdReflection->setAccessible(true); + $personIdReflection->setValue($person, 1); + + $household = new Household(); + $householdReflection = new ReflectionClass($household); + $householdId = $householdReflection->getProperty('id'); + $householdId->setAccessible(true); + $householdId->setValue($household, 1); + $householdMember = (new HouseholdMember())->setPerson($person) + ->setStartDate(new DateTimeImmutable('1 month ago')); + $household->addMember($householdMember); + + $summaryBudget = new SummaryBudget( + $em->reveal(), + $translatableStringHelper->reveal(), + $resourceRepository->reveal(), + $chargeRepository->reveal() + ); + + $summary = $summaryBudget->getSummaryForPerson($person); + $summaryForHousehold = $summaryBudget->getSummaryForHousehold($household); + + // we check the structure for the summary. The structure is the same for household + // and persons + + $expected = [ + 'charges' => [ + 'rental' => ['sum' => 250.0, 'comment' => '', 'label' => 'Rental'], + 'other' => ['sum' => 0.0, 'comment' => '', 'label' => 'Other'], + ], + 'resources' => [ + 'salary' => ['sum' => 1500.0, 'comment' => '', 'label' => 'Salary'], + 'misc' => ['sum' => 0.0, 'comment' => '', 'label' => 'Misc'], + ], + ]; + + foreach ([$summaryForHousehold, $summary] as $summary) { + $this->assertIsArray($summary); + $this->assertEqualsCanonicalizing(['charges', 'resources'], array_keys($summary)); + $this->assertEqualsCanonicalizing(['rental', 'other'], array_keys($summary['charges'])); + $this->assertEqualsCanonicalizing(['salary', 'misc'], array_keys($summary['resources'])); + + foreach ($expected as $resCha => $contains) { + foreach ($contains as $kind => $row) { + $this->assertEqualsCanonicalizing($row, $summary[$resCha][$kind]); + } + } + } + } +} diff --git a/src/Bundle/ChillBudgetBundle/config/services/config.yaml b/src/Bundle/ChillBudgetBundle/config/services/config.yaml deleted file mode 100644 index 21136db2f..000000000 --- a/src/Bundle/ChillBudgetBundle/config/services/config.yaml +++ /dev/null @@ -1,5 +0,0 @@ -services: - Chill\BudgetBundle\Config\ConfigRepository: - arguments: - $resources: '%chill_budget.resources%' - $charges: '%chill_budget.charges%' diff --git a/src/Bundle/ChillBudgetBundle/config/services/controller.yaml b/src/Bundle/ChillBudgetBundle/config/services/controller.yaml index 82c683536..ae6fb84d6 100644 --- a/src/Bundle/ChillBudgetBundle/config/services/controller.yaml +++ b/src/Bundle/ChillBudgetBundle/config/services/controller.yaml @@ -3,3 +3,7 @@ services: autowire: true resource: '../../Controller' tags: ['controller.service_arguments'] + Chill\BudgetBundle\Controller\Admin\: + autowire: true + autoconfigure: true + resource: '../../Controller/Admin' diff --git a/src/Bundle/ChillBudgetBundle/config/services/form.yaml b/src/Bundle/ChillBudgetBundle/config/services/form.yaml index 63862ce94..a033413d0 100644 --- a/src/Bundle/ChillBudgetBundle/config/services/form.yaml +++ b/src/Bundle/ChillBudgetBundle/config/services/form.yaml @@ -1,14 +1,9 @@ services: - Chill\BudgetBundle\Form\ResourceType: - arguments: - $configRepository: '@Chill\BudgetBundle\Config\ConfigRepository' - $translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper' - tags: - - { name: 'form.type' } - - Chill\BudgetBundle\Form\ChargeType: - arguments: - $configRepository: '@Chill\BudgetBundle\Config\ConfigRepository' - $translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper' + Chill\BudgetBundle\Form\: + autowire: true + resource: '../../Form' tags: - { name: 'form.type' } +# Chill\BudgetBundle\Form\Admin\: +# autowire: true +# resource: '../../Form/Admin' diff --git a/src/Bundle/ChillBudgetBundle/config/services/menu.yaml b/src/Bundle/ChillBudgetBundle/config/services/menu.yaml index 34128519b..ba8b301d5 100644 --- a/src/Bundle/ChillBudgetBundle/config/services/menu.yaml +++ b/src/Bundle/ChillBudgetBundle/config/services/menu.yaml @@ -1,8 +1,5 @@ services: - Chill\BudgetBundle\Menu\PersonMenuBuilder: - autowire: true - autoconfigure: true - - Chill\BudgetBundle\Menu\HouseholdMenuBuilder: + Chill\BudgetBundle\Menu\: autowire: true autoconfigure: true + resource: './../../Menu' diff --git a/src/Bundle/ChillBudgetBundle/config/services/repository.yaml b/src/Bundle/ChillBudgetBundle/config/services/repository.yaml new file mode 100644 index 000000000..7205a8378 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/config/services/repository.yaml @@ -0,0 +1,5 @@ +services: + Chill\BudgetBundle\Repository\: + autowire: true + autoconfigure: true + resource: './../../Repository' \ No newline at end of file diff --git a/src/Bundle/ChillBudgetBundle/config/services/templating.yaml b/src/Bundle/ChillBudgetBundle/config/services/templating.yaml index 903db5d67..2646f3892 100644 --- a/src/Bundle/ChillBudgetBundle/config/services/templating.yaml +++ b/src/Bundle/ChillBudgetBundle/config/services/templating.yaml @@ -1,7 +1,5 @@ services: - Chill\BudgetBundle\Templating\Twig: - arguments: - $configRepository: '@Chill\BudgetBundle\Config\ConfigRepository' - $translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper' - tags: - - { name: 'twig.extension' } \ No newline at end of file + Chill\BudgetBundle\Templating\: + autowire: true + autoconfigure: true + resource: '../../Templating' diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20221116163445.php b/src/Bundle/ChillBudgetBundle/migrations/Version20221116163445.php new file mode 100644 index 000000000..118b7c30d --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20221116163445.php @@ -0,0 +1,39 @@ +addSql('DROP SEQUENCE chill_budget.charge_type_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE chill_budget.resource_type_id_seq CASCADE'); + $this->addSql('DROP TABLE chill_budget.charge_type'); + $this->addSql('DROP TABLE chill_budget.resource_type'); + } + + public function getDescription(): string + { + return 'Create resource type and charge type'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE SEQUENCE chill_budget.charge_type_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE chill_budget.resource_type_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE chill_budget.charge_type (id INT NOT NULL, isActive BOOLEAN DEFAULT TRUE NOT NULL, name JSONB DEFAULT \'{}\'::jsonb NOT NULL, ordering DOUBLE PRECISION DEFAULT \'0\' NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE chill_budget.resource_type (id INT NOT NULL, isActive BOOLEAN DEFAULT TRUE NOT NULL, name JSONB DEFAULT \'{}\'::jsonb NOT NULL, ordering DOUBLE PRECISION DEFAULT \'0\' NOT NULL, PRIMARY KEY(id))'); + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20221130101659.php b/src/Bundle/ChillBudgetBundle/migrations/Version20221130101659.php new file mode 100644 index 000000000..98d67b341 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20221130101659.php @@ -0,0 +1,41 @@ +addSql('ALTER TABLE chill_budget.resource_type DROP kind'); + $this->addSql('ALTER TABLE chill_budget.resource_type DROP tags'); + $this->addSql('ALTER TABLE chill_budget.charge_type DROP kind'); + $this->addSql('ALTER TABLE chill_budget.charge_type DROP tags'); + } + + public function getDescription(): string + { + return 'Add kind and tags property to charge and resource types'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_budget.charge_type ADD kind VARCHAR(255) DEFAULT \'\' NOT NULL'); + $this->addSql('ALTER TABLE chill_budget.charge_type ADD tags JSONB DEFAULT \'{}\'::jsonb NOT NULL'); + $this->addSql('COMMENT ON COLUMN chill_budget.charge_type.tags IS \'(DC2Type:jsonb)\''); + $this->addSql('ALTER TABLE chill_budget.resource_type ADD kind VARCHAR(255) DEFAULT \'\' NOT NULL'); + $this->addSql('ALTER TABLE chill_budget.resource_type ADD tags JSONB DEFAULT \'{}\'::jsonb NOT NULL'); + $this->addSql('COMMENT ON COLUMN chill_budget.resource_type.tags IS \'(DC2Type:jsonb)\''); + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20221202165608.php b/src/Bundle/ChillBudgetBundle/migrations/Version20221202165608.php new file mode 100644 index 000000000..c2152100b --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20221202165608.php @@ -0,0 +1,41 @@ +addSql('ALTER TABLE chill_budget.charge DROP CONSTRAINT FK_5C99D2C355284914'); + $this->addSql('ALTER TABLE chill_budget.charge DROP charge_id'); + $this->addSql('ALTER TABLE chill_budget.resource DROP CONSTRAINT FK_5E0A5E9789329D25'); + $this->addSql('ALTER TABLE chill_budget.resource DROP resource_id'); + } + + public function getDescription(): string + { + return 'Integrate budget admin entity'; + } + + public function up(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_budget.charge ADD charge_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_budget.charge ADD CONSTRAINT FK_5C99D2C355284914 FOREIGN KEY (charge_id) REFERENCES chill_budget.charge_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_5C99D2C355284914 ON chill_budget.charge (charge_id)'); + $this->addSql('ALTER TABLE chill_budget.resource ADD resource_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_budget.resource ADD CONSTRAINT FK_5E0A5E9789329D25 FOREIGN KEY (resource_id) REFERENCES chill_budget.resource_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_5E0A5E9789329D25 ON chill_budget.resource (resource_id)'); + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php b/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php new file mode 100644 index 000000000..cfe3a0089 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php @@ -0,0 +1,81 @@ +addSql('DELETE FROM chill_budget.resource_type;'); + $this->addSql('DELETE FROM chill_budget.charge_type;'); + } + + public function getDescription(): string + { + return 'Use new budget admin entities'; + } + + public function setContainer(?ContainerInterface $container = null) + { + $this->container = $container; + } + + public function up(Schema $schema): void + { + $resources = $this->container->getParameter('chill_budget.resources'); + $charges = $this->container->getParameter('chill_budget.charges'); + + foreach ($resources as $value) { + $lang = $value['labels'][0]['lang']; + $label = $value['labels'][0]['label']; + $kind = $value['key']; + $this->addSql( + 'INSERT INTO chill_budget.resource_type (id, isActive, name, ordering, kind) VALUES ( + nextval(\'chill_budget.resource_type_id_seq\'), true, jsonb_build_object(:lang::text, :label::text), 0, :kind::text)', + ['lang' => $lang, 'label' => $label, 'kind' => $kind], + ['lang' => Types::STRING, 'label' => Types::STRING, 'kind' => Types::STRING] + ); + $this->addSql( + 'UPDATE chill_budget.resource SET resource_id = resource_type.id + FROM chill_budget.resource_type WHERE resource.type = :kind AND resource_type.kind = resource.type;', + ['kind' => $kind], + ['kind' => Types::STRING] + ); + } + + foreach ($charges as $value) { + $lang = $value['labels'][0]['lang']; + $label = $value['labels'][0]['label']; + $kind = $value['key']; + $this->addSql( + 'INSERT INTO chill_budget.charge_type VALUES (nextval(\'chill_budget.charge_type_id_seq\'), true, + jsonb_build_object(:lang::text, :label::text), 0, :kind::text);', + ['lang' => $lang, 'label' => $label, 'kind' => $kind], + ['lang' => Types::STRING, 'label' => Types::STRING, 'kind' => Types::STRING] + ); + $this->addSql( + 'UPDATE chill_budget.charge SET charge_id = charge_type.id + FROM chill_budget.charge_type WHERE charge.type = :kind AND charge_type.kind = charge.type;', + ['kind' => $kind], + ['kind' => Types::STRING] + ); + } + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20230201131008.php b/src/Bundle/ChillBudgetBundle/migrations/Version20230201131008.php new file mode 100644 index 000000000..7131c31f2 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20230201131008.php @@ -0,0 +1,37 @@ +addSql('COMMENT ON COLUMN chill_budget.resource_type.tags IS \'(DC2Type:json)\''); + $this->addSql('COMMENT ON COLUMN chill_budget.charge_type.tags IS \'(DC2Type:json)\''); + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20230209161546.php b/src/Bundle/ChillBudgetBundle/migrations/Version20230209161546.php new file mode 100644 index 000000000..4495db8a7 --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20230209161546.php @@ -0,0 +1,37 @@ +addSql('DROP INDEX resource_kind_unique_type_idx'); + $this->addSql('DROP INDEX charge_kind_unique_type_idx'); + } + + public function getDescription(): string + { + return 'Budget: add unique constraint on kind for charge_kind and resource_kind'; + } + + public function up(Schema $schema): void + { + $this->addSql("UPDATE chill_budget.resource_type SET kind=md5(random()::text) WHERE kind = ''"); + $this->addSql("UPDATE chill_budget.charge_type SET kind=md5(random()::text) WHERE kind = ''"); + $this->addSql('CREATE UNIQUE INDEX resource_kind_unique_type_idx ON chill_budget.resource_type (kind);'); + $this->addSql('CREATE UNIQUE INDEX charge_kind_unique_type_idx ON chill_budget.charge_type (kind);'); + } +} diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20230328155010.php b/src/Bundle/ChillBudgetBundle/migrations/Version20230328155010.php new file mode 100644 index 000000000..ed524940e --- /dev/null +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20230328155010.php @@ -0,0 +1,56 @@ +addSql(<<<'SQL' + WITH type_to_id AS ( + SELECT DISTINCT charge.charge_id AS id, charge.type + FROM chill_budget.charge + WHERE type <> '' + ) + UPDATE chill_budget.charge_type + SET kind = type_to_id.type + FROM type_to_id + WHERE type_to_id.type <> '' AND type_to_id.id = charge_type.id + SQL); + + $this->addSql(<<<'SQL' + WITH type_to_id AS ( + SELECT DISTINCT resource.resource_id AS id, resource.type + FROM chill_budget. resource + WHERE type <> '' + ) + UPDATE chill_budget.resource_type + SET kind = type_to_id.type + FROM type_to_id + WHERE type_to_id.type <> '' AND type_to_id.id = resource_type.id + SQL); + } + + public function down(Schema $schema): void + { + $this->addSql("UPDATE chill_budget.resource_type SET kind=md5(random()::text) WHERE kind = ''"); + $this->addSql("UPDATE chill_budget.charge_type SET kind=md5(random()::text) WHERE kind = ''"); + } +} diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml index 299fa295e..2ff258aea 100644 --- a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml @@ -3,23 +3,23 @@ Resource: Ressource Charge: Charge Budget for %name%: Budget de %name% Budget for household %household%: Budget du ménage -Current budget household members: Budget actuel des membres du ménage +Budget household members: Budget des membres du ménage Show budget of %name%: Montrer budget de %name% See complete budget: Voir budget complet Hide budget: Masquer Hide budget of %name%: Masquer budget de %name% Resource element type: Nature de la ressource -Actual budget: Éléments actuels du budget +Actual budget: Éléments actuels Actual resources: Ressources actuelles Actual resources for %name%: Ressources actuelles de %name% Actual charges for %name%: Charges actuelles de %name% Actual charges: Charges actuelles -Past budget: Éléments du budget passé +Past budget: Éléments passés Show past budget: Montrer budget passé Show future budget: Montrer budget future Past resources: Ressources passées Past charges: Charges passées -Future budget: Futurs éléments du budget +Future budget: Éléments futurs Future resources: Ressources futures Future charges: Charges futures Budget element type: Nature @@ -29,7 +29,7 @@ End of validity period: Fin de la période de validité Total: Total Create new resource: Créer une nouvelle ressource Create new charge: Créer une nouvelle charge -See person: Voir personne +See person: Voir usagers There isn't any element recorded: Aucun élément enregistré No resources registered: Aucune ressource enregistrée @@ -49,6 +49,8 @@ Remove resource: Supprimer la ressource Remove charge: Supprimer la charge Are you sure you want to remove the ressource "%type%" associated to "%name%" ?: Êtes-vous sûr·e de vouloir supprimer la ressource de nature "%type%" associée à %name% ? Are you sure you want to remove the charge "%type%" associated to "%name%" ?: Êtes-vous sûr·e de vouloir supprimer la charge de nature "%type%" associée à %name% ? +Are you sure you want to remove the charge "%type%" associated to household "%household%" ?: Êtes-vous sur·e de vouloir supprimer la charge "%type%" associée au ménage ? +Are you sure you want to remove the resource "%type%" associated to household "%household%" ?: Êtes-vous sur·e de vouloir supprimer la ressource "%type%" associée au ménage ? Resource deleted: Ressource supprimée Charge deleted: Charge supprimée Charge created: Charge créée @@ -58,6 +60,8 @@ Charge updated: charge mise à jour Choose a resource type: Choisissez un type de ressource Choose a charge type: Choisissez un type de charge +Resource type: Type de ressource +Charge type: Type de charge Amount: Montant Comment: Commentaire @@ -74,3 +78,42 @@ The balance: Différence entre ressources et charges Valid since %startDate% until %endDate%: Valide depuis le %startDate% jusqu'au %endDate% Valid since %startDate%: Valide depuis le %startDate% + +budget: + admin: + form: + Charge_kind_key: Clé d'identification + Resource_kind_key: Clé d'identification + This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document: Cette clé sert à identifier le type de charge ou de revenu lors de la génération de document. Seuls les caractères alpha-numériques sont autorisés. Modifier cette clé peut avoir un effet lors de la génération de nouveaux documents. + +# ROLES +Budget elements: Budget +CHILL_BUDGET_ELEMENT_CREATE: Créer une ressource/charge +CHILL_BUDGET_ELEMENT_DELETE: Supprimer une ressource/charge +CHILL_BUDGET_ELEMENT_SEE: Voir les ressources/charges +CHILL_BUDGET_ELEMENT_UPDATE: Modifier une ressource/charge + +## admin + +crud: + resource_kind: + title_new: Nouveau type de ressource + title_edit: Modifier le type de ressource + charge_kind: + title_new: Nouveau type de charge + title_edit: Modifier le type de charge + +admin: + menu: + Resource types: Types de ressource + Charge types: Types de charge + title: + Charge Type List: Liste des types de charge + Resource Type List: Liste des types de ressource + Budget configuration: Configuration des éléments de budget + new: + Create a new charge type: Créér un nouveau type de charge + Create a new resource type: Créér un nouveau type de ressource + form: + Choose the type of resource: Choisissez une type de ressource + Choose the type of charge: Choisissez une type de charge diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.nl.yml b/src/Bundle/ChillBudgetBundle/translations/messages.nl.yml index 5fd21520d..de334f79f 100644 --- a/src/Bundle/ChillBudgetBundle/translations/messages.nl.yml +++ b/src/Bundle/ChillBudgetBundle/translations/messages.nl.yml @@ -2,8 +2,8 @@ Budget: Budget Resource: Inkomsten Charge: Onkosten Budget for %name%: Budget van %name% -Budget for household %household%: Budget van gezin -Current budget household members: Actuele budget van gezinsleden +Budget for household %household%: Budget van huishouden +Current budget household members: Actuele budget van leden huishouden Show budget of %name%: Toon budget van %name% See complete budget: Toon volledige budget Hide budget: Verbergen diff --git a/src/Bundle/ChillBudgetBundle/translations/validators.fr.yml b/src/Bundle/ChillBudgetBundle/translations/validators.fr.yml index 7281b6380..01b240eac 100644 --- a/src/Bundle/ChillBudgetBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillBudgetBundle/translations/validators.fr.yml @@ -1,2 +1,8 @@ The amount cannot be empty: Le montant ne peut pas être vide ou égal à zéro -The budget element's end date must be after the start date: La date de fin doit être après la date de début \ No newline at end of file +The budget element's end date must be after the start date: La date de fin doit être après la date de début + +budget: + admin: + form: + kind: + only_alphanumeric diff --git a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php index 902fe4c38..b90fb83d4 100644 --- a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php +++ b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php @@ -60,7 +60,7 @@ class MapAndSubscribeUserCalendarCommand extends Command public function execute(InputInterface $input, OutputInterface $output): int { - $this->logger->info(__CLASS__ . ' execute command'); + $this->logger->info(self::class . ' execute command'); $limit = 50; $offset = 0; @@ -71,12 +71,12 @@ class MapAndSubscribeUserCalendarCommand extends Command $created = 0; $renewed = 0; - $this->logger->info(__CLASS__ . ' the number of user to get - renew', [ + $this->logger->info(self::class . ' the number of user to get - renew', [ 'total' => $total, 'expiration' => $expiration->format(DateTimeImmutable::ATOM), ]); - while ($offset < ($total - 1)) { + while ($offset < $total) { $users = $this->userRepository->findByMostOldSubscriptionOrWithoutSubscriptionOrData( $interval, $limit, @@ -92,7 +92,7 @@ class MapAndSubscribeUserCalendarCommand extends Command // we first try to renew an existing subscription, if any. // if not, or if it fails, we try to create a new one if ($this->mapCalendarToUser->hasActiveSubscription($user)) { - $this->logger->debug(__CLASS__ . ' renew a subscription for', [ + $this->logger->debug(self::class . ' renew a subscription for', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -104,7 +104,7 @@ class MapAndSubscribeUserCalendarCommand extends Command if (0 !== $expirationTs) { ++$renewed; } else { - $this->logger->warning(__CLASS__ . ' could not renew subscription for a user', [ + $this->logger->warning(self::class . ' could not renew subscription for a user', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -112,7 +112,7 @@ class MapAndSubscribeUserCalendarCommand extends Command } if (!$this->mapCalendarToUser->hasActiveSubscription($user)) { - $this->logger->debug(__CLASS__ . ' create a subscription for', [ + $this->logger->debug(self::class . ' create a subscription for', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -124,7 +124,7 @@ class MapAndSubscribeUserCalendarCommand extends Command if (0 !== $expirationTs) { ++$created; } else { - $this->logger->warning(__CLASS__ . ' could not create subscription for a user', [ + $this->logger->warning(self::class . ' could not create subscription for a user', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -139,7 +139,7 @@ class MapAndSubscribeUserCalendarCommand extends Command $this->em->clear(); } - $this->logger->warning(__CLASS__ . ' process executed', [ + $this->logger->warning(self::class . ' process executed', [ 'created' => $created, 'renewed' => $renewed, ]); diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index db5f2ec16..eed693451 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -45,6 +45,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class CalendarController extends AbstractController { @@ -68,6 +69,8 @@ class CalendarController extends AbstractController private TranslatableStringHelperInterface $translatableStringHelper; + private TranslatorInterface $translator; + private UserRepositoryInterface $userRepository; public function __construct( @@ -81,7 +84,8 @@ class CalendarController extends AbstractController TranslatableStringHelperInterface $translatableStringHelper, PersonRepository $personRepository, AccompanyingPeriodRepository $accompanyingPeriodRepository, - UserRepositoryInterface $userRepository + UserRepositoryInterface $userRepository, + TranslatorInterface $translator ) { $this->calendarACLAwareRepository = $calendarACLAwareRepository; $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; @@ -94,6 +98,7 @@ class CalendarController extends AbstractController $this->personRepository = $personRepository; $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; $this->userRepository = $userRepository; + $this->translator = $translator; } /** @@ -131,7 +136,7 @@ class CalendarController extends AbstractController $em->remove($entity); $em->flush(); - $this->addFlash('success', $this->get('translator') + $this->addFlash('success', $this->translator ->trans('The calendar item has been successfully removed.')); return new RedirectResponse($redirectRoute); @@ -190,7 +195,7 @@ class CalendarController extends AbstractController if ($form->isSubmitted() && $form->isValid()) { $em->flush(); - $this->addFlash('success', $this->get('translator')->trans('Success : calendar item updated!')); + $this->addFlash('success', $this->translator->trans('Success : calendar item updated!')); if ($form->get('save_and_upload_doc')->isClicked()) { return $this->redirectToRoute('chill_calendar_calendardoc_new', ['id' => $entity->getId()]); @@ -202,6 +207,7 @@ class CalendarController extends AbstractController 'entityClassName' => Calendar::class, 'entityId' => $entity->getId(), 'template' => $template->getId(), + 'returnPath' => $request->getRequestUri(), ]); } } @@ -210,7 +216,7 @@ class CalendarController extends AbstractController } if ($form->isSubmitted() && !$form->isValid()) { - $this->addFlash('error', $this->get('translator')->trans('This form contains errors')); + $this->addFlash('error', $this->translator->trans('This form contains errors')); } $entity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); @@ -369,10 +375,12 @@ class CalendarController extends AbstractController $em->persist($entity); $em->flush(); - $this->addFlash('success', $this->get('translator')->trans('Success : calendar item created!')); + $this->addFlash('success', $this->translator->trans('Success : calendar item created!')); if ($form->get('save_and_upload_doc')->isClicked()) { - return $this->redirectToRoute('chill_calendar_calendardoc_new', ['id' => $entity->getId()]); + return $this->redirectToRoute('chill_calendar_calendardoc_new', [ + 'id' => $entity->getId() + ]); } foreach ($templates as $template) { @@ -381,6 +389,7 @@ class CalendarController extends AbstractController 'entityClassName' => Calendar::class, 'entityId' => $entity->getId(), 'template' => $template->getId(), + 'returnPath' => $this->generateUrl('chill_calendar_calendar_edit', ['id' => $entity->getId()]), ]); } } @@ -393,7 +402,7 @@ class CalendarController extends AbstractController } if ($form->isSubmitted() && !$form->isValid()) { - $this->addFlash('error', $this->get('translator')->trans('This form contains errors')); + $this->addFlash('error', $this->translator->trans('This form contains errors')); } if (null === $view) { @@ -521,14 +530,20 @@ class CalendarController extends AbstractController 'comment' => $calendar->getComment()->getComment(), ]; - return $this->redirectToRoute( - 'chill_activity_activity_new', - [ - 'accompanying_period_id' => $calendar->getAccompanyingPeriod()->getId(), - 'activityData' => $activityData, - 'returnPath' => $request->query->get('returnPath', null), - ] - ); + $routeParams = [ + 'activityData' => $activityData, + 'returnPath' => $request->query->get('returnPath', null), + ]; + + if ($calendar->getContext() === 'accompanying_period') { + $routeParams['accompanying_period_id'] = $calendar->getAccompanyingPeriod()->getId(); + } elseif ($calendar->getContext() === 'person') { + $routeParams['person_id'] = $calendar->getPerson()->getId(); + } else { + throw new RuntimeException('context not found for this calendar'); + } + + return $this->redirectToRoute('chill_activity_activity_new', $routeParams); } private function buildListFilterOrder(): FilterOrderHelper @@ -539,21 +554,6 @@ class CalendarController extends AbstractController return $filterOrder->build(); } - private function buildParamsToUrl(?User $user, ?AccompanyingPeriod $accompanyingPeriod): array - { - $params = []; - - if (null !== $user) { - $params['user_id'] = $user->getId(); - } - - if (null !== $accompanyingPeriod) { - $params['id'] = $accompanyingPeriod->getId(); - } - - return $params; - } - /** * Creates a form to delete a Calendar entity by id. */ diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php index 74f8d93e9..d02e55f32 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php @@ -145,6 +145,9 @@ class CalendarDocController $returnParams = ['id' => $calendarDoc->getCalendar()->getPerson()->getId()]; break; + + default: + throw new \LogicException(sprintf("This context '%s' is not supported", $calendarDoc->getCalendar()->getContext())); } $form = $this->formFactory->createBuilder() diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php index a1226ca6a..805386669 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php @@ -61,7 +61,7 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere ->setEmail('centreA@test.chill.social') ->setLocationType($type = new LocationType()) ->setPhonenumber1(PhoneNumberUtil::getInstance()->parse('+3287653812')); - $type->setTitle('Service'); + $type->setTitle(['fr' => 'Service']); $address->setStreet('Rue des Épaules')->setStreetNumber('14') ->setPostcode($postCode = new PostalCode()); $postCode->setCode('4145')->setName('Houte-Si-Plout')->setCountry( diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php index 25b8ae8a8..ba325e296 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Chill\CalendarBundle\DataFixtures\ORM; use Chill\CalendarBundle\Entity\Invite; +use Chill\MainBundle\DataFixtures\ORM\LoadUsers; +use Chill\MainBundle\Entity\User; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; use Doctrine\Persistence\ObjectManager; @@ -33,14 +35,21 @@ class LoadInvite extends Fixture implements FixtureGroupInterface public function load(ObjectManager $manager): void { $arr = [ - ['name' => ['fr' => 'Rendez-vous décliné']], - ['name' => ['fr' => 'Rendez-vous accepté']], + [ + 'name' => ['fr' => 'Rendez-vous décliné'], + 'status' => Invite::DECLINED, + ], + [ + 'name' => ['fr' => 'Rendez-vous accepté'], + 'status' => Invite::ACCEPTED, + ], ]; foreach ($arr as $a) { echo 'Creating calendar invite : ' . $a['name']['fr'] . "\n"; $invite = (new Invite()) - ->setStatus($a['name']); + ->setStatus($a['status']) + ->setUser($this->getRandomUser()); $manager->persist($invite); $reference = 'Invite_' . $a['name']['fr']; $this->addReference($reference, $invite); @@ -49,4 +58,11 @@ class LoadInvite extends Fixture implements FixtureGroupInterface $manager->flush(); } + + private function getRandomUser(): User + { + $userRef = array_rand(LoadUsers::$refs); + + return $this->getReference($userRef); + } } diff --git a/src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php index 127b69047..a3e4ae391 100644 --- a/src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillCalendarBundle/DependencyInjection/Configuration.php @@ -24,7 +24,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_calendar'); - $rootNode = $treeBuilder->getRootNode('chill_calendar'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index 0f112cf36..79219a6e0 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -29,6 +29,7 @@ use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\ReadableCollection; use Doctrine\ORM\Mapping as ORM; use LogicException; use Symfony\Component\Serializer\Annotation as Serializer; @@ -92,6 +93,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod", inversedBy="calendars") + * @Serializer\Groups({"calendar:read", "read"}) */ private ?AccompanyingPeriod $accompanyingPeriod = null; @@ -507,12 +509,12 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente } /** - * @return Collection|User[] + * @return ReadableCollection<(int|string), User> * @Serializer\Groups({"calendar:read", "read"}) */ - public function getUsers(): Collection + public function getUsers(): ReadableCollection { - return $this->getInvites()->map(static function (Invite $i) { return $i->getUser(); }); + return $this->getInvites()->map(static fn (Invite $i) => $i->getUser()); } public function hasCalendarRange(): bool @@ -597,7 +599,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente } $invite = $this->invites - ->filter(static function (Invite $invite) use ($user) { return $invite->getUser() === $user; }) + ->filter(static fn (Invite $invite) => $invite->getUser() === $user) ->first(); $this->removeInvite($invite); diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php index 14cfad98b..5dbc4286f 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php @@ -63,7 +63,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface * @Groups({"read", "write", "calendar:read"}) * @Assert\NotNull */ - private ?Location $location; + private ?Location $location = null; /** * @ORM\Column(type="datetime_immutable", nullable=false) diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 9b0ad9057..e1de9f399 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -66,6 +66,10 @@ final class AgentAggregator implements AggregatorInterface return 'Agent'; } + if (null === $value || '' === $value) { + return ''; + } + $r = $this->userRepository->find($value); return $this->userRender->renderString($r, []); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index 329e2e50e..611cb6d79 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -67,6 +67,10 @@ class CancelReasonAggregator implements AggregatorInterface return 'Cancel reason'; } + if (null === $value || '' === $value) { + return ''; + } + $j = $this->cancelReasonRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 2a6f3b63e..23292a5b0 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -66,6 +66,10 @@ final class JobAggregator implements AggregatorInterface return 'Job'; } + if (null === $value || '' === $value) { + return ''; + } + $j = $this->jobRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 687dc9096..940000f47 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -60,6 +60,10 @@ final class LocationAggregator implements AggregatorInterface return 'Location'; } + if (null === $value || '' === $value) { + return ''; + } + $l = $this->locationRepository->find($value); return $l->getName(); diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index b23b304f6..6574e3934 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -66,7 +66,13 @@ final class LocationTypeAggregator implements AggregatorInterface return 'Location type'; } - $j = $this->locationTypeRepository->find($value); + if (null === $value || '' === $value) { + return ''; + } + + if (null === $j = $this->locationTypeRepository->find($value)) { + return ''; + } return $this->translatableStringHelper->localize( $j->getTitle() diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index b16b06d84..3aff3e0d8 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -66,6 +66,10 @@ final class ScopeAggregator implements AggregatorInterface return 'Scope'; } + if (null === $value || '' === $value) { + return ''; + } + $s = $this->scopeRepository->find($value); return $this->translatableStringHelper->localize( diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php index a80653441..ad5910461 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php @@ -44,14 +44,7 @@ class UrgencyAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { $qb->addSelect('cal.urgent AS urgency_aggregator'); - - $groupBy = $qb->getDQLPart('groupBy'); - - if (!empty($groupBy)) { - $qb->addGroupBy('urgency_aggregator'); - } else { - $qb->groupBy('urgency_aggregator'); - } + $qb->addGroupBy('urgency_aggregator'); } public function applyOn(): string diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index 06d6defca..9d3f00f99 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -52,7 +52,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface return 'Exports of calendar'; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data) { if ('export_result' !== $key) { throw new LogicException("the key {$key} is not used by this export"); @@ -61,9 +61,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface $labels = array_combine($values, $values); $labels['_header'] = $this->getTitle(); - return static function ($value) use ($labels) { - return $labels[$value]; - }; + return static fn ($value) => $labels[$value]; } public function getQueryKeys($data): array @@ -91,9 +89,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface */ public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder { - $centers = array_map(static function ($el) { - return $el['center']; - }, $acl); + $centers = array_map(static fn ($el) => $el['center'], $acl); $qb = $this->calendarRepository->createQueryBuilder('cal'); diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index ddecba415..14dd42d6b 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -61,9 +61,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface $labels = array_combine($values, $values); $labels['_header'] = $this->getTitle(); - return static function ($value) use ($labels) { - return $labels[$value]; - }; + return static fn ($value) => $labels[$value]; } public function getQueryKeys($data): array diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index d99e73a2e..1d31bfa26 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -61,9 +61,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface $labels = array_combine($values, $values); $labels['_header'] = $this->getTitle(); - return static function ($value) use ($labels) { - return $labels[$value]; - }; + return static fn ($value) => $labels[$value]; } public function getQueryKeys($data): array diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index 18a4b0f4b..b58cee594 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -58,9 +58,7 @@ class AgentFilter implements FilterInterface { $builder->add('accepted_agents', EntityType::class, [ 'class' => User::class, - 'choice_label' => function (User $u) { - return $this->userRender->renderString($u, []); - }, + 'choice_label' => fn (User $u) => $this->userRender->renderString($u, []), 'multiple' => true, 'expanded' => true, ]); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php index fde867b64..d6c38e163 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php @@ -49,23 +49,11 @@ class CalendarRangeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - $where = $qb->getDQLPart('where'); - - dump($data); - - if ($data['hasCalendarRange']) { - $clause = $qb->expr()->isNotNull('cal.calendarRange'); + if (null !== $data['hasCalendarRange']) { + $qb->andWhere($qb->expr()->isNotNull('cal.calendarRange')); } else { - $clause = $qb->expr()->isNull('cal.calendarRange'); + $qb->andWhere($qb->expr()->isNull('cal.calendarRange')); } - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); } public function applyOn(): string @@ -87,6 +75,8 @@ class CalendarRangeFilter implements FilterInterface public function describeAction($data, $format = 'string'): array { + $choice = ''; + foreach (self::CHOICES as $k => $v) { if ($v === $data['hasCalendarRange']) { $choice = $k; diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index 0f0f42adc..69fb24447 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -69,11 +69,9 @@ class JobFilter implements FilterInterface { $builder->add('job', EntityType::class, [ 'class' => UserJob::class, - 'choice_label' => function (UserJob $j) { - return $this->translatableStringHelper->localize( - $j->getLabel() - ); - }, + 'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize( + $j->getLabel() + ), 'multiple' => true, 'expanded' => true, ]); diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index 4d84543a3..08d9ae023 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -69,11 +69,9 @@ class ScopeFilter implements FilterInterface { $builder->add('scope', EntityType::class, [ 'class' => Scope::class, - 'choice_label' => function (Scope $s) { - return $this->translatableStringHelper->localize( - $s->getName() - ); - }, + 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( + $s->getName() + ), 'multiple' => true, 'expanded' => true, ]); diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php index 26a9d59e2..34a501028 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php @@ -26,9 +26,6 @@ class CalendarDocEditType extends AbstractType ->add('title', TextType::class, [ 'label' => 'chill_calendar.Document title', 'required' => true, - ]) - ->add('doc', StoredObjectType::class, [ - 'label' => 'chill_calendar.Document object', ]); } diff --git a/src/Bundle/ChillCalendarBundle/Menu/AdminMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/AdminMenuBuilder.php index ad00609e2..1658029a7 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/AdminMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/AdminMenuBuilder.php @@ -39,7 +39,6 @@ class AdminMenuBuilder implements LocalMenuBuilderInterface ->setAttribute('class', 'list-group-item-header') ->setExtras([ 'order' => 6000, - 'icons' => ['calendar'], ]); $menu->addChild('Cancel reason', [ diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php index 94ba4974c..f97cbc7b2 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php @@ -22,6 +22,9 @@ use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Messenger\Message\CalendarMessage; use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage; use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PostPersistEventArgs; +use Doctrine\ORM\Event\PostRemoveEventArgs; +use Doctrine\ORM\Event\PostUpdateEventArgs; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Security\Core\Security; @@ -37,7 +40,7 @@ class CalendarEntityListener $this->security = $security; } - public function postPersist(Calendar $calendar, LifecycleEventArgs $args): void + public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void { if (!$calendar->preventEnqueueChanges) { $this->messageBus->dispatch( @@ -50,7 +53,7 @@ class CalendarEntityListener } } - public function postRemove(Calendar $calendar, LifecycleEventArgs $args): void + public function postRemove(Calendar $calendar, PostRemoveEventArgs $args): void { if (!$calendar->preventEnqueueChanges) { $this->messageBus->dispatch( @@ -62,7 +65,7 @@ class CalendarEntityListener } } - public function postUpdate(Calendar $calendar, LifecycleEventArgs $args): void + public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void { if (!$calendar->preventEnqueueChanges) { $this->messageBus->dispatch( diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php index 7628c7af4..4df548277 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php @@ -22,6 +22,9 @@ use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\Messenger\Message\CalendarRangeMessage; use Chill\CalendarBundle\Messenger\Message\CalendarRangeRemovedMessage; use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PostPersistEventArgs; +use Doctrine\ORM\Event\PostRemoveEventArgs; +use Doctrine\ORM\Event\PostUpdateEventArgs; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Security\Core\Security; @@ -37,7 +40,7 @@ class CalendarRangeEntityListener $this->security = $security; } - public function postPersist(CalendarRange $calendarRange, LifecycleEventArgs $eventArgs): void + public function postPersist(CalendarRange $calendarRange, PostPersistEventArgs $eventArgs): void { if (!$calendarRange->preventEnqueueChanges) { $this->messageBus->dispatch( @@ -50,7 +53,7 @@ class CalendarRangeEntityListener } } - public function postRemove(CalendarRange $calendarRange, LifecycleEventArgs $eventArgs): void + public function postRemove(CalendarRange $calendarRange, PostRemoveEventArgs $eventArgs): void { if (!$calendarRange->preventEnqueueChanges) { $this->messageBus->dispatch( @@ -62,7 +65,7 @@ class CalendarRangeEntityListener } } - public function postUpdate(CalendarRange $calendarRange, LifecycleEventArgs $eventArgs): void + public function postUpdate(CalendarRange $calendarRange, PostUpdateEventArgs $eventArgs): void { if (!$calendarRange->preventEnqueueChanges) { $this->messageBus->dispatch( diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php index 361fd33c2..eabdf9063 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php @@ -89,10 +89,10 @@ class CalendarToRemoteHandler implements MessageHandlerInterface $newInvites = array_filter( array_map( - function ($id) { return $this->inviteRepository->find($id); }, + fn ($id) => $this->inviteRepository->find($id), $calendarMessage->getNewInvitesIds(), ), - static function (?Invite $invite) { return null !== $invite; } + static fn (?Invite $invite) => null !== $invite ); $this->calendarConnector->syncCalendar( diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php index 9c1e84511..a09c70c1e 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php @@ -77,7 +77,7 @@ class MSGraphChangeNotificationHandler implements MessageHandlerInterface $user = $this->userRepository->find($changeNotificationMessage->getUserId()); if (null === $user) { - $this->logger->warning(__CLASS__ . ' notification concern non-existent user, skipping'); + $this->logger->warning(self::class . ' notification concern non-existent user, skipping'); return; } @@ -86,7 +86,7 @@ class MSGraphChangeNotificationHandler implements MessageHandlerInterface $secret = $this->mapCalendarToUser->getSubscriptionSecret($user); if ($secret !== ($notification['clientState'] ?? -1)) { - $this->logger->warning(__CLASS__ . ' could not validate secret, skipping'); + $this->logger->warning(self::class . ' could not validate secret, skipping'); continue; } @@ -101,7 +101,7 @@ class MSGraphChangeNotificationHandler implements MessageHandlerInterface $this->calendarSyncer->handleCalendarSync($calendar, $notification, $user); $this->em->flush(); } else { - $this->logger->info(__CLASS__ . ' id not found in any calendar nor calendar range'); + $this->logger->info(self::class . ' id not found in any calendar nor calendar range'); } } diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php index ec5977ad3..c8a8f8aeb 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php @@ -58,14 +58,12 @@ class CalendarMessage $this->previousMainUserId = null !== $calendar->previousMainUser ? $calendar->previousMainUser->getId() : null; $this->newInvitesIds = array_map(static fn (Invite $i) => $i->getId(), $calendar->newInvites); - $this->oldInvites = array_map(static function (Invite $i) { - return [ - 'inviteId' => $i->getId(), - 'userId' => $i->getUser()->getId(), - 'userEmail' => $i->getUser()->getEmail(), - 'userLabel' => $i->getUser()->getLabel(), - ]; - }, $calendar->oldInvites); + $this->oldInvites = array_map(static fn (Invite $i) => [ + 'inviteId' => $i->getId(), + 'userId' => $i->getUser()->getId(), + 'userEmail' => $i->getUser()->getEmail(), + 'userLabel' => $i->getUser()->getLabel(), + ], $calendar->oldInvites); } public function getAction(): string diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php index 504d48ffc..563bd3a38 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php @@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\User; use DateTimeImmutable; use LogicException; use Psr\Log\LoggerInterface; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use function array_key_exists; @@ -74,9 +75,18 @@ class MapCalendarToUser public function getDefaultUserCalendar(string $idOrUserPrincipalName): ?array { - $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [ - 'query' => ['$filter' => 'isDefaultCalendar eq true'], - ])->toArray()['value']; + try { + $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [ + 'query' => ['$filter' => 'isDefaultCalendar eq true'], + ])->toArray()['value']; + } catch (ClientExceptionInterface $e) { + $this->logger->error('[MapCalendarToUser] Error while listing calendars for a user', [ + 'http_status_code' => $e->getResponse()->getStatusCode(), + 'id_user' => $idOrUserPrincipalName, + ]); + + return null; + } return $value[0] ?? null; } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php index ac1de552a..176dbe0b0 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php @@ -121,9 +121,7 @@ class RemoteEventConverter 'subject' => '[Chill] ' . implode( ', ', - $calendar->getPersons()->map(function (Person $p) { - return $this->personRender->renderString($p, []); - })->toArray() + $calendar->getPersons()->map(fn (Person $p) => $this->personRender->renderString($p, []))->toArray() ), 'start' => [ 'dateTime' => $calendar->getStartDate()->setTimezone($this->remoteDateTimeZone) @@ -161,9 +159,7 @@ class RemoteEventConverter { return [ 'attendees' => $calendar->getInvites()->map( - function (Invite $i) { - return $this->buildInviteToAttendee($i); - } + fn (Invite $i) => $this->buildInviteToAttendee($i) )->toArray(), ]; } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php index a9227282d..d05adfed7 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php @@ -59,7 +59,7 @@ class CalendarRangeSyncer } $calendarRange->preventEnqueueChanges = true; - $this->logger->info(__CLASS__ . ' remove a calendar range because deleted on remote calendar'); + $this->logger->info(self::class . ' remove a calendar range because deleted on remote calendar'); $this->em->remove($calendarRange); break; @@ -71,7 +71,7 @@ class CalendarRangeSyncer $notification['resource'] )->toArray(); } catch (ClientExceptionInterface $clientException) { - $this->logger->warning(__CLASS__ . ' could not retrieve event from ms graph. Already deleted ?', [ + $this->logger->warning(self::class . ' could not retrieve event from ms graph. Already deleted ?', [ 'calendarRangeId' => $calendarRange->getId(), 'remoteEventId' => $notification['resource'], ]); @@ -82,7 +82,7 @@ class CalendarRangeSyncer $lastModified = RemoteEventConverter::convertStringDateWithTimezone($new['lastModifiedDateTime']); if ($calendarRange->getRemoteAttributes()['lastModifiedDateTime'] === $lastModified->getTimestamp()) { - $this->logger->info(__CLASS__ . ' change key is equals. Source is probably a local update', [ + $this->logger->info(self::class . ' change key is equals. Source is probably a local update', [ 'calendarRangeId' => $calendarRange->getId(), 'remoteEventId' => $notification['resource'], ]); diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php index 984e77d87..b3febf4d4 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php @@ -79,7 +79,7 @@ class CalendarSyncer $notification['resource'] )->toArray(); } catch (ClientExceptionInterface $clientException) { - $this->logger->warning(__CLASS__ . ' could not retrieve event from ms graph. Already deleted ?', [ + $this->logger->warning(self::class . ' could not retrieve event from ms graph. Already deleted ?', [ 'calendarId' => $calendar->getId(), 'remoteEventId' => $notification['resource'], ]); @@ -96,7 +96,7 @@ class CalendarSyncer ); if ($calendar->getRemoteAttributes()['lastModifiedDateTime'] === $lastModified->getTimestamp()) { - $this->logger->info(__CLASS__ . ' change key is equals. Source is probably a local update', [ + $this->logger->info(self::class . ' change key is equals. Source is probably a local update', [ 'calendarRangeId' => $calendar->getId(), 'remoteEventId' => $notification['resource'], ]); @@ -110,11 +110,11 @@ class CalendarSyncer $endDate = RemoteEventConverter::convertStringDateWithoutTimezone($new['end']['dateTime']); if ($startDate->getTimestamp() !== $calendar->getStartDate()->getTimestamp()) { - $calendar->setStartDate($startDate)->setStatus(Calendar::STATUS_MOVED); + $calendar->setStartDate($startDate); } if ($endDate->getTimestamp() !== $calendar->getEndDate()->getTimestamp()) { - $calendar->setEndDate($endDate)->setStatus(Calendar::STATUS_MOVED); + $calendar->setEndDate($endDate); } $calendar diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php index c376f9680..0e3beff5f 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php @@ -34,6 +34,7 @@ use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -64,6 +65,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface private OnBehalfOfUserHttpClient $userHttpClient; + private Security $security; + public function __construct( CalendarRepository $calendarRepository, CalendarRangeRepository $calendarRangeRepository, @@ -74,7 +77,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface OnBehalfOfUserHttpClient $userHttpClient, RemoteEventConverter $remoteEventConverter, TranslatorInterface $translator, - UrlGeneratorInterface $urlGenerator + UrlGeneratorInterface $urlGenerator, + Security $security ) { $this->calendarRepository = $calendarRepository; $this->calendarRangeRepository = $calendarRangeRepository; @@ -86,6 +90,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $this->translator = $translator; $this->urlGenerator = $urlGenerator; $this->userHttpClient = $userHttpClient; + $this->security = $security; } public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int @@ -102,8 +107,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface 'users/' . $userId . '/calendarView', [ 'query' => [ - 'startDateTime' => $startDate->format(DateTimeImmutable::ATOM), - 'endDateTime' => $endDate->format(DateTimeImmutable::ATOM), + 'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), + 'endDateTime' => $endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), '$count' => 'true', '$top' => 0, ], @@ -133,6 +138,24 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface public function isReady(): bool { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + // this is not a user from chill. This is not the role of this class to + // restrict access, so we will just say that we do not have to do anything more + // here... + return true; + } + + if (null === $this->mapCalendarToUser->getUserId($user)) { + // this user is not mapped with remote calendar. The user will have to wait for + // the next calendar subscription iteration + $this->logger->debug('mark user ready for msgraph calendar as he does not have any mapping', [ + 'userId' => $user->getId(), + ]); + return true; + } + return $this->tokenStorage->hasToken(); } @@ -158,8 +181,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface 'users/' . $userId . '/calendarView', [ 'query' => [ - 'startDateTime' => $startDate->format(DateTimeImmutable::ATOM), - 'endDateTime' => $endDate->format(DateTimeImmutable::ATOM), + 'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), + 'endDateTime' => $endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), '$select' => 'id,subject,start,end,isAllDay', '$top' => $limit, '$skip' => $offset, @@ -167,21 +190,17 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface ] )->toArray(); - $ids = array_map(static function ($item) { return $item['id']; }, $bareEvents['value']); + $ids = array_map(static fn ($item) => $item['id'], $bareEvents['value']); $existingIdsInRange = $this->calendarRangeRepository->findRemoteIdsPresent($ids); $existingIdsInCalendar = $this->calendarRepository->findRemoteIdsPresent($ids); return array_values( array_map( - function ($item) { - return $this->remoteEventConverter->convertToRemote($item); - }, + fn ($item) => $this->remoteEventConverter->convertToRemote($item), // filter all event to keep only the one not in range array_filter( $bareEvents['value'], - static function ($item) use ($existingIdsInRange, $existingIdsInCalendar) { - return ((!$existingIdsInRange[$item['id']]) ?? true) && ((!$existingIdsInCalendar[$item['id']]) ?? true); - } + static fn ($item) => ((!$existingIdsInRange[$item['id']]) ?? true) && ((!$existingIdsInCalendar[$item['id']]) ?? true) ) ) ); @@ -514,10 +533,13 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $userId = $this->mapCalendarToUser->getUserId($user); if (null === $userId) { - throw new Exception('no remote calendar for this user', [ - 'user' => $user->getId(), - 'remoteId' => $remoteId, - ]); + throw new Exception( + sprintf( + 'no remote calendar for this user: %s, remoteid: %s', + $user->getId(), + $remoteId + ) + ); } try { @@ -576,9 +598,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface } $this->cacheScheduleTimeForUser[$userId] = array_map( - function ($item) { - return $this->remoteEventConverter->convertAvailabilityToRemoteEvent($item); - }, + fn ($item) => $this->remoteEventConverter->convertAvailabilityToRemoteEvent($item), $response['value'][0]['scheduleItems'] ); diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php index 6861df341..7c6ef4e13 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php @@ -215,7 +215,7 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface $qb ->where( $qb->expr()->orX( - // the calendar where the person is the main person: + // the calendar where the person is the main person: $qb->expr()->eq('c.person', ':person'), // when the calendar is in a reachable period, and contains person $qb->expr()->andX( diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/types.ts b/src/Bundle/ChillCalendarBundle/Resources/public/types.ts index ebc7ab7be..c18cfea13 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/types.ts +++ b/src/Bundle/ChillCalendarBundle/Resources/public/types.ts @@ -1,4 +1,4 @@ -import {EventInput} from '@fullcalendar/vue3'; +import {EventInput} from '@fullcalendar/core'; import {DateTime, Location, User, UserAssociatedInterface} from '../../../ChillMainBundle/Resources/public/types' ; import {Person} from "../../../ChillPersonBundle/Resources/public/types"; diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue index 472bb525b..e09175a4b 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue @@ -15,6 +15,7 @@ :picked="null !== this.$store.getters.getMainUser ? [this.$store.getters.getMainUser] : []" :removableIfSet="false" :displayPicked="false" + :suggested="this.suggestedUsers" @addNewEntity="setMainUser" >
      @@ -116,7 +117,6 @@ + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/README.md b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/README.md new file mode 100644 index 000000000..2d10dace8 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/README.md @@ -0,0 +1,5 @@ +# About buttons and components available + +## DocumentActionButtonsGroup + +This is an component to use to render a group of button with actions linked to a document. diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue new file mode 100644 index 000000000..aa99a223f --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/ConvertButton.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue new file mode 100644 index 000000000..f05d1e91c --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/DownloadButton.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue new file mode 100644 index 000000000..d68f60f86 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue @@ -0,0 +1,44 @@ + + + + + + diff --git a/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts new file mode 100644 index 000000000..5b61a108d --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/helpers.ts @@ -0,0 +1,193 @@ +import {StoredObject, StoredObjectStatus, StoredObjectStatusChange} from "../../types"; + +const MIMES_EDIT = new Set([ + 'application/vnd.ms-powerpoint', + 'application/vnd.ms-excel', + 'application/vnd.oasis.opendocument.text', + 'application/vnd.oasis.opendocument.text-flat-xml', + 'application/vnd.oasis.opendocument.spreadsheet', + 'application/vnd.oasis.opendocument.spreadsheet-flat-xml', + 'application/vnd.oasis.opendocument.presentation', + 'application/vnd.oasis.opendocument.presentation-flat-xml', + 'application/vnd.oasis.opendocument.graphics', + 'application/vnd.oasis.opendocument.graphics-flat-xml', + 'application/vnd.oasis.opendocument.chart', + 'application/msword', + 'application/vnd.ms-excel', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-word.document.macroEnabled.12', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'application/x-dif-document', + 'text/spreadsheet', + 'text/csv', + 'application/x-dbase', + 'text/rtf', + 'text/plain', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', +]); + + + +const MIMES_VIEW = new Set([ + ...MIMES_EDIT, + [ + 'image/svg+xml', + 'application/vnd.sun.xml.writer', + 'application/vnd.sun.xml.calc', + 'application/vnd.sun.xml.impress', + 'application/vnd.sun.xml.draw', + 'application/vnd.sun.xml.writer.global', + 'application/vnd.sun.xml.writer.template', + 'application/vnd.sun.xml.calc.template', + 'application/vnd.sun.xml.impress.template', + 'application/vnd.sun.xml.draw.template', + 'application/vnd.oasis.opendocument.text-master', + 'application/vnd.oasis.opendocument.text-template', + 'application/vnd.oasis.opendocument.text-master-template', + 'application/vnd.oasis.opendocument.spreadsheet-template', + 'application/vnd.oasis.opendocument.presentation-template', + 'application/vnd.oasis.opendocument.graphics-template', + 'application/vnd.ms-word.template.macroEnabled.12', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'application/vnd.ms-excel.template.macroEnabled.12', + 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'application/vnd.ms-powerpoint.template.macroEnabled.12', + 'application/vnd.wordperfect', + 'application/x-aportisdoc', + 'application/x-hwp', + 'application/vnd.ms-works', + 'application/x-mswrite', + 'application/vnd.lotus-1-2-3', + 'image/cgm', + 'image/vnd.dxf', + 'image/x-emf', + 'image/x-wmf', + 'application/coreldraw', + 'application/vnd.visio2013', + 'application/vnd.visio', + 'application/vnd.ms-visio.drawing', + 'application/x-mspublisher', + 'application/x-sony-bbeb', + 'application/x-gnumeric', + 'application/macwriteii', + 'application/x-iwork-numbers-sffnumbers', + 'application/vnd.oasis.opendocument.text-web', + 'application/x-pagemaker', + 'application/x-fictionbook+xml', + 'application/clarisworks', + 'image/x-wpg', + 'application/x-iwork-pages-sffpages', + 'application/x-iwork-keynote-sffkey', + 'application/x-abiword', + 'image/x-freehand', + 'application/vnd.sun.xml.chart', + 'application/x-t602', + 'image/bmp', + 'image/png', + 'image/gif', + 'image/tiff', + 'image/jpg', + 'image/jpeg', + 'application/pdf', + ] +]) + +function is_extension_editable(mimeType: string): boolean { + return MIMES_EDIT.has(mimeType); +} + +function is_extension_viewable(mimeType: string): boolean { + return MIMES_VIEW.has(mimeType); +} + +function build_convert_link(uuid: string) { + return `/chill/wopi/convert/${uuid}`; +} + +function build_download_info_link(object_name: string) { + return `/asyncupload/temp_url/generate/GET?object_name=${object_name}`; +} + +function build_wopi_editor_link(uuid: string, returnPath?: string) { + if (returnPath === undefined) { + returnPath = window.location.pathname + window.location.search + window.location.hash; + } + + return `/chill/wopi/edit/${uuid}?returnPath=` + encodeURIComponent(returnPath); +} + +function download_doc(url: string): Promise { + return window.fetch(url).then(r => { + if (r.ok) { + return r.blob() + } + + throw new Error('Could not download document'); + }); +} + +async function download_and_decrypt_doc(urlGenerator: string, keyData: JsonWebKey, iv: Uint8Array): Promise +{ + const algo = 'AES-CBC'; + // get an url to download the object + const downloadInfoResponse = await window.fetch(urlGenerator); + + if (!downloadInfoResponse.ok) { + throw new Error("error while downloading url " + downloadInfoResponse.status + " " + downloadInfoResponse.statusText); + } + + const downloadInfo = await downloadInfoResponse.json() as {url: string}; + const rawResponse = await window.fetch(downloadInfo.url); + + if (!rawResponse.ok) { + throw new Error("error while downloading raw file " + rawResponse.status + " " + rawResponse.statusText); + } + + if (iv.length === 0) { + return rawResponse.blob(); + } + + const rawBuffer = await rawResponse.arrayBuffer(); + + try { + const key = await window.crypto.subtle + .importKey('jwk', keyData, { name: algo }, false, ['decrypt']); + const decrypted = await window.crypto.subtle + .decrypt({ name: algo, iv: iv }, key, rawBuffer); + + return Promise.resolve(new Blob([decrypted])); + } catch (e) { + console.error('get error while keys and decrypt operations'); + console.error(e); + + throw e; + } +} + +async function is_object_ready(storedObject: StoredObject): Promise +{ + const new_status_response = await window + .fetch( `/api/1.0/doc-store/stored-object/${storedObject.uuid}/is-ready`); + + if (!new_status_response.ok) { + throw new Error("could not fetch the new status"); + } + + return await new_status_response.json(); +} + +export { + build_convert_link, + build_download_info_link, + build_wopi_editor_link, + download_and_decrypt_doc, + download_doc, + is_extension_editable, + is_extension_viewable, + is_object_ready, +}; diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/_workflow.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/_workflow.html.twig index e9147ed4a..58d4903b4 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/_workflow.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/_workflow.html.twig @@ -1,64 +1,58 @@ {% import "@ChillDocStore/Macro/macro.html.twig" as m %} {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %} -
      -
      -
      -
      - -
      -
      -

      {{ document.title }}

      +{% if document is null %} +
      + {{ 'workflow.Document deleted'|trans }} +
      +{% else %} +
      +
      +
      +
      + +
      +
      +

      {{ document.title }}

      - {{ mm.mimeIcon(document.object.type) }} - - {% if document.description is not empty %} -
      - {{ document.description }} -
      - {% endif %} + {{ mm.mimeIcon(document.object.type) }} + {% if document.description is not empty %} +
      + {{ document.description }} +
      + {% endif %} +
      -
      -{% set freezed = false %} -{% for step in entity_workflow.stepsChained %} - {% if loop.last %} - {% if step.previous is not null and step.previous.freezeAfter == true %} - {% set freezed = true %} - {% endif %} - {% endif %} -{% endfor %} - -{% if display_action is defined and display_action == true %} -
        - {% if document.course != null and is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', document.course) %} -
      • - - {{ 'Course number'|trans }} {{ document.course.id }} - -
      • - {% endif %} -
      • - {{ m.download_button(document.object, document.title) }} -
      • -
      • - {% if chill_document_is_editable(document.object) %} - {% if not freezed %} - {{ document.object|chill_document_edit_button({'title': document.title|e('html') }) }} - {% else %} - - {{ 'Update document'|trans }} - + {% set freezed = false %} + {% for step in entity_workflow.stepsChained %} + {% if loop.last %} + {% if step.previous is not null and step.previous.freezeAfter == true %} + {% set freezed = true %} {% endif %} {% endif %} - {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE', document) and document.course != null %} + {% endfor %} + + {% if display_action is defined and display_action == true %} + + {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE', document) and document.course != null %} +
      • + +
      • + {% endif %} +
      + {% endif %} {% endif %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/delete.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/delete.html.twig index a6679829b..c9bb608cf 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/delete.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/delete.html.twig @@ -9,11 +9,6 @@
      {{ 'Title'|trans }}
      {{ document.title }}
      - {% if document.scope is not null %} -
      {{ 'Scope' | trans }}
      -
      {{ document.scope.name | localize_translatable_string }}
      - {% endif %} -
      {{ 'Category'|trans }}
      {{ document.category.name|localize_translatable_string }}
      diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/index.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/index.html.twig index df18efa71..7a013260c 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/index.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/index.html.twig @@ -8,16 +8,16 @@ {% block js %} {{ parent() }} - {{ encore_entry_script_tags('mod_async_upload') }} {{ encore_entry_script_tags('mod_docgen_picktemplate') }} {{ encore_entry_script_tags('mod_entity_workflow_pick') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} - {{ encore_entry_link_tags('mod_async_upload') }} {{ encore_entry_link_tags('mod_docgen_picktemplate') }} {{ encore_entry_link_tags('mod_entity_workflow_pick') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/show.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/show.html.twig index 45ed3988b..3c62451a9 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/show.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/show.html.twig @@ -14,6 +14,7 @@ {{ parent() }} {{ encore_entry_link_tags('mod_async_upload') }} {{ encore_entry_link_tags('mod_entity_workflow_pick') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} @@ -61,13 +62,8 @@ {% endif %}
    • - {{ m.download_button(document.object, document.title) }} + {{ document.object|chill_document_button_group(document.title) }}
    • - {% if chill_document_is_editable(document.object) %} -
    • - {{ document.object|chill_document_edit_button }} -
    • - {% endif %} {% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %} {% if workflows_frame is not empty %}
    • @@ -86,4 +82,5 @@ {{ parent() }} {{ encore_entry_script_tags('mod_async_upload') }} {{ encore_entry_script_tags('mod_entity_workflow_pick') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig new file mode 100644 index 000000000..f83cafd51 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/Button/button_group.html.twig @@ -0,0 +1,7 @@ +{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%} +
      diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/DocumentCategory/index.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/DocumentCategory/index.html.twig index 5731f57f5..ff20257a5 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/DocumentCategory/index.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/DocumentCategory/index.html.twig @@ -5,14 +5,14 @@ {% block admin_content %}

      {{ 'Document category list' | trans }}

      -
    •     {{ 'Budget calculator result'|trans }}
      {{ 'The balance'|trans }}  {{ result|format_currency('EUR') }}
      +
      - + @@ -23,7 +23,7 @@ - {% endfor %} @@ -108,31 +108,17 @@ {{ chill_pagination(paginator) }} {% endif %} -
      +
      {{ form_start(form_add_event_participation_by_person) }} - {# - - #} - {{ form_widget(form_add_event_participation_by_person.event_id, { 'attr' : { 'class' : 'form-control' } } ) }} -
      - {# - - #} - {{ form_widget(form_add_event_participation_by_person.submit, { 'attr' : { 'class' : 'btn btn-success' } } ) }} + {{ form_widget(form_add_event_participation_by_person.event_id, { 'attr' : { + 'class' : 'custom-select', + 'style': 'min-width: 15em; max-width: 18em; display: inline-block;' + }}) }} +
      + {{ form_widget(form_add_event_participation_by_person.submit, { 'attr' : { 'class' : 'btn btn-sm btn-save' } } ) }}
      {{ form_rest(form_add_event_participation_by_person) }} {{ form_end(form_add_event_participation_by_person) }}
      -{# -{{ form(form_add_event_participation_by_person) }} -#} - -
      - -
      - -
      -
      - {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/new.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/new.html.twig index 44d24040b..f0d1b0ea2 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/new.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/new.html.twig @@ -3,6 +3,7 @@ {% block title 'Event creation'|trans %} {% block event_content -%} +

      {{ 'Event creation'|trans }}

      {{ form_start(form) }} @@ -26,4 +27,5 @@ {{ form_end(form) }} +
      {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig index c4fb4aacd..a10d754e6 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/newPickCenter.html.twig @@ -3,6 +3,7 @@ {% block title 'Event creation'|trans %} {% block event_content -%} +

      {{ 'Event creation'|trans }}

      {{ form_start(form) }} @@ -22,5 +23,5 @@ {{ form_end(form) }} - +
      {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig index 6af5dd80a..4ce92a200 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/show.html.twig @@ -5,9 +5,10 @@ {% import 'ChillPersonBundle:Person:macro.html.twig' as person_macro %} {% block event_content -%} +

      {{ 'Details of an event'|trans }}

      -
      {{ 'Creator bundle id' | trans }} {{ 'Internal id inside creator bundle' | trans }} {{ 'Document class' | trans }} {{ 'Name' | trans }}{{ 'Actions' | trans }}{{ 'Actions' | trans }}
      {{ document_category.documentClass }} {{ document_category.name | localize_translatable_string}} +
      + {% if document.object.isPending %} +
      {{ 'docgen.Doc generation is pending'|trans }}
      + {% elseif document.object.isFailure %} +
      {{ 'docgen.Doc generation failed'|trans }}
      + {% endif %}
      {{ document.title }}
      -
      - {{ mm.mimeIcon(document.object.type) }} -
      + {% if document.object.type is not empty %} +
      + {{ mm.mimeIcon(document.object.type) }} +
      + {% endif %}

      {{ document.category.name|localize_translatable_string }}

      - {% if document.template is not null %} + {% if document.object.hasTemplate %}
      -

      {{ document.template.name.fr }}

      +

      {{ document.object.template.name|localize_translatable_string }}

      {% endif %}
      @@ -44,54 +51,44 @@
        {% if document.course is defined %} - {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %} -
      • - +
      • + {{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }} +
      • + {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %} +
      • + {{ document.object|chill_document_button_group(document.title, is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document)) }} +
      • +
      • +
      • {% endif %} {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
      • - {% if chill_document_is_editable(document.object) %} -
      • - {{ document.object|chill_document_edit_button }} -
      • - {% endif %} {% endif %} - {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %} -
      • - {{ m.download_button(document.object, document.title) }} -
      • -
      • - -
      • - {% endif %} -
      • - {{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }} -
      • - {% else %} - {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %} + {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
      • - + +
      • + {% endif %} + {% else %} + {% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %} +
      • + {{ document.object|chill_document_button_group(document.title, is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document)) }} +
      • +
      • +
      • {% endif %} {% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
      • - {% if chill_document_is_editable(document.object) %} -
      • - {{ document.object|chill_document_edit_button }} -
      • - {% endif %} {% endif %} - {% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %} -
      • - {{ m.download_button(document.object, document.title) }} -
      • -
      • - + {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %} +
      • +
      • {% endif %} {% endif %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro.html.twig index 886544b1e..199a86c15 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro.html.twig @@ -2,14 +2,47 @@ {% if storedObject is null %} {% else %} - {{ 'Download'|trans }} {% endif %} {% endmacro %} + +{% macro download_button_small(storedObject, filename = null) %} + {% if storedObject is null %} + + {% else %} + + {{ 'Download'|trans }} + {% endif %} +{% endmacro %} + +{% macro download_button_group(storedObject, canEdit = true, filename = null, options = {}) %} + {% if storedObject is null %} + + {% else %} +
        + {% endif %} +{% endmacro %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro_mimeicon.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro_mimeicon.html.twig index a9bc07e2f..7079a0d94 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro_mimeicon.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/Macro/macro_mimeicon.html.twig @@ -48,8 +48,8 @@ {% endif %} {% endfor %} - + {% endmacro %} \ No newline at end of file diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig index 5dc359fa8..8d201605e 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/index.html.twig @@ -27,16 +27,16 @@ {% block js %} {{ parent() }} - {{ encore_entry_script_tags('mod_async_upload') }} {{ encore_entry_script_tags('mod_docgen_picktemplate') }} {{ encore_entry_script_tags('mod_entity_workflow_pick') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} {% endblock %} {% block css %} {{ parent() }} - {{ encore_entry_link_tags('mod_async_upload') }} {{ encore_entry_link_tags('mod_docgen_picktemplate') }} {{ encore_entry_link_tags('mod_entity_workflow_pick') }} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig index b26aa4b8b..c276e067e 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/PersonDocument/show.html.twig @@ -24,7 +24,11 @@ {% block title %}{{ 'Detail of document of %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}{% endblock %} {% block js %} - {{ encore_entry_script_tags('mod_async_upload') }} + {{ encore_entry_script_tags('mod_document_action_buttons_group') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} {% block content %} @@ -70,6 +74,10 @@ {% endif %} +
      • + {{ document.object|chill_document_button_group(document.title, is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document)) }} +
      • + {% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
      • @@ -77,16 +85,4 @@
      • {% endif %} - -
      • - {{ m.download_button(document.object, document.title) }} -
      • - - {% if chill_document_is_editable(document.object) %} -
      • - {{ document.object|chill_document_edit_button }} -
      • - {% endif %} - - {# {{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }} #} {% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php index 02dfb5b64..0ef1d4d49 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php @@ -78,12 +78,12 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov return []; } - protected function supports($attribute, $subject) + protected function supports($attribute, $subject): bool { return $this->voterHelper->supports($attribute, $subject); } - protected function voteOnAttribute($attribute, $subject, TokenInterface $token) + protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { if (!$token->getUser() instanceof User) { return false; diff --git a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php index daed12b84..a1ef42ff1 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php +++ b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php @@ -60,7 +60,7 @@ final class StoredObjectManager implements StoredObjectManagerInterface $this ->tempUrlGenerator ->generate( - Request::METHOD_PUT, + Request::METHOD_HEAD, $document->getFilename() ) ->url diff --git a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtension.php b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtension.php index 43dc28f15..754c3fb3c 100644 --- a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtension.php +++ b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtension.php @@ -24,6 +24,10 @@ class WopiEditTwigExtension extends AbstractExtension 'needs_environment' => true, 'is_safe' => ['html'], ]), + new TwigFilter('chill_document_button_group', [WopiEditTwigExtensionRuntime::class, 'renderButtonGroup'], [ + 'needs_environment' => true, + 'is_safe' => ['html'], + ]), ]; } diff --git a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php index f53d6336b..ec1df1465 100644 --- a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php +++ b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php @@ -13,6 +13,8 @@ namespace Chill\DocStoreBundle\Templating; use ChampsLibres\WopiLib\Contract\Service\Discovery\DiscoveryInterface; use Chill\DocStoreBundle\Entity\StoredObject; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Twig\Environment; use Twig\Extension\RuntimeExtensionInterface; @@ -112,20 +114,53 @@ final class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface 'application/pdf', ]; + private const DEFAULT_OPTIONS_TEMPLATE_BUTTON_GROUP = [ + 'small' => false, + ]; + private const TEMPLATE = '@ChillDocStore/Button/wopi_edit_document.html.twig'; + private const TEMPLATE_BUTTON_GROUP = '@ChillDocStore/Button/button_group.html.twig'; + private DiscoveryInterface $discovery; - public function __construct(DiscoveryInterface $discovery) + private NormalizerInterface $normalizer; + + public function __construct(DiscoveryInterface $discovery, NormalizerInterface $normalizer) { $this->discovery = $discovery; + $this->normalizer = $normalizer; } + /** + * return true if the document is editable. + * + * **NOTE**: as the Vue button does have similar test, this is not required if in use with + * the dedicated Vue component (GroupDownloadButton.vue, WopiEditButton.vue) + */ public function isEditable(StoredObject $document): bool { return in_array($document->getType(), self::SUPPORTED_MIMES, true); } + /** + * @param array{small: boolean} $options + * + * @throws \Twig\Error\LoaderError + * @throws \Twig\Error\RuntimeError + * @throws \Twig\Error\SyntaxError + */ + public function renderButtonGroup(Environment $environment, StoredObject $document, ?string $title = null, bool $canEdit = true, array $options = []): string + { + return $environment->render(self::TEMPLATE_BUTTON_GROUP, [ + 'document' => $document, + 'document_json' => $this->normalizer->normalize($document, 'json', [AbstractNormalizer::GROUPS => ['read']]), + 'title' => $title, + 'can_edit' => $canEdit, + 'options' => array_merge(self::DEFAULT_OPTIONS_TEMPLATE_BUTTON_GROUP, $options), + ]); + } + public function renderEditButton(Environment $environment, StoredObject $document, ?array $options = null): string { return $environment->render(self::TEMPLATE, [ diff --git a/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php b/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php index 8e94dbd83..c3285507e 100644 --- a/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php +++ b/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php @@ -51,9 +51,7 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler $persons = []; if (null !== $course) { - $persons = $course->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $participation) { - return $participation->getPerson(); - })->toArray(); + $persons = $course->getCurrentParticipations()->map(static fn (AccompanyingPeriodParticipation $participation) => $participation->getPerson())->toArray(); } return [ @@ -65,6 +63,10 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler { $doc = $this->getRelatedEntity($entityWorkflow); + if (null === $doc) { + return $this->translator->trans('workflow.Document deleted'); + } + return $this->translator->trans('workflow.Document (n°%doc%)', ['%doc%' => $entityWorkflow->getRelatedEntityId()]) . ' - ' . $doc->getTitle(); } @@ -91,6 +93,16 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler return null; } + public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array + { + $suggestedUsers = $entityWorkflow->getUsersInvolved(); + + $referrer = $this->getRelatedEntity($entityWorkflow)->getCourse()->getUser(); + $suggestedUsers[spl_object_hash($referrer)] = $referrer; + + return $suggestedUsers; + } + public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string { return '@ChillDocStore/AccompanyingCourseDocument/_workflow.html.twig'; diff --git a/src/Bundle/ChillDocStoreBundle/chill.webpack.config.js b/src/Bundle/ChillDocStoreBundle/chill.webpack.config.js index c9b2b8877..3499fcf55 100644 --- a/src/Bundle/ChillDocStoreBundle/chill.webpack.config.js +++ b/src/Bundle/ChillDocStoreBundle/chill.webpack.config.js @@ -4,4 +4,5 @@ module.exports = function(encore) ChillDocStoreAssets: __dirname + '/Resources/public' }); encore.addEntry('mod_async_upload', __dirname + '/Resources/public/module/async_upload/index.js'); + encore.addEntry('mod_document_action_buttons_group', __dirname + '/Resources/public/module/document_action_buttons_group/index'); }; diff --git a/src/Bundle/ChillDocStoreBundle/migrations/Version20230227161327.php b/src/Bundle/ChillDocStoreBundle/migrations/Version20230227161327.php new file mode 100644 index 000000000..a9453fa07 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/migrations/Version20230227161327.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE chill_doc.stored_object ADD generationTrialsCounter INT DEFAULT 0 NOT NULL;'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_doc.stored_object DROP generationTrialsCounter'); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml index 17326b299..1d06c58e4 100644 --- a/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillDocStoreBundle/translations/messages.fr.yml @@ -14,11 +14,14 @@ Edit attributes: Modifier les propriétés du document Existing document: Document existant No document to download: Aucun document à télécharger 'Choose a document category': Choisissez une catégorie de document -Any document found: Aucun document trouvé +No document found: Aucun document trouvé The document is successfully registered: Le document est enregistré The document is successfully updated: Le document est mis à jour Any description: Aucune description +document: + Any title: Aucun titre + # delete Delete document ?: Supprimer le document ? Are you sure you want to remove this document ?: Êtes-vous sûr·e de vouloir supprimer ce document ? @@ -63,3 +66,14 @@ Create new DocumentCategory: Créer une nouvelle catégorie de document # WOPI EDIT online_edit_document: Éditer en ligne + +workflow: + Document deleted: Document supprimé + +# ROLES +accompanyingCourseDocument: Documents dans les parcours d'accompagnement +CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE: Créer un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE: Supprimer un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE: Voir les documents +CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS: Voir les détails d'un document +CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document diff --git a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php index dafbc8b8a..1929beac1 100644 --- a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php +++ b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php @@ -113,9 +113,7 @@ class ParticipationController extends AbstractController [ 'event_id' => current($participations)->getEvent()->getId(), 'persons_ids' => implode(',', array_map( - static function (Participation $p) { - return $p->getPerson()->getId(); - }, + static fn (Participation $p) => $p->getPerson()->getId(), $participations )), ] @@ -649,19 +647,14 @@ class ParticipationController extends AbstractController // create a collection of person's id participating to the event /** @var \Doctrine\Common\Collections\ArrayCollection $peopleParticipating */ - $peopleParticipating = $peopleParticipating ?? - $participation->getEvent()->getParticipations()->map( - static function (Participation $p) { - return $p->getPerson()->getId(); - } - ); + $peopleParticipating ??= $participation->getEvent()->getParticipations()->map( + static fn (Participation $p) => $p->getPerson()->getId() + ); // check that the user is not already in the event if ($peopleParticipating->contains($participation->getPerson()->getId())) { $ignoredParticipations[] = $participation ->getEvent()->getParticipations()->filter( - static function (Participation $p) use ($participation) { - return $p->getPerson()->getId() === $participation->getPerson()->getId(); - } + static fn (Participation $p) => $p->getPerson()->getId() === $participation->getPerson()->getId() )->first(); } else { $newParticipations[] = $participation; diff --git a/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadParticipation.php b/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadParticipation.php index ed38faf01..71b07a123 100644 --- a/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadParticipation.php +++ b/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadParticipation.php @@ -43,7 +43,7 @@ class LoadParticipation extends AbstractFixture implements OrderedFixtureInterfa for ($i = 0; $i < $expectedNumber; ++$i) { $event = (new Event()) ->setDate($this->faker->dateTimeBetween('-2 years', '+6 months')) - ->setName($this->faker->words(mt_rand(2, 4), true)) + ->setName($this->faker->words(random_int(2, 4), true)) ->setType($this->getReference(LoadEventTypes::$refs[array_rand(LoadEventTypes::$refs)])) ->setCenter($center) ->setCircle( @@ -75,7 +75,7 @@ class LoadParticipation extends AbstractFixture implements OrderedFixtureInterfa /** @var \Chill\PersonBundle\Entity\Person $person */ foreach ($people as $person) { - $nb = mt_rand(0, 3); + $nb = random_int(0, 3); for ($i = 0; $i < $nb; ++$i) { $event = $events[array_rand($events)]; diff --git a/src/Bundle/ChillEventBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillEventBundle/DependencyInjection/Configuration.php index b36f7b6a9..fe42ad99a 100644 --- a/src/Bundle/ChillEventBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillEventBundle/DependencyInjection/Configuration.php @@ -24,7 +24,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_event'); - $rootNode = $treeBuilder->getRootNode('chill_event'); + $rootNode = $treeBuilder->getRootNode(); // Here you should define the parameters that are allowed to // configure your bundle. See the documentation linked above for diff --git a/src/Bundle/ChillEventBundle/Entity/Event.php b/src/Bundle/ChillEventBundle/Entity/Event.php index 6ac9c1508..d55a7b8a8 100644 --- a/src/Bundle/ChillEventBundle/Entity/Event.php +++ b/src/Bundle/ChillEventBundle/Entity/Event.php @@ -176,9 +176,7 @@ class Event implements HasCenterInterface, HasScopeInterface { $iterator = $this->participations->getIterator(); - $iterator->uasort(static function ($first, $second) { - return strnatcasecmp($first->getPerson()->getFirstName(), $second->getPerson()->getFirstName()); - }); + $iterator->uasort(static fn ($first, $second) => strnatcasecmp($first->getPerson()->getFirstName(), $second->getPerson()->getFirstName())); return $iterator; } diff --git a/src/Bundle/ChillEventBundle/Entity/Participation.php b/src/Bundle/ChillEventBundle/Entity/Participation.php index fd89f73d3..38c849535 100644 --- a/src/Bundle/ChillEventBundle/Entity/Participation.php +++ b/src/Bundle/ChillEventBundle/Entity/Participation.php @@ -197,7 +197,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac * * @return bool */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return in_array($offset, [ 'person', 'role', 'status', 'event', @@ -207,30 +207,21 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * @param mixed $offset * - * @return Event|mixed|Person|Role|Status + * @return Event|Person|Role|Status */ - public function offsetGet($offset) + public function offsetGet($offset): mixed { switch ($offset) { case 'person': return $this->getPerson(); - - break; - case 'role': return $this->getRole(); - - break; - case 'status': return $this->getStatus(); - - break; - case 'event': return $this->getEvent(); - - break; + default: + throw new \LogicException("this offset does not exists : " . $offset); } } @@ -238,28 +229,28 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac * @param mixed $offset * @param mixed $value * - * @return Participation|void + * @return void */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { switch ($offset) { case 'person': - return $this->setPerson($value); + $this->setPerson($value); break; case 'role': - return $this->setRole($value); + $this->setRole($value); break; case 'status': - return $this->setStatus($value); + $this->setStatus($value); break; case 'event': - return $this->setEvent($value); + $this->setEvent($value); break; } @@ -268,7 +259,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * @param mixed $offset */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->offsetSet($offset, null); } diff --git a/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php b/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php index 30a00ebb9..962799dbc 100644 --- a/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php +++ b/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php @@ -62,9 +62,7 @@ class EventChoiceLoader implements ChoiceLoaderInterface { return new \Symfony\Component\Form\ChoiceList\ArrayChoiceList( $this->lazyLoadedEvents, - static function (Event $p) use ($value) { - return call_user_func($value, $p); - } + static fn (Event $p) => call_user_func($value, $p) ); } diff --git a/src/Bundle/ChillEventBundle/Form/EventType.php b/src/Bundle/ChillEventBundle/Form/EventType.php index fec26c373..a72b90494 100644 --- a/src/Bundle/ChillEventBundle/Form/EventType.php +++ b/src/Bundle/ChillEventBundle/Form/EventType.php @@ -54,7 +54,7 @@ class EventType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\EventBundle\Entity\Event', + 'data_class' => \Chill\EventBundle\Entity\Event::class, ]); $resolver ->setRequired(['center', 'role']) diff --git a/src/Bundle/ChillEventBundle/Form/EventTypeType.php b/src/Bundle/ChillEventBundle/Form/EventTypeType.php index 9f971f55d..bab13c374 100644 --- a/src/Bundle/ChillEventBundle/Form/EventTypeType.php +++ b/src/Bundle/ChillEventBundle/Form/EventTypeType.php @@ -36,7 +36,7 @@ class EventTypeType extends AbstractType public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\EventBundle\Entity\EventType', + 'data_class' => \Chill\EventBundle\Entity\EventType::class, ]); } } diff --git a/src/Bundle/ChillEventBundle/Form/RoleType.php b/src/Bundle/ChillEventBundle/Form/RoleType.php index e4e55faca..519e814cf 100644 --- a/src/Bundle/ChillEventBundle/Form/RoleType.php +++ b/src/Bundle/ChillEventBundle/Form/RoleType.php @@ -38,9 +38,7 @@ class RoleType extends AbstractType ->add('active') ->add('type', EntityType::class, [ 'class' => EventType::class, - 'choice_label' => function (EventType $e) { - return $this->translatableStringHelper->localize($e->getName()); - }, + 'choice_label' => fn (EventType $e) => $this->translatableStringHelper->localize($e->getName()), ]); } @@ -55,7 +53,7 @@ class RoleType extends AbstractType public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\EventBundle\Entity\Role', + 'data_class' => \Chill\EventBundle\Entity\Role::class, ]); } } diff --git a/src/Bundle/ChillEventBundle/Form/StatusType.php b/src/Bundle/ChillEventBundle/Form/StatusType.php index e70011d22..5801f3264 100644 --- a/src/Bundle/ChillEventBundle/Form/StatusType.php +++ b/src/Bundle/ChillEventBundle/Form/StatusType.php @@ -38,7 +38,7 @@ class StatusType extends AbstractType public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\EventBundle\Entity\Status', + 'data_class' => \Chill\EventBundle\Entity\Status::class, ]); } } diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php b/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php index 782bd7628..05436b3e8 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php @@ -109,16 +109,12 @@ class PickEventType extends AbstractType // add the default options $resolver->setDefaults([ 'class' => Event::class, - 'choice_label' => static function (Event $e) { - return $e->getDate()->format('d/m/Y, H:i') . ' → ' . - // $e->getType()->getName()['fr'] . ': ' . // display the type of event - $e->getName(); - }, + 'choice_label' => static fn (Event $e) => $e->getDate()->format('d/m/Y, H:i') . ' → ' . + // $e->getType()->getName()['fr'] . ': ' . // display the type of event + $e->getName(), 'placeholder' => 'Pick an event', 'attr' => ['class' => 'select2 '], - 'choice_attr' => static function (Event $e) { - return ['data-center' => $e->getCenter()->getId()]; - }, + 'choice_attr' => static fn (Event $e) => ['data-center' => $e->getCenter()->getId()], 'choiceloader' => function (Options $options) { $centers = $this->filterCenters($options); @@ -143,15 +139,13 @@ class PickEventType extends AbstractType // option role if (null === $options['role']) { $centers = array_map( - static function (GroupCenter $g) { - return $g->getCenter(); - }, + static fn (GroupCenter $g) => $g->getCenter(), $this->user->getGroupCenters()->toArray() ); } else { $centers = $this->authorizationHelper->getReachableCenters( $this->user, - (string) $options['role'] + (string) $options['role']->getRole() ); } @@ -173,9 +167,7 @@ class PickEventType extends AbstractType if ( !in_array($c->getId(), array_map( - static function (Center $c) { - return $c->getId(); - }, + static fn (Center $c) => $c->getId(), $centers ), true) ) { diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickEventTypeType.php b/src/Bundle/ChillEventBundle/Form/Type/PickEventTypeType.php index eacdc78f1..d027c05cf 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickEventTypeType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickEventTypeType.php @@ -39,16 +39,10 @@ class PickEventTypeType extends AbstractType $resolver->setDefaults( [ 'class' => EventType::class, - 'query_builder' => static function (EntityRepository $er) { - return $er->createQueryBuilder('et') - ->where('et.active = true'); - }, - 'choice_label' => static function (EventType $t) use ($helper) { - return $helper->localize($t->getName()); - }, - 'choice_attrs' => static function (EventType $t) { - return ['data-link-category' => $t->getId()]; - }, + 'query_builder' => static fn (EntityRepository $er) => $er->createQueryBuilder('et') + ->where('et.active = true'), + 'choice_label' => static fn (EventType $t) => $helper->localize($t->getName()), + 'choice_attrs' => static fn (EventType $t) => ['data-link-category' => $t->getId()], ] ); } diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php b/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php index 95864056a..8fd8ff7d7 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php @@ -80,9 +80,7 @@ class PickRoleType extends AbstractType $options = $config->getOptions(); $form->getParent()->add($name, $type, array_replace($options, [ - 'group_by' => function (Role $r) { - return $this->translatableStringHelper->localize($r->getType()->getName()); - }, + 'group_by' => fn (Role $r) => $this->translatableStringHelper->localize($r->getType()->getName()), ])); } } @@ -111,17 +109,13 @@ class PickRoleType extends AbstractType 'class' => Role::class, 'query_builder' => $qb, 'group_by' => null, - 'choice_attr' => static function (Role $r) { - return [ - 'data-event-type' => $r->getType()->getId(), - 'data-link-category' => $r->getType()->getId(), - ]; - }, - 'choice_label' => static function (Role $r) use ($translatableStringHelper, $translator) { - return $translatableStringHelper->localize($r->getName()) . - ($r->getActive() === true ? '' : - ' (' . $translator->trans('unactive') . ')'); - }, + 'choice_attr' => static fn (Role $r) => [ + 'data-event-type' => $r->getType()->getId(), + 'data-link-category' => $r->getType()->getId(), + ], + 'choice_label' => static fn (Role $r) => $translatableStringHelper->localize($r->getName()) . + ($r->getActive() === true ? '' : + ' (' . $translator->trans('unactive') . ')'), ]); } diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php b/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php index 4d96ed95d..dcc3ba205 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php @@ -82,9 +82,7 @@ class PickStatusType extends AbstractType $type = $config->getType()->getName(); $options = $config->getOptions(); $form->getParent()->add($name, $type, array_replace($options, [ - 'group_by' => function (Status $s) { - return $this->translatableStringHelper->localize($s->getType()->getName()); - }, + 'group_by' => fn (Status $s) => $this->translatableStringHelper->localize($s->getType()->getName()), ])); } ); @@ -112,17 +110,13 @@ class PickStatusType extends AbstractType 'class' => Status::class, 'query_builder' => $qb, 'group_by' => null, - 'choice_attr' => static function (Status $s) { - return [ - 'data-event-type' => $s->getType()->getId(), - 'data-link-category' => $s->getType()->getId(), - ]; - }, - 'choice_label' => static function (Status $s) use ($translatableStringHelper, $translator) { - return $translatableStringHelper->localize($s->getName()) . - ($s->getActive() === true ? '' : - ' (' . $translator->trans('unactive') . ')'); - }, + 'choice_attr' => static fn (Status $s) => [ + 'data-event-type' => $s->getType()->getId(), + 'data-link-category' => $s->getType()->getId(), + ], + 'choice_label' => static fn (Status $s) => $translatableStringHelper->localize($s->getName()) . + ($s->getActive() === true ? '' : + ' (' . $translator->trans('unactive') . ')'), ]); } diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/confirm_delete.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/confirm_delete.html.twig index 86b7c6fd2..c3a13b55a 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/confirm_delete.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/confirm_delete.html.twig @@ -5,6 +5,7 @@ {% block title 'Delete event'|trans %} {% block event_content %} +
        {{ include('@ChillMain/Util/confirmation_template.html.twig', { @@ -15,6 +16,6 @@ 'form' : delete_form } ) }} - +
        {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig index 288c81edd..a528f1f5c 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig @@ -3,6 +3,7 @@ {% block title 'Event edit'|trans %} {% block event_content -%} +

        {{ 'Event edit'|trans }}

        {{ form_start(edit_form) }} @@ -28,6 +29,8 @@ {{ form_widget(edit_form.submit, { 'attr' : { 'class' : 'btn btn-update' } }) }}
      - + {{ form_end(edit_form) }} + + {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig index 6e77b6df8..8d5f49da8 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/list.html.twig @@ -6,42 +6,42 @@

      {{ 'Results %start%-%end% of %total%'|trans({ '%start%' : start, '%end%': start + events|length, '%total%' : total } ) }}

      - +
      - - - - - - + + + + + + - {% for event in events %} - - - - - + + + + - - {% endfor %} + {% endif %} + + + + + {% endfor %}
      {{ 'Name'|trans }}{{ 'Date'|trans }}{{ 'Event type'|trans }} 
      {{ 'Name'|trans }}{{ 'Date'|trans }}{{ 'Event type'|trans }} 
      {{ event.name }}{{ event.date|format_date('long') }}{{ event.type.name|localize_translatable_string }} -
        -
      • - {# {% if is_granted('CHILL_EVENT_SEE_DETAILS', event) %} #} - - {{ 'See'|trans }} - - {# {% endif %} #} - {% if is_granted('CHILL_EVENT_UPDATE', event) %} + {% for event in events %} +
      {{ event.name }}{{ event.date|format_date('long') }}{{ event.type.name|localize_translatable_string }} + -
      - + {% endif %} {% if preview == false %} -{{ chill_pagination(paginator) }} + {{ chill_pagination(paginator) }} {% endif %} + diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig index 53e97c3c4..ef2dae85c 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/listByPerson.html.twig @@ -44,59 +44,59 @@
      {{ participation.role.name|localize_translatable_string }} {{ participation.status.name|localize_translatable_string }} -
        +
        {% set currentPath = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %} {% set returnLabel = 'Back to %person% events'|trans({ '%person%' : currentPerson } ) %} {% if is_granted('CHILL_EVENT_SEE_DETAILS', participation.event) %} -
      • -
      • + class="btn btn-primary btn-sm" title="{{ 'See details of the event'|trans }}"> + + {% endif %} {% if is_granted('CHILL_EVENT_UPDATE', participation.event) and is_granted('CHILL_EVENT_PARTICIPATION_UPDATE', participation) %} -
      • -
      • + +
      + {% else %} -
    • {% if is_granted('CHILL_EVENT_UPDATE', participation.event) %} - - {{ 'Edit the event'|trans }} - + + {{ 'Edit the event'|trans }} + {% endif %} {% if is_granted('CHILL_EVENT_PARTICIPATION_UPDATE', participation) %} - - {{ 'Edit the participation'|trans }} - + + {{ 'Edit the participation'|trans }} + {% endif %} -
    • {% endif %} - +
      +
      @@ -69,7 +70,7 @@

      {% transchoice count %}%count% participations to this event{% endtranschoice %}

      {% if count > 0 %} -
      {{ 'Name'|trans }}
      +
      @@ -117,7 +118,7 @@ {% endif %} -
      +
      {{ form_start(form_add_participation_by_person) }}
      @@ -150,5 +151,5 @@
      {{ chill_delegated_block('block_footer_show', { 'event': event }) }}
      - +
      {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/confirm_delete.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/confirm_delete.html.twig index 9b023a915..0d993b075 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Participation/confirm_delete.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/confirm_delete.html.twig @@ -5,7 +5,7 @@ {% block title 'Remove participation'|trans %} {% block event_content %} - +
      {{ include('@ChillMain/Util/confirmation_template.html.twig', { 'title' : 'Remove participation'|trans, @@ -15,6 +15,6 @@ 'form' : delete_form } ) }} - +
      {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/edit-multiple.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/edit-multiple.html.twig index a50615414..f0f522a3d 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Participation/edit-multiple.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/edit-multiple.html.twig @@ -3,9 +3,10 @@ {% import 'ChillPersonBundle:Person:macro.html.twig' as person_macro %} {% block event_content -%} +

      {{ 'Participation Edit'|trans }}

      -
      {{ 'Person'|trans }}
      +
      @@ -18,11 +19,11 @@
      {{ 'Associated event'|trans }}
      -

      {{ 'Participations'|trans }}

      +

      {{ 'Participations'|trans }}

      {{ form_start(form) }} - +
      @@ -59,4 +60,5 @@ {{ form_end(form) }} + {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/edit.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/edit.html.twig index 19592526e..db716b3dc 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Participation/edit.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/edit.html.twig @@ -3,6 +3,7 @@ {% import 'ChillPersonBundle:Person:macro.html.twig' as person_macro %} {% block event_content -%} +

      {{ 'Participation Edit'|trans }}

      {{ 'Person'|trans }}
      @@ -42,4 +43,5 @@ {{ form_end(form) }} + {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/new-multiple.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/new-multiple.html.twig index a0551ff1a..224b7265f 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Participation/new-multiple.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/new-multiple.html.twig @@ -18,7 +18,7 @@ {% block event_content -%}

      {{ 'Participation creation'|trans }}

      -
      +
      @@ -30,7 +30,7 @@ {% include 'ChillEventBundle:Participation:_ignored_participations.html.twig' with ignored_participations %} {{ form_start(form) }} -
      {{ 'Associated event'|trans }}
      +
      diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/new.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/new.html.twig index 33f7bc213..3fbea8b68 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Participation/new.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/new.html.twig @@ -5,6 +5,7 @@ {% block title 'Participation creation'|trans %} {% block event_content -%} +

      {{ 'Participation creation'|trans }}

      {{ 'Person'|trans }}
      @@ -43,5 +44,5 @@ {{ form_end(form) }} - + {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Resources/views/layout.html.twig b/src/Bundle/ChillEventBundle/Resources/views/layout.html.twig index 45eb6e481..e34a10e18 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/layout.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/layout.html.twig @@ -16,9 +16,9 @@ * along with this program. If not, see . #} -{% extends "@ChillMain/layoutWithVerticalMenu.html.twig" %} +{% extends "@ChillMain/layout.html.twig" %} -{% block layout_wvm_content %} +{% block content %} {% block event_content %}

      {{ 'Event' |trans }}

      {% endblock %} diff --git a/src/Bundle/ChillEventBundle/Search/EventSearch.php b/src/Bundle/ChillEventBundle/Search/EventSearch.php index 8f72cc4ed..a7ac22592 100644 --- a/src/Bundle/ChillEventBundle/Search/EventSearch.php +++ b/src/Bundle/ChillEventBundle/Search/EventSearch.php @@ -113,27 +113,23 @@ class EventSearch extends AbstractSearch ] ); } + // format is "json" + $results = []; + $search = $this->search($terms, $start, $limit, $options); - if ('json' === $format) { - $results = []; - $search = $this->search($terms, $start, $limit, $options); - - foreach ($search as $item) { - $results[] = [ - 'id' => $item->getId(), - 'text' => $item->getDate()->format('d/m/Y, H:i') . ' → ' . - // $item->getType()->getName()['fr'] . ': ' . // display the type of event - $item->getName(), - ]; - } - - return [ - 'results' => $results, - 'pagination' => [ - 'more' => $paginator->hasNextPage(), - ], + foreach ($search as $item) { + $results[] = [ + 'id' => $item->getId(), + 'text' => $item->getDate()->format('d/m/Y, H:i') . ' → ' . + // $item->getType()->getName()['fr'] . ': ' . // display the type of event + $item->getName(), ]; } + + return [ + 'results' => $results, + 'more' => $paginator->hasNextPage(), + ]; } public function supports($domain, $format) @@ -174,8 +170,8 @@ class EventSearch extends AbstractSearch } if ( - (isset($terms['name']) || isset($terms['_default'])) - && (!empty($terms['name']) || !empty($terms['_default'])) + (isset($terms['name']) || isset($terms['_default'])) + && (!empty($terms['name']) || !empty($terms['_default'])) ) { // the form with name:"xyz" has precedence $name = $terms['name'] ?? $terms['_default']; diff --git a/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php b/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php index fa1ecabbe..d61c1f385 100644 --- a/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php +++ b/src/Bundle/ChillEventBundle/Tests/Controller/ParticipationControllerTest.php @@ -239,9 +239,7 @@ final class ParticipationControllerTest extends WebTestCase $this->personsIdsCache = array_merge( $this->personsIdsCache, $event->getParticipations()->map( - static function ($p) { - return $p->getPerson()->getId(); - } + static fn ($p) => $p->getPerson()->getId() ) ->toArray() ); @@ -305,9 +303,7 @@ final class ParticipationControllerTest extends WebTestCase $event = $this->getRandomEventWithMultipleParticipations(); $persons_id = implode(',', $event->getParticipations()->map( - static function ($p) { - return $p->getPerson()->getId(); - } + static fn ($p) => $p->getPerson()->getId() )->toArray()); $crawler = $this->client->request( @@ -333,9 +329,7 @@ final class ParticipationControllerTest extends WebTestCase $nbParticipations = $event->getParticipations()->count(); // get the persons_id participating on this event $persons_id = $event->getParticipations()->map( - static function ($p) { - return $p->getPerson()->getId(); - } + static fn ($p) => $p->getPerson()->getId() )->toArray(); // exclude the existing persons_ids from the new person $this->personsIdsCache = array_merge($this->personsIdsCache, $persons_id); @@ -464,9 +458,7 @@ final class ParticipationControllerTest extends WebTestCase $circles = $this->em->getRepository(\Chill\MainBundle\Entity\Scope::class) ->findAll(); - array_filter($circles, static function ($circle) use ($circleName) { - return in_array($circleName, $circle->getName(), true); - }); + array_filter($circles, static fn ($circle) => in_array($circleName, $circle->getName(), true)); $circle = $circles[0]; $events = $this->em->getRepository(\Chill\EventBundle\Entity\Event::class) diff --git a/src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php b/src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php index c1ae84b95..9fac6c88e 100644 --- a/src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php +++ b/src/Bundle/ChillEventBundle/Timeline/TimelineEventProvider.php @@ -208,9 +208,7 @@ class TimelineEventProvider implements TimelineProviderInterface foreach ($reachableCenters as $center) { $reachableCircleId = array_map( - static function (Scope $scope) { - return $scope->getId(); - }, + static fn (Scope $scope) => $scope->getId(), $this->helper->getReachableCircles($this->user, $role, $person->getCenter()) ); $centerAndScopeLines[] = sprintf( diff --git a/src/Bundle/ChillEventBundle/translations/messages.fr.yml b/src/Bundle/ChillEventBundle/translations/messages.fr.yml index 3ca0da260..8810c040a 100644 --- a/src/Bundle/ChillEventBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillEventBundle/translations/messages.fr.yml @@ -34,7 +34,7 @@ Edit the participation: Modifier la participation Participation Edit: Modifier une participation Add a participation: Ajouter un participant Participation creation: Ajouter une participation -Associated person: Personne associée +Associated person: Usager associé Associated event: Événement associé Back to the event: Retour à l'événement The participation was created: La participation a été créée @@ -108,4 +108,4 @@ csv: csv Create a new role: Créer un nouveau rôle Create a new type: Créer un nouveau type -Create a new status: Créer un nouveau statut \ No newline at end of file +Create a new status: Créer un nouveau statut diff --git a/src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php index d2c09d7fa..98ea3125a 100644 --- a/src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillFamilyMembersBundle/DependencyInjection/Configuration.php @@ -24,7 +24,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_amli_family_members'); - $rootNode = $treeBuilder->getRootNode('chill_amli_family_members'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php index 2ef99ae03..4bc9b4d79 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/AbstractCRUDController.php @@ -34,6 +34,29 @@ abstract class AbstractCRUDController extends AbstractController */ protected array $crudConfig = []; + /** + * get the role given from the config. + * + * @param mixed $entity + * @param mixed $_format + */ + protected function getRoleFor(string $action, Request $request, $entity, $_format): string + { + $actionConfig = $this->getActionConfig($action); + + if (null !== $actionConfig['roles'][$request->getMethod()]) { + return $actionConfig['roles'][$request->getMethod()]; + } + + if ($this->crudConfig['base_role']) { + return $this->crudConfig['base_role']; + } + + throw new \RuntimeException(sprintf('the config does not have any role for the ' . + 'method %s nor a global role for the whole action. Add those to your ' . + 'configuration or override the required method', $request->getMethod())); + } + public static function getSubscribedServices(): array { return array_merge( diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php index be45be681..645f7525c 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/ApiController.php @@ -274,17 +274,19 @@ class ApiController extends AbstractCRUDController $postedData = $this->getSerializer()->deserialize($request->getContent(), $postedDataType, $_format, $postedDataContext); } catch (\Symfony\Component\Serializer\Exception\UnexpectedValueException $e) { throw new BadRequestHttpException(sprintf('Unable to deserialize posted ' . - 'data: %s', $e->getMessage()), 0, $e); + 'data: %s', $e->getMessage()), $e, 0); } switch ($request->getMethod()) { case Request::METHOD_DELETE: // oups... how to use property accessor to remove element ? + /* @phpstan-ignore-next-line as we do not find a simpler way to do this */ $entity->{'remove' . ucfirst($property)}($postedData); break; case Request::METHOD_POST: + /* @phpstan-ignore-next-line as we do not find a simpler way to do this */ $entity->{'add' . ucfirst($property)}($postedData); break; @@ -499,28 +501,6 @@ class ApiController extends AbstractCRUDController return ['groups' => ['read']]; } - /** - * get the role given from the config. - * - * @param mixed $entity - * @param mixed $_format - */ - protected function getRoleFor(string $action, Request $request, $entity, $_format): string - { - $actionConfig = $this->getActionConfig($action); - - if (null !== $actionConfig['roles'][$request->getMethod()]) { - return $actionConfig['roles'][$request->getMethod()]; - } - - if ($this->crudConfig['base_role']) { - return $this->crudConfig['base_role']; - } - - throw new RuntimeException(sprintf('the config does not have any role for the ' . - 'method %s nor a global role for the whole action. Add those to your ' . - 'configuration or override the required method', $request->getMethod())); - } protected function getSerializer(): SerializerInterface { diff --git a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php index 9e6555025..730ac32c1 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php +++ b/src/Bundle/ChillMainBundle/CRUD/Controller/CRUDController.php @@ -230,7 +230,7 @@ class CRUDController extends AbstractController */ protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface { - $formClass = $formClass ?? $this->getFormClassFor($action); + $formClass ??= $this->getFormClassFor($action); $form = $this->createForm($formClass, $entity, $formOptions); diff --git a/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php b/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php index c3197936e..4fbf5961d 100644 --- a/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php +++ b/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php @@ -101,7 +101,7 @@ class CRUDRoutesLoader extends Loader $singleCollection = $action['single_collection'] ?? '_entity' === $name ? 'single' : null; if ('collection' === $singleCollection) { -// continue; + // continue; } // compute default action @@ -141,9 +141,7 @@ class CRUDRoutesLoader extends Loader $methods = array_keys(array_filter( $action['methods'], - static function ($value, $key) { - return $value; - }, + static fn ($value, $key) => $value, ARRAY_FILTER_USE_BOTH )); diff --git a/src/Bundle/ChillMainBundle/ChillMainBundle.php b/src/Bundle/ChillMainBundle/ChillMainBundle.php index 4442bd19b..9e276311d 100644 --- a/src/Bundle/ChillMainBundle/ChillMainBundle.php +++ b/src/Bundle/ChillMainBundle/ChillMainBundle.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\MainBundle; +use Chill\MainBundle\Cron\CronJobInterface; use Chill\MainBundle\CRUD\CompilerPass\CRUDControllerCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\ACLFlagsCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\ExportsCompilerPass; @@ -59,6 +60,8 @@ class ChillMainBundle extends Bundle ->addTag('chill.count_notification.user'); $container->registerForAutoconfiguration(EntityWorkflowHandlerInterface::class) ->addTag('chill_main.workflow_handler'); + $container->registerForAutoconfiguration(CronJobInterface::class) + ->addTag('chill_main.cron_job'); $container->addCompilerPass(new SearchableServicesCompilerPass()); $container->addCompilerPass(new ConfigConsistencyCompilerPass()); @@ -69,7 +72,6 @@ class ChillMainBundle extends Bundle $container->addCompilerPass(new NotificationCounterCompilerPass()); $container->addCompilerPass(new MenuCompilerPass()); $container->addCompilerPass(new ACLFlagsCompilerPass()); - $container->addCompilerPass(new GroupingCenterCompilerPass()); $container->addCompilerPass(new CRUDControllerCompilerPass()); $container->addCompilerPass(new ShortMessageCompilerPass()); } diff --git a/src/Bundle/ChillMainBundle/Command/ExecuteCronJobCommand.php b/src/Bundle/ChillMainBundle/Command/ExecuteCronJobCommand.php new file mode 100644 index 000000000..0e81177dc --- /dev/null +++ b/src/Bundle/ChillMainBundle/Command/ExecuteCronJobCommand.php @@ -0,0 +1,55 @@ +cronManager = $cronManager; + } + + protected function configure() + { + $this + ->setDescription('Execute the cronjob(s) given as argument, or one cronjob scheduled by system.') + ->setHelp("If no job is specified, the next available cronjob will be executed by system.\nThis command should be execute every 15 minutes (more or less)") + ->addArgument('job', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'one or more job to force execute (by default, all jobs are executed)', []) + ->addUsage(''); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + if ([] === $input->getArgument('job')) { + $this->cronManager->run(); + + return 0; + } + + foreach ($input->getArgument('job') as $jobName) { + $this->cronManager->run($jobName); + } + + return 0; + } +} diff --git a/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php b/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php index fd8a469d6..ea42fde78 100644 --- a/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php +++ b/src/Bundle/ChillMainBundle/Command/LoadPostalCodesCommand.php @@ -102,11 +102,7 @@ class LoadPostalCodesCommand extends Command try { $this->addPostalCode($row, $output); ++$num; - } catch (ExistingPostalCodeException $ex) { - $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); - } catch (CountryCodeNotFoundException $ex) { - $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); - } catch (PostalCodeNotValidException $ex) { + } catch (ExistingPostalCodeException|CountryCodeNotFoundException|PostalCodeNotValidException $ex) { $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); } ++$line; diff --git a/src/Bundle/ChillMainBundle/Controller/AbsenceController.php b/src/Bundle/ChillMainBundle/Controller/AbsenceController.php new file mode 100644 index 000000000..5dafa4615 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/AbsenceController.php @@ -0,0 +1,65 @@ +getUser(); + $form = $this->createForm(AbsenceType::class, $user); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->flush(); + + return $this->redirect($this->generateUrl('chill_main_user_absence_index')); + } + + return $this->render('@ChillMain/Menu/absence.html.twig', [ + 'user' => $user, + 'form' => $form->createView(), + ]); + } + + /** + * @Route( + * "/{_locale}/absence/unset", + * name="chill_main_user_absence_unset", + * methods={"GET", "POST"} + * ) + */ + public function unsetAbsence(Request $request) + { + $user = $this->getUser(); + + $user->setAbsenceStart(null); + $em = $this->getDoctrine()->getManager(); + $em->flush(); + + return $this->redirect($this->generateUrl('chill_main_user_absence_index')); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php b/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php new file mode 100644 index 000000000..aab63aea3 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php @@ -0,0 +1,110 @@ +security = $security; + $this->entityManager = $entityManager; + $this->serializer = $serializer; + } + + /** + * @Route("/api/1.0/main/address/reference-match/{id}/set/reviewed", methods={"POST"}) + */ + public function markAddressAsReviewed(Address $address): JsonResponse + { + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + + $address->setRefStatus(Address::ADDR_REFERENCE_STATUS_REVIEWED); + + $this->entityManager->flush(); + + return new JsonResponse( + $this->serializer->serialize($address, 'json', [AbstractNormalizer::GROUPS => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } + + /** + * Set an address back to "to review". Only if the address is in "reviewed" state. + * + * @Route("/api/1.0/main/address/reference-match/{id}/set/to_review", methods={"POST"}) + */ + public function markAddressAsToReview(Address $address): JsonResponse + { + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + + if (Address::ADDR_REFERENCE_STATUS_REVIEWED !== $address->getRefStatus()) { + throw new AccessDeniedHttpException("forbidden to mark a matching address to 'to review'"); + } + + $address->setRefStatus(Address::ADDR_REFERENCE_STATUS_TO_REVIEW); + + $this->entityManager->flush(); + + return new JsonResponse( + $this->serializer->serialize($address, 'json', [AbstractNormalizer::GROUPS => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } + + /** + * @Route("/api/1.0/main/address/reference-match/{id}/sync-with-reference", methods={"POST"}) + */ + public function syncAddressWithReference(Address $address): JsonResponse + { + if (null === $address->getAddressReference()) { + throw new BadRequestHttpException('this address does not have any address reference'); + } + + $address->syncWithReference($address->getAddressReference()); + + $this->entityManager->flush(); + + return new JsonResponse( + $this->serializer->serialize($address, 'json', [AbstractNormalizer::GROUPS => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 84bf80c6b..6c4ea0269 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -164,7 +164,7 @@ class ExportController extends AbstractController { $this->denyAccessUnlessGranted(SavedExportVoter::GENERATE, $savedExport); - $key = md5(uniqid((string) mt_rand(), false)); + $key = md5(uniqid((string) random_int(0, mt_getrandmax()), false)); $this->redis->setEx($key, 3600, serialize($savedExport->getOptions())); @@ -298,6 +298,8 @@ class ExportController extends AbstractController 'csrf_protection' => $isGenerate ? false : true, ]); + // TODO: add a condition to be able to select a regroupment of centers? + if ('centers' === $step || 'generate_centers' === $step) { $builder->add('centers', PickCenterType::class, [ 'export_alias' => $alias, @@ -479,7 +481,7 @@ class ExportController extends AbstractController 'alias' => $alias, ]; unset($parameters['_token']); - $key = md5(uniqid((string) mt_rand(), false)); + $key = md5(uniqid((string) random_int(0, mt_getrandmax()), false)); $this->redis->setEx($key, 3600, serialize($parameters)); @@ -663,7 +665,7 @@ class ExportController extends AbstractController $this->logger->notice('[export] choices for an export unserialized', [ 'key' => $key, - 'rawData' => json_encode($rawData), + 'rawData' => json_encode($rawData, JSON_THROW_ON_ERROR), ]); return $rawData; diff --git a/src/Bundle/ChillMainBundle/Controller/GeographicalUnitByAddressApiController.php b/src/Bundle/ChillMainBundle/Controller/GeographicalUnitByAddressApiController.php new file mode 100644 index 000000000..988439de5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/GeographicalUnitByAddressApiController.php @@ -0,0 +1,75 @@ +paginatorFactory = $paginatorFactory; + $this->geographicalUnitRepository = $geographicalUnitRepository; + $this->security = $security; + $this->serializer = $serializer; + } + + /** + * @Route("/api/1.0/main/geographical-unit/by-address/{id}.{_format}", requirements={"_format": "json"}) + */ + public function getGeographicalUnitCoveringAddress(Address $address): JsonResponse + { + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + + $count = $this->geographicalUnitRepository->countGeographicalUnitContainingAddress($address); + $pagination = $this->paginatorFactory->create($count); + $units = $this->geographicalUnitRepository->findGeographicalUnitContainingAddress($address, $pagination->getCurrentPageFirstItemNumber(), $pagination->getItemsPerPage()); + + $collection = new Collection($units, $pagination); + + return new JsonResponse( + $this->serializer->serialize($collection, 'json', [AbstractNormalizer::GROUPS => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/LocationController.php b/src/Bundle/ChillMainBundle/Controller/LocationController.php index f3c4db082..78a4f7ba3 100644 --- a/src/Bundle/ChillMainBundle/Controller/LocationController.php +++ b/src/Bundle/ChillMainBundle/Controller/LocationController.php @@ -28,7 +28,7 @@ class LocationController extends CRUDController protected function customizeQuery(string $action, Request $request, $query): void { - $query->where('e.availableForUsers = true'); //TODO not working + $query->where('e.availableForUsers = TRUE'); } protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationController.php b/src/Bundle/ChillMainBundle/Controller/NotificationController.php index a6e876b6d..327a06df6 100644 --- a/src/Bundle/ChillMainBundle/Controller/NotificationController.php +++ b/src/Bundle/ChillMainBundle/Controller/NotificationController.php @@ -282,9 +282,7 @@ class NotificationController extends AbstractController if ($request->query->has('edit')) { $commentId = $request->query->getInt('edit'); - $editedComment = $notification->getComments()->filter(static function (NotificationComment $c) use ($commentId) { - return $c->getId() === $commentId; - })->first(); + $editedComment = $notification->getComments()->filter(static fn (NotificationComment $c) => $c->getId() === $commentId)->first(); if (false === $editedComment) { throw $this->createNotFoundException("Comment with id {$commentId} does not exists nor belong to this notification"); diff --git a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php index 372d0d7d1..5d32a8dbb 100644 --- a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php +++ b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php @@ -158,9 +158,7 @@ class PermissionsGroupController extends AbstractController 'edit_form' => $editForm->createView(), 'role_scopes_sorted' => $roleScopesSorted, 'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()), - 'delete_role_scopes_form' => array_map(static function ($form) { - return $form->createView(); - }, $deleteRoleScopesForm), + 'delete_role_scopes_form' => array_map(static fn ($form) => $form->createView(), $deleteRoleScopesForm), 'add_role_scopes_form' => $addRoleScopesForm->createView(), ]); } @@ -305,9 +303,7 @@ class PermissionsGroupController extends AbstractController 'role_scopes_sorted' => $roleScopesSorted, 'edit_form' => $editForm->createView(), 'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()), - 'delete_role_scopes_form' => array_map(static function ($form) { - return $form->createView(); - }, $deleteRoleScopesForm), + 'delete_role_scopes_form' => array_map(static fn ($form) => $form->createView(), $deleteRoleScopesForm), 'add_role_scopes_form' => $addRoleScopesForm->createView(), ]); } @@ -449,9 +445,7 @@ class PermissionsGroupController extends AbstractController 'role_scopes_sorted' => $roleScopesSorted, 'edit_form' => $editForm->createView(), 'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()), - 'delete_role_scopes_form' => array_map(static function ($form) { - return $form->createView(); - }, $deleteRoleScopesForm), + 'delete_role_scopes_form' => array_map(static fn ($form) => $form->createView(), $deleteRoleScopesForm), 'add_role_scopes_form' => $addRoleScopesForm->createView(), ]); } @@ -573,9 +567,7 @@ class PermissionsGroupController extends AbstractController if (!array_key_exists($roleScope->getRole(), $expandedRoles)) { $expandedRoles[$roleScope->getRole()] = array_map( - static function (Role $role) { - return $role->getRole(); - }, + static fn (Role $role) => $role->getRole(), $this->roleHierarchy ->getReachableRoles( [new Role($roleScope->getRole())] diff --git a/src/Bundle/ChillMainBundle/Controller/RegroupmentController.php b/src/Bundle/ChillMainBundle/Controller/RegroupmentController.php new file mode 100644 index 000000000..c73b03027 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/RegroupmentController.php @@ -0,0 +1,26 @@ +addOrderBy('e.id', 'ASC'); + + return parent::orderQuery($action, $query, $request, $paginator); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/ScopeApiController.php b/src/Bundle/ChillMainBundle/Controller/ScopeApiController.php new file mode 100644 index 000000000..85041f0f3 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/ScopeApiController.php @@ -0,0 +1,25 @@ +andWhere($query->expr()->eq('e.active', "'TRUE'")); + } + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/SearchController.php b/src/Bundle/ChillMainBundle/Controller/SearchController.php index 8592dd2c3..7eec60324 100644 --- a/src/Bundle/ChillMainBundle/Controller/SearchController.php +++ b/src/Bundle/ChillMainBundle/Controller/SearchController.php @@ -109,10 +109,8 @@ class SearchController extends AbstractController ->getHasAdvancedFormSearchServices(); if (count($advancedSearchProviders) === 1) { - reset($advancedSearchProviders); - return $this->redirectToRoute('chill_main_advanced_search', [ - 'name' => key($advancedSearchProviders), + 'name' => array_key_first($advancedSearchProviders), ]); } diff --git a/src/Bundle/ChillMainBundle/Controller/UserApiController.php b/src/Bundle/ChillMainBundle/Controller/UserApiController.php index b29fe7c8e..da873e118 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserApiController.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; +use Chill\MainBundle\Pagination\PaginatorInterface; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -70,4 +71,13 @@ class UserApiController extends ApiController $query->andWhere($query->expr()->eq('e.enabled', "'TRUE'")); } } + + /** + * @param mixed $query + * @param mixed $_format + */ + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format) + { + return $query->orderBy('e.label', 'ASC'); + } } diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index 9d3941411..ecf8a3c9c 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -337,14 +337,13 @@ class UserController extends CRUDController [ 'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($entity, $request)->createView(), 'delete_groupcenter_form' => array_map( - static function (Form $form) { - return $form->createView(); - }, + static fn (Form $form) => $form->createView(), iterator_to_array($this->getDeleteLinkGroupCenterByUser($entity, $request), true) ), ] ); - } elseif ('index' === $action) { + } + if ('index' === $action) { return array_merge( ['allow_change_password' => $this->parameterBag->get('chill_main.access_user_change_password')], $defaultTemplateParameters diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php index b451e9209..f0e728252 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php @@ -93,6 +93,45 @@ class WorkflowApiController ); } + /** + * Return a list of workflow which are waiting an action for the user. + * + * @Route("/api/1.0/main/workflow/my-cc", methods={"GET"}) + */ + public function myWorkflowCc(Request $request): JsonResponse + { + if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { + throw new AccessDeniedException(); + } + + $total = $this->entityWorkflowRepository->countByCc($this->security->getUser()); + + if ($request->query->getBoolean('countOnly', false)) { + return new JsonResponse( + $this->serializer->serialize(new Counter($total), 'json'), + JsonResponse::HTTP_OK, + [], + true + ); + } + + $paginator = $this->paginatorFactory->create($total); + + $workflows = $this->entityWorkflowRepository->findByCc( + $this->security->getUser(), + ['id' => 'DESC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return new JsonResponse( + $this->serializer->serialize(new Collection($workflows, $paginator), 'json', ['groups' => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } + /** * @Route("/api/1.0/main/workflow/{id}/subscribe", methods={"POST"}) */ diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index 9be2f04fd..36647612b 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -30,6 +30,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Core\Security; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\TransitionBlocker; @@ -48,11 +49,13 @@ class WorkflowController extends AbstractController private Registry $registry; + private Security $security; + private TranslatorInterface $translator; private ValidatorInterface $validator; - public function __construct(EntityWorkflowManager $entityWorkflowManager, EntityWorkflowRepository $entityWorkflowRepository, ValidatorInterface $validator, PaginatorFactory $paginatorFactory, Registry $registry, EntityManagerInterface $entityManager, TranslatorInterface $translator) + public function __construct(EntityWorkflowManager $entityWorkflowManager, EntityWorkflowRepository $entityWorkflowRepository, ValidatorInterface $validator, PaginatorFactory $paginatorFactory, Registry $registry, EntityManagerInterface $entityManager, TranslatorInterface $translator, Security $security) { $this->entityWorkflowManager = $entityWorkflowManager; $this->entityWorkflowRepository = $entityWorkflowRepository; @@ -61,6 +64,7 @@ class WorkflowController extends AbstractController $this->registry = $registry; $this->entityManager = $entityManager; $this->translator = $translator; + $this->security = $security; } /** @@ -85,7 +89,6 @@ class WorkflowController extends AbstractController ->setRelatedEntityClass($request->query->get('entityClass')) ->setRelatedEntityId($request->query->getInt('entityId')) ->setWorkflowName($request->query->get('workflow')) - ->addSubscriberToStep($this->getUser()) ->addSubscriberToFinal($this->getUser()); $errors = $this->validator->validate($entityWorkflow, null, ['creation']); @@ -225,6 +228,33 @@ class WorkflowController extends AbstractController ); } + /** + * @Route("/{_locale}/main/workflow/list/cc", name="chill_main_workflow_list_cc") + */ + public function myWorkflowsCc(Request $request): Response + { + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); + + $total = $this->entityWorkflowRepository->countByDest($this->getUser()); + $paginator = $this->paginatorFactory->create($total); + + $workflows = $this->entityWorkflowRepository->findByCc( + $this->getUser(), + ['createdAt' => 'DESC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return $this->render( + '@ChillMain/Workflow/list.html.twig', + [ + 'workflows' => $this->buildHandler($workflows), + 'paginator' => $paginator, + 'step' => 'cc', + ] + ); + } + /** * @Route("/{_locale}/main/workflow/list/dest", name="chill_main_workflow_list_dest") */ @@ -292,10 +322,22 @@ class WorkflowController extends AbstractController if (count($workflow->getEnabledTransitions($entityWorkflow)) > 0) { // possible transition + + $usersInvolved = $entityWorkflow->getUsersInvolved(); + $currentUserFound = array_search($this->security->getUser(), $usersInvolved, true); + + if (false !== $currentUserFound) { + unset($usersInvolved[$currentUserFound]); + } + $transitionForm = $this->createForm( WorkflowStepType::class, $entityWorkflow->getCurrentStep(), - ['transition' => true, 'entity_workflow' => $entityWorkflow] + [ + 'transition' => true, + 'entity_workflow' => $entityWorkflow, + 'suggested_users' => $usersInvolved + ] ); $transitionForm->handleRequest($request); @@ -303,12 +345,10 @@ class WorkflowController extends AbstractController if ($transitionForm->isSubmitted() && $transitionForm->isValid()) { if (!$workflow->can($entityWorkflow, $transition = $transitionForm['transition']->getData()->getName())) { $blockers = $workflow->buildTransitionBlockerList($entityWorkflow, $transition); - $msgs = array_map(function (TransitionBlocker $tb) { - return $this->translator->trans( - $tb->getMessage(), - $tb->getParameters() - ); - }, iterator_to_array($blockers)); + $msgs = array_map(fn (TransitionBlocker $tb) => $this->translator->trans( + $tb->getMessage(), + $tb->getParameters() + ), iterator_to_array($blockers)); throw $this->createAccessDeniedException( sprintf( @@ -319,6 +359,7 @@ class WorkflowController extends AbstractController } // TODO symfony 5: add those "future" on context ($workflow->apply($entityWorkflow, $transition, $context) + $entityWorkflow->futureCcUsers = $transitionForm['future_cc_users']->getData(); $entityWorkflow->futureDestUsers = $transitionForm['future_dest_users']->getData(); $entityWorkflow->futureDestEmails = $transitionForm['future_dest_emails']->getData(); diff --git a/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php b/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php new file mode 100644 index 000000000..4e1ca9ff6 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Cron/CronJobInterface.php @@ -0,0 +1,23 @@ + + */ + private iterable $jobs; + + private LoggerInterface $logger; + + /** + * @param CronJobInterface[] $jobs + */ + public function __construct( + CronJobExecutionRepositoryInterface $cronJobExecutionRepository, + EntityManagerInterface $entityManager, + iterable $jobs, + LoggerInterface $logger + ) { + $this->cronJobExecutionRepository = $cronJobExecutionRepository; + $this->entityManager = $entityManager; + $this->jobs = $jobs; + $this->logger = $logger; + } + + public function run(?string $forceJob = null): void + { + if (null !== $forceJob) { + $this->runForce($forceJob); + + return; + } + + [$orderedJobs, $lasts] = $this->getOrderedJobs(); + + foreach ($orderedJobs as $job) { + if ($job->canRun($lasts[$job->getKey()] ?? null)) { + if (array_key_exists($job->getKey(), $lasts)) { + $this->entityManager + ->createQuery(self::UPDATE_BEFORE_EXEC) + ->setParameters([ + 'now' => new DateTimeImmutable('now'), + 'key' => $job->getKey(), + ]) + ->execute(); + } else { + $execution = new CronJobExecution($job->getKey()); + $this->entityManager->persist($execution); + $this->entityManager->flush(); + } + $this->entityManager->clear(); + + try { + $this->logger->info(sprintf('%sWill run job', self::LOG_PREFIX), ['job' => $job->getKey()]); + $job->run(); + + $this->entityManager + ->createQuery(self::UPDATE_AFTER_EXEC) + ->setParameters([ + 'now' => new DateTimeImmutable('now'), + 'status' => CronJobExecution::SUCCESS, + 'key' => $job->getKey(), + ]) + ->execute(); + + $this->logger->info(sprintf('%sSuccessfully run job', self::LOG_PREFIX), ['job' => $job->getKey()]); + + return; + } catch (Exception $e) { + $this->logger->error(sprintf('%sRunning job failed', self::LOG_PREFIX), ['job' => $job->getKey()]); + $this->entityManager + ->createQuery(self::UPDATE_AFTER_EXEC) + ->setParameters([ + 'now' => new DateTimeImmutable('now'), + 'status' => CronJobExecution::FAILURE, + 'key' => $job->getKey(), + ]) + ->execute(); + + return; + } + } + } + } + + /** + * @return array<0: CronJobInterface[], 1: array> + */ + private function getOrderedJobs(): array + { + /** @var array $lasts */ + $lasts = []; + + foreach ($this->cronJobExecutionRepository->findAll() as $execution) { + $lasts[$execution->getKey()] = $execution; + } + + // order by last, NULL first + $orderedJobs = iterator_to_array($this->jobs); + usort( + $orderedJobs, + static function (CronJobInterface $a, CronJobInterface $b) use ($lasts): int { + if ( + (!array_key_exists($a->getKey(), $lasts) && !array_key_exists($b->getKey(), $lasts)) + ) { + return 0; + } + + if (!array_key_exists($a->getKey(), $lasts) && array_key_exists($b->getKey(), $lasts)) { + return -1; + } + + if (!array_key_exists($b->getKey(), $lasts) && array_key_exists($a->getKey(), $lasts)) { + return 1; + } + + return $lasts[$a->getKey()]->getLastStart() <=> $lasts[$b->getKey()]->getLastStart(); + } + ); + + return [$orderedJobs, $lasts]; + } + + private function runForce(string $forceJob): void + { + foreach ($this->jobs as $job) { + if ($job->getKey() === $forceJob) { + $job->run(); + } + } + } +} diff --git a/src/Bundle/ChillMainBundle/Cron/CronManagerInterface.php b/src/Bundle/ChillMainBundle/Cron/CronManagerInterface.php new file mode 100644 index 000000000..d2292d455 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Cron/CronManagerInterface.php @@ -0,0 +1,20 @@ +setRefId($this->faker->numerify('ref-id-######')); $ar->setStreet($this->faker->streetName); - $ar->setStreetNumber((string) mt_rand(0, 199)); + $ar->setStreetNumber((string) random_int(0, 199)); $ar->setPoint($this->getRandomPoint()); $ar->setPostcode($this->getReference( LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)] @@ -89,8 +89,8 @@ class LoadAddressReferences extends AbstractFixture implements ContainerAwareInt { $lonBrussels = 4.35243; $latBrussels = 50.84676; - $lon = $lonBrussels + 0.01 * mt_rand(-5, 5); - $lat = $latBrussels + 0.01 * mt_rand(-5, 5); + $lon = $lonBrussels + 0.01 * random_int(-5, 5); + $lat = $latBrussels + 0.01 * random_int(-5, 5); return Point::fromLonLat($lon, $lat); } diff --git a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLanguages.php b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLanguages.php index f2876eefb..88a4869cc 100644 --- a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLanguages.php +++ b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadLanguages.php @@ -50,8 +50,8 @@ class LoadLanguages extends AbstractFixture implements ContainerAwareInterface, foreach (Intl::getLanguageBundle()->getLanguageNames() as $code => $language) { if ( - !in_array($code, $this->regionalVersionToInclude, true) - && !in_array($code, $this->ancientToExclude, true) + !in_array($code, $this->regionalVersionToInclude, true) + && !in_array($code, $this->ancientToExclude, true) ) { $lang = (new Language()) ->setId($code) diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 2a785af42..c86a69be2 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Controller\CountryController; use Chill\MainBundle\Controller\LanguageController; use Chill\MainBundle\Controller\LocationController; use Chill\MainBundle\Controller\LocationTypeController; +use Chill\MainBundle\Controller\RegroupmentController; use Chill\MainBundle\Controller\UserController; use Chill\MainBundle\Controller\UserJobApiController; use Chill\MainBundle\Controller\UserJobController; @@ -45,9 +46,11 @@ use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType; use Chill\MainBundle\Doctrine\Type\PointType; use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Country; +use Chill\MainBundle\Entity\GeographicalUnitLayer; use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\LocationType; +use Chill\MainBundle\Entity\Regroupment; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Form\CivilityType; @@ -55,6 +58,7 @@ use Chill\MainBundle\Form\CountryType; use Chill\MainBundle\Form\LanguageType; use Chill\MainBundle\Form\LocationFormType; use Chill\MainBundle\Form\LocationTypeType; +use Chill\MainBundle\Form\RegroupmentType; use Chill\MainBundle\Form\UserJobType; use Chill\MainBundle\Form\UserType; use Exception; @@ -148,6 +152,11 @@ class ChillMainExtension extends Extension implements $config['access_permissions_group_list'] ); + $container->setParameter( + 'chill_main.add_address', + $config['add_address'] + ); + $container->setParameter( 'chill_main.routing.resources', $config['routing']['resources'] @@ -223,6 +232,7 @@ class ChillMainExtension extends Extension implements 'installation' => [ 'name' => $config['installation_name'], ], 'available_languages' => $config['available_languages'], + 'add_address' => $config['add_address'], ], 'form_themes' => ['@ChillMain/Form/fields.html.twig'], ]; @@ -493,6 +503,27 @@ class ChillMainExtension extends Extension implements ], ], ], + [ + 'class' => Regroupment::class, + 'name' => 'regroupment', + 'base_path' => '/admin/regroupment', + 'form_class' => RegroupmentType::class, + 'controller' => RegroupmentController::class, + 'actions' => [ + 'index' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillMain/Admin/Regroupment/index.html.twig', + ], + 'new' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillMain/Admin/Regroupment/new.html.twig', + ], + 'edit' => [ + 'role' => 'ROLE_ADMIN', + 'template' => '@ChillMain/Admin/Regroupment/edit.html.twig', + ], + ], + ], ], 'apis' => [ [ @@ -625,6 +656,7 @@ class ChillMainExtension extends Extension implements ], [ 'class' => \Chill\MainBundle\Entity\Scope::class, + 'controller' => \Chill\MainBundle\Controller\ScopeApiController::class, 'name' => 'scope', 'base_path' => '/api/1.0/main/scope', 'base_role' => 'ROLE_USER', @@ -701,6 +733,20 @@ class ChillMainExtension extends Extension implements ], ], ], + [ + 'class' => GeographicalUnitLayer::class, + 'name' => 'geographical-unit-layer', + 'base_path' => '/api/1.0/main/geographical-unit-layer', + 'base_role' => 'ROLE_USER', + 'actions' => [ + '_index' => [ + 'methods' => [ + Request::METHOD_GET => true, + Request::METHOD_HEAD => true, + ], + ], + ], + ] ], ]); } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php deleted file mode 100644 index f0c06564b..000000000 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/GroupingCenterCompilerPass.php +++ /dev/null @@ -1,37 +0,0 @@ -hasDefinition('chill.main.form.pick_centers_type')) { - throw new LogicException('The service chill.main.form.pick_centers_type does ' - . 'not exists in container'); - } - - $pickCenterType = $container->getDefinition('chill.main.form.pick_centers_type'); - - foreach ($container->findTaggedServiceIds('chill.grouping_center') as $serviceId => $tagged) { - $pickCenterType->addMethodCall( - 'addGroupingCenter', - [new Reference($serviceId)] - ); - } - } -} diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/MenuCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/MenuCompilerPass.php index c41a32056..d6a27c943 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/MenuCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/MenuCompilerPass.php @@ -37,13 +37,7 @@ class MenuCompilerPass implements CompilerPassInterface ]; } - usort($services, static function ($a, $b) { - if ($a['priority'] === $b['priority']) { - return 0; - } - - return ($a['priority'] < $b['priority']) ? -1 : 1; - }); + usort($services, static fn ($a, $b) => $a['priority'] <=> $b['priority']); foreach ($services as $service) { $class = $container->getDefinition($service['id'])->getClass(); diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php index f75840c3a..f9fdb80d0 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php @@ -34,7 +34,7 @@ class ShortMessageCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - $config = $container->resolveEnvPlaceholders($container->getParameter('chill_main.short_messages', null), true); + $config = $container->resolveEnvPlaceholders($container->getParameter('chill_main.short_messages'), true); // weird fix for special characters $config['dsn'] = str_replace(['%%'], ['%'], $config['dsn']); $dsn = parse_url($config['dsn']); @@ -43,7 +43,7 @@ class ShortMessageCompilerPass implements CompilerPassInterface if ('null' === $dsn['scheme'] || false === $config['enabled']) { $defaultTransporter = new Reference(NullShortMessageSender::class); } elseif ('ovh' === $dsn['scheme']) { - if (!class_exists('\Ovh\Api')) { + if (!class_exists('\\' . \Ovh\Api::class)) { throw new RuntimeException('Class \\Ovh\\Api not found'); } @@ -66,17 +66,17 @@ class ShortMessageCompilerPass implements CompilerPassInterface $ovh = new Definition(); $ovh - ->setClass('\Ovh\Api') + ->setClass('\\' . \Ovh\Api::class) ->setArgument(0, $dsn['user']) ->setArgument(1, $dsn['pass']) ->setArgument(2, $dsn['host']) ->setArgument(3, $dsn['queries']['consumer_key']); - $container->setDefinition('Ovh\Api', $ovh); + $container->setDefinition(\Ovh\Api::class, $ovh); $ovhSender = new Definition(); $ovhSender ->setClass(OvhShortMessageSender::class) - ->setArgument(0, new Reference('Ovh\Api')) + ->setArgument(0, new Reference(\Ovh\Api::class)) ->setArgument(1, $dsn['queries']['service_name']) ->setArgument(2, $dsn['queries']['sender']) ->setArgument(3, new Reference(LoggerInterface::class)) diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php index 3f09f8181..4605f35ab 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php @@ -37,7 +37,7 @@ class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('chill_main'); - $rootNode = $treeBuilder->getRootNode('chill_main'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() @@ -274,7 +274,17 @@ class Configuration implements ConfigurationInterface ->end() ->end() // end of root/children ->end() // end of root -; + ; + + $rootNode->children() + ->arrayNode('add_address')->addDefaultsIfNotSet()->children() + ->scalarNode('default_country')->cannotBeEmpty()->defaultValue('BE')->end() + ->arrayNode('map_center')->children() + ->scalarNode('x')->cannotBeEmpty()->defaultValue(50.8443)->end() + ->scalarNode('y')->cannotBeEmpty()->defaultValue(4.3523)->end() + ->scalarNode('z')->cannotBeEmpty()->defaultValue(15)->end() + ->end() + ->end(); return $treeBuilder; } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php index 223a7b6cb..d5234bfbe 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AbstractWidgetsCompilerPass.php @@ -193,8 +193,7 @@ abstract class AbstractWidgetsCompilerPass implements CompilerPassInterface /** @var WidgetFactoryInterface $factory */ $factory = $this->widgetServices[$alias]; // get the config (under the key which equals to widget_alias - $config = isset($param[$factory->getWidgetAlias()]) ? - $param[$factory->getWidgetAlias()] : []; + $config = $param[$factory->getWidgetAlias()] ?? []; // register the service into the container $serviceId = $this->registerServiceIntoContainer( $container, diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php index 468314159..41ec16818 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php @@ -135,15 +135,11 @@ trait AddWidgetConfigurationTrait /** * add configuration nodes for the widget at the given place. - * - * @param type $place - * - * @return type */ - protected function addWidgetsConfiguration($place, ContainerBuilder $containerBuilder) + protected function addWidgetsConfiguration(string $place, ContainerBuilder $containerBuilder) { $treeBuilder = new TreeBuilder($place); - $root = $treeBuilder->getRootNode($place) + $root = $treeBuilder->getRootNode() ->canBeUnset() ->info('register widgets on place "' . $place . '"'); @@ -174,7 +170,7 @@ trait AddWidgetConfigurationTrait // adding the possible config on each widget under the widget_alias foreach ($this->filterWidgetByPlace($place) as $factory) { $builder = new TreeBuilder($factory->getWidgetAlias()); - $widgetOptionsRoot = $builder->getRootNode($factory->getWidgetAlias()); + $widgetOptionsRoot = $builder->getRootNode(); $widgetOptionsRoot->canBeUnset() ->info(sprintf( 'the configuration for the widget "%s" (only required if this widget is set in widget_alias)', @@ -215,7 +211,7 @@ trait AddWidgetConfigurationTrait * * @throws InvalidConfigurationException if a service's tag does not have the "alias" key * - * @return type + * @return array */ protected function getWidgetAliasesbyPlace($place, ContainerBuilder $containerBuilder) { diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php index b9ca9c4b6..c76bd22cf 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php @@ -33,9 +33,7 @@ class Greatest extends FunctionNode public function getSql(SqlWalker $sqlWalker) { - return 'GREATEST(' . implode(', ', array_map(static function (Node $expr) use ($sqlWalker) { - return $expr->dispatch($sqlWalker); - }, $this->exprs)) . ')'; + return 'GREATEST(' . implode(', ', array_map(static fn (Node $expr) => $expr->dispatch($sqlWalker), $this->exprs)) . ')'; } public function parse(Parser $parser) diff --git a/src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php b/src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php index 0c8a1b17d..9befa5f40 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php +++ b/src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php @@ -33,9 +33,7 @@ class Least extends FunctionNode public function getSql(SqlWalker $sqlWalker) { - return 'LEAST(' . implode(', ', array_map(static function (Node $expr) use ($sqlWalker) { - return $expr->dispatch($sqlWalker); - }, $this->exprs)) . ')'; + return 'LEAST(' . implode(', ', array_map(static fn (Node $expr) => $expr->dispatch($sqlWalker), $this->exprs)) . ')'; } public function parse(Parser $parser) diff --git a/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php b/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php index c4c18d179..684030ee3 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php +++ b/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php @@ -41,7 +41,7 @@ class Point implements JsonSerializable public static function fromGeoJson(string $geojson): self { - $a = json_decode($geojson); + $a = json_decode($geojson, null, 512, JSON_THROW_ON_ERROR); if (null === $a) { throw PointException::badJsonString($geojson); @@ -96,7 +96,7 @@ class Point implements JsonSerializable { $array = $this->toArrayGeoJson(); - return json_encode($array); + return json_encode($array, JSON_THROW_ON_ERROR); } public function toWKT(): string diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php index 9a0f8b7b3..1bd1a453a 100644 --- a/src/Bundle/ChillMainBundle/Entity/Address.php +++ b/src/Bundle/ChillMainBundle/Entity/Address.php @@ -12,6 +12,10 @@ declare(strict_types=1); namespace Chill\MainBundle\Entity; use Chill\MainBundle\Doctrine\Model\Point; +use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; +use Chill\MainBundle\Doctrine\Model\TrackCreationTrait; +use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; +use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\ThirdPartyBundle\Entity\ThirdParty; use DateTime; use DateTimeInterface; @@ -28,8 +32,28 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; * @ORM\Table(name="chill_main_address") * @ORM\HasLifecycleCallbacks */ -class Address +class Address implements TrackCreationInterface, TrackUpdateInterface { + use TrackCreationTrait; + use TrackUpdateTrait; + + /** + * When an Address does match with the AddressReference + */ + public const ADDR_REFERENCE_STATUS_MATCH = 'match'; + + /** + * When an Address does not match with the AddressReference, and + * is pending for a review + */ + public const ADDR_REFERENCE_STATUS_TO_REVIEW = 'to_review'; + + /** + * When an Address does not match with the AddressReference, but + * is reviewed + */ + public const ADDR_REFERENCE_STATUS_REVIEWED = 'reviewed'; + /** * @ORM\ManyToOne(targetEntity=AddressReference::class) * @Groups({"write"}) @@ -37,67 +61,48 @@ class Address private ?AddressReference $addressReference = null; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $buildingName; + private string $buildingName = ''; /** - * @ORM\Column(type="boolean") + * @ORM\Column(type="boolean", options={"default": false}) * @Groups({"write"}) */ private bool $confidential = false; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $corridor; + private string $corridor = ''; /** - * A list of metadata, added by customizable fields. - * - * @var array - */ - private $customs = []; - - /** - * @var string|null - * * used for the CEDEX information * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $distribution; + private string $distribution = ''; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $extra; + private string $extra = ''; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $flat; + private string $flat = ''; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $floor; + private string $floor = ''; /** * List of geographical units and addresses. @@ -131,11 +136,9 @@ class Address * True if the address is a "no address", aka homeless person, ... * * @Groups({"write"}) - * @ORM\Column(type="boolean") - * - * @var bool + * @ORM\Column(type="boolean", options={"default": false}) */ - private $isNoAddress = false; + private bool $isNoAddress = false; /** * A ThirdParty reference for person's addresses that are linked to a third party. @@ -146,7 +149,7 @@ class Address * @Groups({"write"}) * @ORM\JoinColumn(nullable=true, onDelete="SET NULL") */ - private $linkedToThirdParty; + private ?ThirdParty $linkedToThirdParty = null; /** * A geospatial field storing the coordinates of the Address. @@ -156,7 +159,7 @@ class Address * @ORM\Column(type="point", nullable=true) * @Groups({"write"}) */ - private $point; + private ?Point $point = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode") @@ -166,28 +169,36 @@ class Address private ?PostalCode $postcode = null; /** - * @var string|null - * - * @ORM\Column(type="string", length=255, nullable=true) - * @Groups({"write"}) + * @var self::ADDR_REFERENCE_STATUS_* + * @ORM\Column(type="text", nullable=false, options={"default": self::ADDR_REFERENCE_STATUS_MATCH}) */ - private $steps; + private string $refStatus = self::ADDR_REFERENCE_STATUS_MATCH; /** - * @var string - * - * @ORM\Column(type="string", length=255) - * @Groups({"write"}) + * @ORM\Column(type="datetime_immutable", nullable=false, options={"default": "CURRENT_TIMESTAMP"}) */ - private $street = ''; + private \DateTimeImmutable $refStatusLastUpdate; /** - * @var string * - * @ORM\Column(type="string", length=255) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @Groups({"write"}) */ - private $streetNumber = ''; + private string $steps = ''; + + /** + * + * @ORM\Column(type="text", nullable=false, options={"default": ""}) + * @Groups({"write"}) + */ + private string $street = ''; + + /** + * + * @ORM\Column(type="text", nullable=false, options={"default": ""}) + * @Groups({"write"}) + */ + private string $streetNumber = ''; /** * Indicates when the address starts validation. Used to build an history @@ -210,6 +221,7 @@ class Address public function __construct() { $this->validFrom = new DateTime(); + $this->refStatusLastUpdate = new \DateTimeImmutable('now'); $this->geographicalUnits = new ArrayCollection(); } @@ -220,7 +232,6 @@ class Address ->setBuildingName($original->getBuildingName()) ->setConfidential($original->getConfidential()) ->setCorridor($original->getCorridor()) - ->setCustoms($original->getCustoms()) ->setDistribution($original->getDistribution()) ->setExtra($original->getExtra()) ->setFlat($original->getFlat()) @@ -239,11 +250,20 @@ class Address public static function createFromAddressReference(AddressReference $original): Address { return (new Address()) - ->setPoint($original->getPoint()) - ->setPostcode($original->getPostcode()) - ->setStreet($original->getStreet()) - ->setStreetNumber($original->getStreetNumber()) - ->setAddressReference($original); + ->syncWithReference($original); + } + + public function syncWithReference(AddressReference $addressReference): Address + { + $this + ->setPoint($addressReference->getPoint()) + ->setPostcode($addressReference->getPostcode()) + ->setStreet($addressReference->getStreet()) + ->setStreetNumber($addressReference->getStreetNumber()) + ->setRefStatus(self::ADDR_REFERENCE_STATUS_MATCH) + ->setAddressReference($addressReference); + + return $this; } public function getAddressReference(): ?AddressReference @@ -251,7 +271,7 @@ class Address return $this->addressReference; } - public function getBuildingName(): ?string + public function getBuildingName(): string { return $this->buildingName; } @@ -261,35 +281,27 @@ class Address return $this->confidential; } - public function getCorridor(): ?string + public function getCorridor(): string { return $this->corridor; } - /** - * Get customs informations in the address. - */ - public function getCustoms(): array - { - return $this->customs; - } - - public function getDistribution(): ?string + public function getDistribution(): string { return $this->distribution; } - public function getExtra(): ?string + public function getExtra(): string { return $this->extra; } - public function getFlat(): ?string + public function getFlat(): string { return $this->flat; } - public function getFloor(): ?string + public function getFloor(): string { return $this->floor; } @@ -340,12 +352,22 @@ class Address return $this->postcode; } - public function getSteps(): ?string + public function getRefStatus(): string + { + return $this->refStatus; + } + + public function getRefStatusLastUpdate(): \DateTimeImmutable + { + return $this->refStatusLastUpdate; + } + + public function getSteps(): string { return $this->steps; } - public function getStreet(): ?string + public function getStreet(): string { return $this->street; } @@ -354,6 +376,7 @@ class Address * Get streetAddress1 (legacy function). * * @return string + * @deprecated */ public function getStreetAddress1() { @@ -364,13 +387,14 @@ class Address * Get streetAddress2 (legacy function). * * @return string + * @deprecated */ public function getStreetAddress2() { return $this->streetNumber; } - public function getStreetNumber(): ?string + public function getStreetNumber(): string { return $this->streetNumber; } @@ -378,7 +402,7 @@ class Address /** * @return DateTime */ - public function getValidFrom() + public function getValidFrom(): DateTime { return $this->validFrom; } @@ -407,7 +431,7 @@ class Address public function setBuildingName(?string $buildingName): self { - $this->buildingName = $buildingName; + $this->buildingName = (string) $buildingName; return $this; } @@ -421,47 +445,35 @@ class Address public function setCorridor(?string $corridor): self { - $this->corridor = $corridor; - - return $this; - } - - /** - * Store custom informations in the address. - * - * @return $this - */ - public function setCustoms(array $customs): self - { - $this->customs = $customs; + $this->corridor = (string) $corridor; return $this; } public function setDistribution(?string $distribution): self { - $this->distribution = $distribution; + $this->distribution = (string) $distribution; return $this; } public function setExtra(?string $extra): self { - $this->extra = $extra; + $this->extra = (string) $extra; return $this; } public function setFlat(?string $flat): self { - $this->flat = $flat; + $this->flat = (string) $flat; return $this; } public function setFloor(?string $floor): self { - $this->floor = $floor; + $this->floor = (string) $floor; return $this; } @@ -508,19 +520,44 @@ class Address return $this; } + /** + * Update the ref status + * + * <<<<<<< HEAD + * @param Address::ADDR_REFERENCE_STATUS_* $refStatus + * @param bool|null $updateLastUpdate Also update the "refStatusLastUpdate" + * ======= + * The refstatuslast update is also updated + * >>>>>>> 31152616d (Feature: Provide api endpoint for reviewing addresses) + */ + public function setRefStatus(string $refStatus, ?bool $updateLastUpdate = true): self + { + $this->refStatus = $refStatus; + + if ($updateLastUpdate) { + $this->setRefStatusLastUpdate(new \DateTimeImmutable('now')); + } + + return $this; + } + + public function setRefStatusLastUpdate(\DateTimeImmutable $refStatusLastUpdate): self + { + $this->refStatusLastUpdate = $refStatusLastUpdate; + + return $this; + } + public function setSteps(?string $steps): self { - $this->steps = $steps; + $this->steps = (string) $steps; return $this; } public function setStreet(?string $street): self { - if (null === $street) { - $street = ''; - } - $this->street = $street; + $this->street = (string) $street; return $this; } @@ -531,10 +568,11 @@ class Address * @param string $streetAddress1 * * @return Address + * @deprecated */ - public function setStreetAddress1($streetAddress1) + public function setStreetAddress1(?string $streetAddress1): self { - $this->street = null === $streetAddress1 ? '' : $streetAddress1; + $this->street = (string) $streetAddress1; return $this; } @@ -543,22 +581,19 @@ class Address * Set streetAddress2 (legacy function). * * @param string $streetAddress2 - * + * @deprecated * @return Address */ - public function setStreetAddress2($streetAddress2) + public function setStreetAddress2(?string $streetAddress2): self { - $this->streetNumber = null === $streetAddress2 ? '' : $streetAddress2; + $this->streetNumber = (string) $streetAddress2; return $this; } public function setStreetNumber(?string $streetNumber): self { - if (null === $streetNumber) { - $streetNumber = ''; - } - $this->streetNumber = $streetNumber; + $this->streetNumber = (string) $streetNumber; return $this; } @@ -605,7 +640,7 @@ class Address return; } - if (empty($this->getStreetAddress1())) { + if ('' === $this->getStreet()) { $context ->buildViolation('address.street1-should-be-set') ->atPath('streetAddress1') diff --git a/src/Bundle/ChillMainBundle/Entity/AddressReference.php b/src/Bundle/ChillMainBundle/Entity/AddressReference.php index 68cc32186..e75402c5f 100644 --- a/src/Bundle/ChillMainBundle/Entity/AddressReference.php +++ b/src/Bundle/ChillMainBundle/Entity/AddressReference.php @@ -55,13 +55,13 @@ class AddressReference * @ORM\Column(type="integer") * @groups({"read"}) */ - private $id; + private ?int $id = null; /** - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @groups({"read"}) */ - private $municipalityCode; + private string $municipalityCode = ''; /** * A geospatial field storing the coordinates of the Address. @@ -71,7 +71,7 @@ class AddressReference * @ORM\Column(type="point") * @groups({"read"}) */ - private $point; + private ?Point $point = null; /** * @var PostalCode @@ -79,31 +79,31 @@ class AddressReference * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode") * @groups({"read"}) */ - private $postcode; + private ?PostalCode $postcode = null; /** - * @ORM\Column(type="string", length=255) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @groups({"read"}) */ - private $refId; + private string $refId = ''; /** - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @groups({"read"}) */ - private $source; + private string $source = ''; /** - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @groups({"read"}) */ - private $street; + private string $street = ''; /** - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="text", nullable=false, options={"default": ""}) * @groups({"read"}) */ - private $streetNumber; + private string $streetNumber = ''; /** * @ORM\Column(type="datetime_immutable", nullable=true) @@ -126,7 +126,7 @@ class AddressReference return $this->id; } - public function getMunicipalityCode(): ?string + public function getMunicipalityCode(): string { return $this->municipalityCode; } @@ -141,27 +141,27 @@ class AddressReference * * @return PostalCode */ - public function getPostcode() + public function getPostcode(): ?PostalCode { return $this->postcode; } - public function getRefId(): ?string + public function getRefId(): string { return $this->refId; } - public function getSource(): ?string + public function getSource(): string { return $this->source; } - public function getStreet(): ?string + public function getStreet(): string { return $this->street; } - public function getStreetNumber(): ?string + public function getStreetNumber(): string { return $this->streetNumber; } @@ -192,7 +192,7 @@ class AddressReference public function setMunicipalityCode(?string $municipalityCode): self { - $this->municipalityCode = $municipalityCode; + $this->municipalityCode = (string) $municipalityCode; return $this; } @@ -227,21 +227,21 @@ class AddressReference public function setSource(?string $source): self { - $this->source = $source; + $this->source = (string) $source; return $this; } public function setStreet(?string $street): self { - $this->street = $street; + $this->street = (string) $street; return $this; } public function setStreetNumber(?string $streetNumber): self { - $this->streetNumber = $streetNumber; + $this->streetNumber = (string) $streetNumber; return $this; } diff --git a/src/Bundle/ChillMainBundle/Entity/Country.php b/src/Bundle/ChillMainBundle/Entity/Country.php index 23abf437a..0c8509233 100644 --- a/src/Bundle/ChillMainBundle/Entity/Country.php +++ b/src/Bundle/ChillMainBundle/Entity/Country.php @@ -43,36 +43,20 @@ class Country private ?int $id = null; /** - * @var string + * @var array * * @ORM\Column(type="json") * @groups({"read", "docgen:read"}) * @Context({"is-translatable": true}, groups={"docgen:read"}) */ - private $name; + private array $name = []; - /** - * @return string - */ - public function __toString() - { - return $this->getName(); - } - - /** - * @return the string - */ - public function getCountryCode() + public function getCountryCode(): string { return $this->countryCode; } - /** - * Get id. - * - * @return int - */ - public function getId() + public function getId(): ?int { return $this->id; } @@ -80,31 +64,23 @@ class Country /** * Get name. * - * @return string */ - public function getName() + public function getName(): array { return $this->name; } - /** - * @param string $countryCode - */ - public function setCountryCode($countryCode) + public function setCountryCode(?string $countryCode): self { - $this->countryCode = $countryCode; + $this->countryCode = (string) $countryCode; return $this; } /** - * Set name. - * - * @param string $name - * - * @return Country + * @param array $name */ - public function setName($name) + public function setName(array $name): self { $this->name = $name; diff --git a/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php b/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php new file mode 100644 index 000000000..0cacffac9 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/CronJobExecution.php @@ -0,0 +1,95 @@ +key = $key; + $this->lastStart = new DateTimeImmutable('now'); + } + + public function getKey(): string + { + return $this->key; + } + + public function getLastEnd(): DateTimeImmutable + { + return $this->lastEnd; + } + + public function getLastStart(): DateTimeImmutable + { + return $this->lastStart; + } + + public function getLastStatus(): ?int + { + return $this->lastStatus; + } + + public function setLastEnd(?DateTimeImmutable $lastEnd): CronJobExecution + { + $this->lastEnd = $lastEnd; + + return $this; + } + + public function setLastStart(DateTimeImmutable $lastStart): CronJobExecution + { + $this->lastStart = $lastStart; + + return $this; + } + + public function setLastStatus(?int $lastStatus): CronJobExecution + { + $this->lastStatus = $lastStatus; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php index 9fc437bd0..f404d5931 100644 --- a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php @@ -51,10 +51,7 @@ class CommentEmbeddable return $this->date; } - /** - * @return interger $userId - */ - public function getUserId() + public function getUserId(): ?int { return $this->userId; } diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php index 560b0dd7f..44e53671d 100644 --- a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php +++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php @@ -45,7 +45,7 @@ class PrivateCommentEmbeddable public function merge(PrivateCommentEmbeddable $newComment): self { - $currentComments = null === $this->getComments() ? [] : $this->getComments(); + $currentComments = $this->getComments() ?? []; $mergedComments = $newComment->getComments() + $currentComments; diff --git a/src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php index 37735bbc2..ea017f053 100644 --- a/src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php +++ b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php @@ -36,7 +36,7 @@ class GeographicalUnit /** * @ORM\ManyToOne(targetEntity=GeographicalUnitLayer::class, inversedBy="units") */ - private ?GeographicalUnitLayer $layer; + private ?GeographicalUnitLayer $layer = null; /** * @ORM\Column(type="text", nullable=false, options={"default": ""}) diff --git a/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php index 34f16a0fb..7add53066 100644 --- a/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php +++ b/src/Bundle/ChillMainBundle/Entity/GeographicalUnit/SimpleGeographicalUnitDTO.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace Chill\MainBundle\Entity\GeographicalUnit; +use Symfony\Component\Serializer\Annotation as Serializer; + /** * Simple GeographialUnit Data Transfer Object. * @@ -21,24 +23,28 @@ class SimpleGeographicalUnitDTO /** * @readonly * @psalm-readonly + * @Serializer\Groups({"read"}) */ public int $id; /** * @readonly * @psalm-readonly + * @Serializer\Groups({"read"}) */ public int $layerId; /** * @readonly * @psalm-readonly + * @Serializer\Groups({"read"}) */ public string $unitName; /** * @readonly * @psalm-readonly + * @Serializer\Groups({"read"}) */ public string $unitRefId; diff --git a/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php b/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php index bdea40563..b856c7a21 100644 --- a/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php +++ b/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php @@ -14,6 +14,7 @@ namespace Chill\MainBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Annotation as Serializer; /** * @ORM\Table(name="chill_main_geographical_unit_layer", uniqueConstraints={ @@ -27,16 +28,19 @@ class GeographicalUnitLayer * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") + * @Serializer\Groups({"read"}) */ private ?int $id = null; /** * @ORM\Column(type="json", nullable=false, options={"default": "[]"}) + * @Serializer\Groups({"read"}) */ private array $name = []; /** * @ORM\Column(type="text", nullable=false, options={"default": ""}) + * @Serializer\Groups({"read"}) */ private string $refId = ''; diff --git a/src/Bundle/ChillMainBundle/Entity/GroupCenter.php b/src/Bundle/ChillMainBundle/Entity/GroupCenter.php index c2e62d012..01b450394 100644 --- a/src/Bundle/ChillMainBundle/Entity/GroupCenter.php +++ b/src/Bundle/ChillMainBundle/Entity/GroupCenter.php @@ -31,7 +31,7 @@ class GroupCenter * ) * @ORM\Cache(usage="NONSTRICT_READ_WRITE") */ - private $center; + private ?Center $center = null; /** * @var int @@ -40,83 +40,64 @@ class GroupCenter * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** - * @var PermissionsGroup - * * @ORM\ManyToOne( * targetEntity="Chill\MainBundle\Entity\PermissionsGroup", * inversedBy="groupCenters") * @ORM\Cache(usage="NONSTRICT_READ_WRITE") */ - private $permissionsGroup; + private ?PermissionsGroup $permissionsGroup = null; /** - * @var Collection - * * @ORM\ManyToMany( * targetEntity="Chill\MainBundle\Entity\User", * mappedBy="groupCenters" * ) + * @var Collection */ - private $users; + private Collection $users; /** * GroupCenter constructor. */ public function __construct() { - $this->permissionsGroup = new ArrayCollection(); $this->users = new ArrayCollection(); } - /** - * @return Center - */ - public function getCenter() + public function getCenter(): ?Center { return $this->center; } - /** - * @return int - */ - public function getId() + public function getId(): ?int { return $this->id; } - /** - * @return PermissionGroup - */ - public function getPermissionsGroup() + public function getPermissionsGroup(): ?PermissionsGroup { return $this->permissionsGroup; } /** - * @return ArrayCollection|Collection + * @return Collection */ - public function getUsers() + public function getUsers(): Collection { return $this->users; } - /** - * @return \Chill\MainBundle\Entity\GroupCenter - */ - public function setCenter(Center $center) + public function setCenter(Center $center): self { $this->center = $center; return $this; } - /** - * @return \Chill\MainBundle\Entity\GroupCenter - */ - public function setPermissionsGroup(PermissionsGroup $permissionsGroup) + public function setPermissionsGroup(PermissionsGroup $permissionsGroup): self { $this->permissionsGroup = $permissionsGroup; diff --git a/src/Bundle/ChillMainBundle/Entity/Notification.php b/src/Bundle/ChillMainBundle/Entity/Notification.php index b8586b2e6..dc81b1b54 100644 --- a/src/Bundle/ChillMainBundle/Entity/Notification.php +++ b/src/Bundle/ChillMainBundle/Entity/Notification.php @@ -120,12 +120,12 @@ class Notification implements TrackUpdateInterface /** * @ORM\Column(type="datetime_immutable") */ - private ?DateTimeImmutable $updatedAt; + private ?DateTimeImmutable $updatedAt = null; /** * @ORM\ManyToOne(targetEntity=User::class) */ - private ?User $updatedBy; + private ?User $updatedBy = null; public function __construct() { diff --git a/src/Bundle/ChillMainBundle/Entity/NotificationComment.php b/src/Bundle/ChillMainBundle/Entity/NotificationComment.php index e83271296..daf2b541f 100644 --- a/src/Bundle/ChillMainBundle/Entity/NotificationComment.php +++ b/src/Bundle/ChillMainBundle/Entity/NotificationComment.php @@ -17,6 +17,7 @@ use DateTimeImmutable; use DateTimeInterface; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; +use Doctrine\ORM\Event\PrePersistEventArgs; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; @@ -133,7 +134,7 @@ class NotificationComment implements TrackCreationInterface, TrackUpdateInterfac /** * @ORM\PrePersist */ - public function onPrePersist(LifecycleEventArgs $eventArgs): void + public function onPrePersist(PrePersistEventArgs $eventArgs): void { $this->recentlyPersisted = true; } diff --git a/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php b/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php index fa505e550..6c0d0be5b 100644 --- a/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php +++ b/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php @@ -121,9 +121,7 @@ class PermissionsGroup public function isRoleScopePresentOnce(ExecutionContextInterface $context) { $roleScopesId = array_map( - static function (RoleScope $roleScope) { - return $roleScope->getId(); - }, + static fn (RoleScope $roleScope) => $roleScope->getId(), $this->getRoleScopes()->toArray() ); $countedIds = array_count_values($roleScopesId); diff --git a/src/Bundle/ChillMainBundle/Entity/Regroupment.php b/src/Bundle/ChillMainBundle/Entity/Regroupment.php new file mode 100644 index 000000000..96953abf5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/Regroupment.php @@ -0,0 +1,95 @@ +centers = new ArrayCollection(); + } + + public function getCenters(): Collection + { + return $this->centers; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getIsActive(): bool + { + return $this->isActive; + } + + public function getName(): string + { + return $this->name; + } + + public function setCenters(?Collection $centers): self + { + $this->centers = $centers; + + return $this; + } + + public function setIsActive(bool $isActive): self + { + $this->isActive = $isActive; + + return $this; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index 80a0b5b2a..a8ef88fbe 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -11,14 +11,15 @@ declare(strict_types=1); namespace Chill\MainBundle\Entity; +use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use RuntimeException; -use Symfony\Component\Security\Core\User\AdvancedUserInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation as Serializer; -use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Context\ExecutionContextInterface; use function in_array; /** @@ -31,7 +32,7 @@ use function in_array; * "user": User::class * }) */ -class User implements AdvancedUserInterface +class User implements UserInterface { /** * @ORM\Id @@ -40,6 +41,11 @@ class User implements AdvancedUserInterface */ protected ?int $id = null; + /** + * @ORM\Column(type="datetime_immutable", nullable=true) + */ + private ?DateTimeImmutable $absenceStart = null; + /** * Array where SAML attributes's data are stored. * @@ -58,8 +64,6 @@ class User implements AdvancedUserInterface private ?Location $currentLocation = null; /** - * @var string - * * @ORM\Column(type="string", length=150, nullable=true) */ private ?string $email = null; @@ -175,6 +179,11 @@ class User implements AdvancedUserInterface { } + public function getAbsenceStart(): ?DateTimeImmutable + { + return $this->absenceStart; + } + /** * Get attributes. * @@ -216,7 +225,7 @@ class User implements AdvancedUserInterface } /** - * @return GroupCenter + * @return Collection */ public function getGroupCenters() { @@ -225,10 +234,8 @@ class User implements AdvancedUserInterface /** * Get id. - * - * @return int */ - public function getId() + public function getId(): ?int { return $this->id; } @@ -295,6 +302,11 @@ class User implements AdvancedUserInterface return $this->usernameCanonical; } + public function isAbsent(): bool + { + return null !== $this->getAbsenceStart() && $this->getAbsenceStart() <= new DateTimeImmutable('now'); + } + /** * @return bool */ @@ -359,6 +371,11 @@ class User implements AdvancedUserInterface } } + public function setAbsenceStart(?DateTimeImmutable $absenceStart): void + { + $this->absenceStart = $absenceStart; + } + public function setAttributeByDomain(string $domain, string $key, $value): self { $this->attributes[$domain][$key] = $value; @@ -487,7 +504,7 @@ class User implements AdvancedUserInterface * * @param string $name * - * @return Agent + * @return User */ public function setUsername($name) { diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php index c448ea19e..d0f558cd5 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Doctrine\Model\TrackCreationTrait; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Validator\Constraints\Entity\WorkflowStepUsersOnTransition; use Chill\MainBundle\Workflow\Validator\EntityWorkflowCreation; use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection; @@ -24,6 +25,7 @@ use Doctrine\ORM\Mapping as ORM; use Iterator; use RuntimeException; use Symfony\Component\Serializer\Annotation as Serializer; +use Symfony\Component\Validator\Constraints as Assert; use function count; use function is_array; @@ -41,6 +43,13 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface use TrackUpdateTrait; + /** + * a list of future cc users for the next steps. + * + * @var array|User[] + */ + public array $futureCcUsers = []; + /** * a list of future dest emails for the next steps. * @@ -90,7 +99,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\OneToMany(targetEntity=EntityWorkflowStep::class, mappedBy="entityWorkflow", orphanRemoval=true, cascade={"persist"}) * @ORM\OrderBy({"transitionAt": "ASC", "id": "ASC"}) - * + * @Assert\Valid(traverse=true) * @var Collection|EntityWorkflowStep[] */ private Collection $steps; @@ -348,6 +357,23 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface return $this->transitionningStep; } + /** + * @return User[] + */ + public function getUsersInvolved(): array + { + $usersInvolved = []; + $usersInvolved[spl_object_hash($this->getCreatedBy())] = $this->getCreatedBy(); + + foreach ($this->steps as $step) { + foreach ($step->getDestUser() as $u) { + $usersInvolved[spl_object_hash($u)] = $u; + } + } + + return $usersInvolved; + } + public function getWorkflowName(): string { return $this->workflowName; diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php index d86770560..1f3070eb2 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php @@ -32,6 +32,12 @@ class EntityWorkflowStep */ private string $accessKey; + /** + * @ORM\ManyToMany(targetEntity=User::class) + * @ORM\JoinTable(name="chill_main_workflow_entity_step_cc_user") + */ + private Collection $ccUser; + /** * @ORM\Column(type="text", options={"default": ""}) */ @@ -114,11 +120,21 @@ class EntityWorkflowStep public function __construct() { + $this->ccUser = new ArrayCollection(); $this->destUser = new ArrayCollection(); $this->destUserByAccessKey = new ArrayCollection(); $this->accessKey = bin2hex(openssl_random_pseudo_bytes(32)); } + public function addCcUser(User $user): self + { + if (!$this->ccUser->contains($user)) { + $this->ccUser[] = $user; + } + + return $this; + } + public function addDestEmail(string $email): self { if (!in_array($email, $this->destEmail, true)) { @@ -132,8 +148,6 @@ class EntityWorkflowStep { if (!$this->destUser->contains($user)) { $this->destUser[] = $user; - $this->getEntityWorkflow() - ->addSubscriberToFinal($user); } return $this; @@ -143,8 +157,6 @@ class EntityWorkflowStep { if (!$this->destUserByAccessKey->contains($user) && !$this->destUser->contains($user)) { $this->destUserByAccessKey[] = $user; - $this->getEntityWorkflow() - ->addSubscriberToFinal($user); } return $this; @@ -171,6 +183,11 @@ class EntityWorkflowStep ); } + public function getCcUser(): Collection + { + return $this->ccUser; + } + public function getComment(): string { return $this->comment; @@ -265,11 +282,16 @@ class EntityWorkflowStep return true; } + public function removeCcUser(User $user): self + { + $this->ccUser->removeElement($user); + + return $this; + } + public function removeDestEmail(string $email): self { - $this->destEmail = array_filter($this->destEmail, static function (string $existing) use ($email) { - return $email !== $existing; - }); + $this->destEmail = array_filter($this->destEmail, static fn (string $existing) => $email !== $existing); return $this; } diff --git a/src/Bundle/ChillMainBundle/Export/ExportInterface.php b/src/Bundle/ChillMainBundle/Export/ExportInterface.php index be43ad47a..d4e456ca6 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportInterface.php +++ b/src/Bundle/ChillMainBundle/Export/ExportInterface.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Export; -use Closure; +use Doctrine\ORM\NativeQuery; use Doctrine\ORM\QueryBuilder; /** @@ -24,6 +24,7 @@ use Doctrine\ORM\QueryBuilder; * aggregation, use `ListInterface`. * * @example Chill\PersonBundle\Export\CountPerson an example of implementation + * @template Q of QueryBuilder|NativeQuery */ interface ExportInterface extends ExportElementInterface { @@ -83,9 +84,9 @@ interface ExportInterface extends ExportElementInterface * * @param string $key The column key, as added in the query * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR') - * @param mixed $data The data from the export's form (as defined in `buildForm` + * @param mixed $data The data from the export's form (as defined in `buildForm`) * - * @return Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + * @return callable(null|string|int|float|'_header' $value): string|int|\DateTimeInterface where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` */ public function getLabels($key, array $values, $data); @@ -103,7 +104,7 @@ interface ExportInterface extends ExportElementInterface /** * Return the results of the query builder. * - * @param \Doctrine\ORM\NativeQuery|QueryBuilder $query + * @param Q $query * @param mixed[] $data the data from the export's fomr (added by self::buildForm) * * @return mixed[] an array of results @@ -133,7 +134,7 @@ interface ExportInterface extends ExportElementInterface * @param array $acl an array where each row has a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` keys containing the reachable circles. Example: `array( array('center' => $centerA, 'circles' => array($circleA, $circleB) ) )` * @param array $data the data from the form, if any * - * @return \Doctrine\ORM\NativeQuery|QueryBuilder the query to execute. + * @return Q the query to execute. */ public function initiateQuery(array $requiredModifiers, array $acl, array $data = []); diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php index 7dc6f120f..b84c80118 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php @@ -199,9 +199,7 @@ class CSVListFormatter implements FormatterInterface foreach ($keys as $key) { // get an array with all values for this key if possible - $values = array_map(static function ($v) use ($key) { - return $v[$key]; - }, $this->result); + $values = array_map(static fn ($v) => $v[$key], $this->result); // store the label in the labelsCache property $this->labelsCache[$key] = $export->getLabels($key, $values, $this->exportData); } diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php index b062a9c3c..63d691443 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php @@ -187,9 +187,7 @@ class CSVPivotedListFormatter implements FormatterInterface foreach ($keys as $key) { // get an array with all values for this key if possible - $values = array_map(static function ($v) use ($key) { - return $v[$key]; - }, $this->result); + $values = array_map(static fn ($v) => $v[$key], $this->result); // store the label in the labelsCache property $this->labelsCache[$key] = $export->getLabels($key, $values, $this->exportData); } diff --git a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php index 6b77e5b2b..dc09c55a1 100644 --- a/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php +++ b/src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php @@ -435,7 +435,7 @@ class SpreadSheetFormatter implements FormatterInterface * Get the displayable result. * * @param string $key - * @param string $value + * @param mixed $value * * @return string */ @@ -445,7 +445,7 @@ class SpreadSheetFormatter implements FormatterInterface $this->initializeCache($key); } - $value = null === $value ? '' : $value; + $value ??= ''; return call_user_func($this->cacheDisplayableResult[$key], $value); } diff --git a/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php new file mode 100644 index 000000000..3ee5f20d8 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Export/Helper/AggregateStringHelper.php @@ -0,0 +1,36 @@ +generateKeysForUnitsNames($prefix)), array_keys($this->generateKeysForUnitsRefs($prefix))); + $prefixes = [...$prefixes, ...array_keys($this->generateKeysForUnitsNames($prefix)), ...array_keys($this->generateKeysForUnitsRefs($prefix))]; continue; } @@ -257,9 +257,7 @@ class ExportAddressHelper $prefixes = array_merge( $prefixes, array_map( - static function ($item) use ($prefix) { - return $prefix . $item; - }, + static fn ($item) => $prefix . $item, self::COLUMN_MAPPING[$key] ) ); @@ -310,7 +308,7 @@ class ExportAddressHelper return ''; } - return $this->translatableStringHelper->localize(json_decode($value, true)); + return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); }; case 'isNoAddress': @@ -369,7 +367,7 @@ class ExportAddressHelper return ''; } - $decodedValues = json_decode($value, true); + $decodedValues = json_decode($value, true, 512, JSON_THROW_ON_ERROR); switch (count($decodedValues)) { case 0: diff --git a/src/Bundle/ChillMainBundle/Export/Helper/TranslatableStringExportLabelHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/TranslatableStringExportLabelHelper.php index 44ce2b194..9b49d476b 100644 --- a/src/Bundle/ChillMainBundle/Export/Helper/TranslatableStringExportLabelHelper.php +++ b/src/Bundle/ChillMainBundle/Export/Helper/TranslatableStringExportLabelHelper.php @@ -39,7 +39,7 @@ class TranslatableStringExportLabelHelper return ''; } - return $this->translatableStringHelper->localize(json_decode($value, true)); + return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); }; } @@ -54,7 +54,7 @@ class TranslatableStringExportLabelHelper return ''; } - $decoded = json_decode($value, true); + $decoded = json_decode($value, true, 512, JSON_THROW_ON_ERROR); return implode( '|', diff --git a/src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php b/src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php index d8eb7e9cc..2821bf1a6 100644 --- a/src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php +++ b/src/Bundle/ChillMainBundle/Export/Helper/UserHelper.php @@ -45,16 +45,16 @@ class UserHelper public function getLabelMulti($key, array $values, string $header): callable { - return function ($value) { + return function ($value) use ($header) { if ('_header' === $value) { - return 'users name'; + return $header; } if (null === $value) { return ''; } - $decoded = json_decode($value); + $decoded = json_decode($value, null, 512, JSON_THROW_ON_ERROR); if (0 === count($decoded)) { return ''; diff --git a/src/Bundle/ChillMainBundle/Form/AdvancedSearchType.php b/src/Bundle/ChillMainBundle/Form/AbsenceType.php similarity index 50% rename from src/Bundle/ChillMainBundle/Form/AdvancedSearchType.php rename to src/Bundle/ChillMainBundle/Form/AbsenceType.php index 9157e8023..d0aed640c 100644 --- a/src/Bundle/ChillMainBundle/Form/AdvancedSearchType.php +++ b/src/Bundle/ChillMainBundle/Form/AbsenceType.php @@ -11,34 +11,28 @@ declare(strict_types=1); namespace Chill\MainBundle\Form; -use Chill\MainBundle\Search\SearchProvider; +use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Form\Type\ChillDateType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -class AdvancedSearchType extends AbstractType +class AbsenceType extends AbstractType { - /** - * @var SearchProvider - */ - protected $searchProvider; - - public function __construct(SearchProvider $searchProvider) - { - $this->searchProvider = $searchProvider; - } - public function buildForm(FormBuilderInterface $builder, array $options) { - $this->searchProvider - ->getHasAdvancedFormByName($options['search_service']) - ->createSearchForm($builder); + $builder + ->add('absenceStart', ChillDateType::class, [ + 'required' => true, + 'input' => 'datetime_immutable', + 'label' => 'absence.Absence start', + ]); } public function configureOptions(OptionsResolver $resolver) { - $resolver - ->setRequired('search_service') - ->setAllowedTypes('search_service', ['string']); + $resolver->setDefaults([ + 'data_class' => User::class, + ]); } } diff --git a/src/Bundle/ChillMainBundle/Form/CenterType.php b/src/Bundle/ChillMainBundle/Form/CenterType.php index 6af579870..ff758ca49 100644 --- a/src/Bundle/ChillMainBundle/Form/CenterType.php +++ b/src/Bundle/ChillMainBundle/Form/CenterType.php @@ -30,7 +30,7 @@ class CenterType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\MainBundle\Entity\Center', + 'data_class' => \Chill\MainBundle\Entity\Center::class, ]); } diff --git a/src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php b/src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php index bb9b180f5..174fb3304 100644 --- a/src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php +++ b/src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php @@ -48,9 +48,7 @@ class PostalCodeChoiceLoader implements ChoiceLoaderInterface { return new \Symfony\Component\Form\ChoiceList\ArrayChoiceList( $this->lazyLoadedPostalCodes, - static function (?PostalCode $pc = null) use ($value) { - return call_user_func($value, $pc); - } + static fn (?PostalCode $pc = null) => call_user_func($value, $pc) ); } diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php index 8961627d4..ca9c8452e 100644 --- a/src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/AddressDataMapper.php @@ -43,11 +43,13 @@ class AddressDataMapper implements DataMapperInterface /** @var FormInterface $form */ switch ($key) { case 'streetAddress1': + /** @phpstan-ignore-next-line */ $form->setData($address->getStreetAddress1()); break; case 'streetAddress2': + /** @phpstan-ignore-next-line */ $form->setData($address->getStreetAddress2()); break; @@ -110,11 +112,13 @@ class AddressDataMapper implements DataMapperInterface return; } + /** @phpstan-ignore-next-line */ $address->setStreetAddress1($form->getData()); break; case 'streetAddress2': + /** @phpstan-ignore-next-line */ $address->setStreetAddress2($form->getData()); break; diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php new file mode 100644 index 000000000..01303bfbb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php @@ -0,0 +1,73 @@ + $form */ + $form = iterator_to_array($forms); + + $pickedRegroupment = []; + + foreach ($this->regroupmentRepository->findAll() as $regroupment) { + /** @phpstan-ignore-next-line */ + [$contained, $notContained] = $regroupment->getCenters()->partition(static fn (Center $center): bool => false); + + if (0 === count($notContained)) { + $pickedRegroupment[] = $regroupment; + } + } + + $form['regroupment']->setData($pickedRegroupment); + $form['centers']->setData($data); + } + + public function mapFormsToData($forms, &$data): void + { + /** @var array $forms */ + $forms = iterator_to_array($forms); + + $centers = []; + + foreach ($forms['center']->getData() as $center) { + $centers[spl_object_hash($center)] = $center; + } + + if (array_key_exists('regroupment', $forms)) { + /** @var Regroupment $regroupment */ + foreach ($forms['regroupment']->getData() as $regroupment) { + foreach ($regroupment->getCenters() as $center) { + $centers[spl_object_hash($center)] = $center; + } + } + } + + $data = array_values($centers); + } +} diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/RollingDateDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/RollingDateDataMapper.php index 21d0c3fde..909b671b8 100644 --- a/src/Bundle/ChillMainBundle/Form/DataMapper/RollingDateDataMapper.php +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/RollingDateDataMapper.php @@ -38,7 +38,7 @@ class RollingDateDataMapper implements DataMapperInterface $forms = iterator_to_array($forms); $viewData = new RollingDate( - $forms['roll']->getData(), + ($forms['roll']->getData() ?? RollingDate::T_TODAY), $forms['fixedDate']->getData() ); } diff --git a/src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php b/src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php index 5cc50f185..6aa5eee40 100644 --- a/src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/DataTransformer/IdToEntityDataTransformer.php @@ -42,7 +42,7 @@ class IdToEntityDataTransformer implements DataTransformerInterface { $this->repository = $repository; $this->multiple = $multiple; - $this->getId = $getId ?? static function (object $o) { return $o->getId(); }; + $this->getId = $getId ?? static fn (object $o) => $o->getId(); } /** diff --git a/src/Bundle/ChillMainBundle/Form/LocationFormType.php b/src/Bundle/ChillMainBundle/Form/LocationFormType.php index 8e6861029..ff2c563d3 100644 --- a/src/Bundle/ChillMainBundle/Form/LocationFormType.php +++ b/src/Bundle/ChillMainBundle/Form/LocationFormType.php @@ -36,15 +36,11 @@ final class LocationFormType extends AbstractType $builder ->add('locationType', EntityType::class, [ 'class' => EntityLocationType::class, - 'choice_attr' => static function (EntityLocationType $entity) { - return [ - 'data-address' => $entity->getAddressRequired(), - 'data-contact' => $entity->getContactData(), - ]; - }, - 'choice_label' => function (EntityLocationType $entity) { - return $this->translatableStringHelper->localize($entity->getTitle()); - }, + 'choice_attr' => static fn (EntityLocationType $entity) => [ + 'data-address' => $entity->getAddressRequired(), + 'data-contact' => $entity->getContactData(), + ], + 'choice_label' => fn (EntityLocationType $entity) => $this->translatableStringHelper->localize($entity->getTitle()), ]) ->add('name', TextType::class) ->add('phonenumber1', ChillPhoneNumberType::class, ['required' => false]) @@ -75,7 +71,7 @@ final class LocationFormType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\MainBundle\Entity\Location', + 'data_class' => \Chill\MainBundle\Entity\Location::class, ]); } diff --git a/src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php b/src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php index ad5f7243b..16aafeb41 100644 --- a/src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php +++ b/src/Bundle/ChillMainBundle/Form/PermissionsGroupType.php @@ -60,7 +60,7 @@ class PermissionsGroupType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\MainBundle\Entity\PermissionsGroup', + 'data_class' => \Chill\MainBundle\Entity\PermissionsGroup::class, ]); } diff --git a/src/Bundle/ChillMainBundle/Form/RegroupmentType.php b/src/Bundle/ChillMainBundle/Form/RegroupmentType.php new file mode 100644 index 000000000..bc8e6684f --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/RegroupmentType.php @@ -0,0 +1,47 @@ +add('name', TextType::class, [ + 'label' => 'Nom', + ]) + ->add('centers', EntityType::class, [ + 'class' => Center::class, + 'multiple' => true, + 'attr' => ['class' => 'select2'], + ]) + ->add('isActive', CheckboxType::class, [ + 'label' => 'Actif ?', + 'required' => false, + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefault('class', Regroupment::class); + } +} diff --git a/src/Bundle/ChillMainBundle/Form/ScopeType.php b/src/Bundle/ChillMainBundle/Form/ScopeType.php index 691328500..c5a7657b0 100644 --- a/src/Bundle/ChillMainBundle/Form/ScopeType.php +++ b/src/Bundle/ChillMainBundle/Form/ScopeType.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Form; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -21,7 +22,12 @@ class ScopeType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('name', TranslatableStringFormType::class); + ->add('name', TranslatableStringFormType::class) + ->add('active', ChoiceType::class, [ + 'choices' => [ + 'Active' => true, + 'Inactive' => false, + ], ]); } /** @@ -30,7 +36,7 @@ class ScopeType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\MainBundle\Entity\Scope', + 'data_class' => \Chill\MainBundle\Entity\Scope::class, ]); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/AppendScopeChoiceTypeTrait.php b/src/Bundle/ChillMainBundle/Form/Type/AppendScopeChoiceTypeTrait.php index 547aeb3ec..8eda0d9d9 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/AppendScopeChoiceTypeTrait.php +++ b/src/Bundle/ChillMainBundle/Form/Type/AppendScopeChoiceTypeTrait.php @@ -83,8 +83,8 @@ trait AppendScopeChoiceTypeTrait { $resolver ->setRequired(['center', 'role']) - ->setAllowedTypes('center', 'Chill\MainBundle\Entity\Center') - ->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role'); + ->setAllowedTypes('center', \Chill\MainBundle\Entity\Center::class) + ->setAllowedTypes('role', 'string'); } /** diff --git a/src/Bundle/ChillMainBundle/Form/Type/ChillDateTimeType.php b/src/Bundle/ChillMainBundle/Form/Type/ChillDateTimeType.php index 639848d9a..0063ee7d9 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/ChillDateTimeType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/ChillDateTimeType.php @@ -27,7 +27,6 @@ class ChillDateTimeType extends AbstractType { $resolver ->setDefault('date_widget', 'single_text') - ->setDefault('date_format', 'dd-MM-yyyy') ->setDefault('time_widget', 'choice') ->setDefault('minutes', range(0, 59, 5)) ->setDefault('hours', range(8, 22)) diff --git a/src/Bundle/ChillMainBundle/Form/Type/CommentType.php b/src/Bundle/ChillMainBundle/Form/Type/CommentType.php index 9b8fc4701..542a429c6 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/CommentType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/CommentType.php @@ -56,12 +56,7 @@ class CommentType extends AbstractType public function buildView(FormView $view, FormInterface $form, array $options) { - $view->vars = array_replace( - $view->vars, - [ - 'fullWidth' => true, - ] - ); + $view->vars['fullWidth'] = true; } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillMainBundle/Form/Type/ComposedGroupCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/ComposedGroupCenterType.php index d78cf813b..48bd37dcc 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/ComposedGroupCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/ComposedGroupCenterType.php @@ -23,21 +23,17 @@ class ComposedGroupCenterType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('permissionsgroup', EntityType::class, [ - 'class' => 'Chill\MainBundle\Entity\PermissionsGroup', - 'choice_label' => static function (PermissionsGroup $group) { - return $group->getName(); - }, + 'class' => \Chill\MainBundle\Entity\PermissionsGroup::class, + 'choice_label' => static fn (PermissionsGroup $group) => $group->getName(), ])->add('center', EntityType::class, [ - 'class' => 'Chill\MainBundle\Entity\Center', - 'choice_label' => static function (Center $center) { - return $center->getName(); - }, + 'class' => \Chill\MainBundle\Entity\Center::class, + 'choice_label' => static fn (Center $center) => $center->getName(), ]); } public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefault('data_class', 'Chill\MainBundle\Entity\GroupCenter'); + $resolver->setDefault('data_class', \Chill\MainBundle\Entity\GroupCenter::class); } public function getBlockPrefix() diff --git a/src/Bundle/ChillMainBundle/Form/Type/ComposedRoleScopeType.php b/src/Bundle/ChillMainBundle/Form/Type/ComposedRoleScopeType.php index 1d541cbd7..38f1475d5 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/ComposedRoleScopeType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/ComposedRoleScopeType.php @@ -82,15 +82,12 @@ class ComposedRoleScopeType extends AbstractType return ['data-has-scope' => '1']; }, - 'group_by' => function ($role, $key, $index) { - return $this->roleProvider->getRoleTitle($role); - }, + 'group_by' => fn ($role, $key, $index) => $this->roleProvider->getRoleTitle($role), ]) ->add('scope', EntityType::class, [ 'class' => Scope::class, - 'choice_label' => static function (Scope $scope) use ($translatableStringHelper) { - return $translatableStringHelper->localize($scope->getName()); - }, + 'choice_label' => static fn (Scope $scope) => $translatableStringHelper->localize($scope->getName()), + 'placeholder' => 'Choose amongst scopes', 'required' => false, 'data' => null, ]); @@ -98,6 +95,6 @@ class ComposedRoleScopeType extends AbstractType public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefault('data_class', 'Chill\MainBundle\Entity\RoleScope'); + $resolver->setDefault('data_class', \Chill\MainBundle\Entity\RoleScope::class); } } diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php index 46fa8799f..529bd9789 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php @@ -43,7 +43,7 @@ class EntityToJsonTransformer implements DataTransformerInterface public function reverseTransform($value) { - $denormalized = json_decode($value, true); + $denormalized = json_decode($value, true, 512, JSON_THROW_ON_ERROR); if ($this->multiple) { if (null === $denormalized) { @@ -51,9 +51,7 @@ class EntityToJsonTransformer implements DataTransformerInterface } return array_map( - function ($item) { - return $this->denormalizeOne($item); - }, + fn ($item) => $this->denormalizeOne($item), $denormalized ); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php index aca165652..a21f49b2c 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php +++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php @@ -31,8 +31,6 @@ class MultipleObjectsToIdTransformer implements DataTransformerInterface * Transforms a string (id) to an object (item). * * @param mixed $array - * - * @return ArrayCollection */ public function reverseTransform($array) { @@ -53,10 +51,8 @@ class MultipleObjectsToIdTransformer implements DataTransformerInterface * Transforms an object (use) to a string (id). * * @param array $array - * - * @return ArrayCollection */ - public function transform($array) + public function transform($array): array { $ret = []; diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index 20db0b535..c89907cf3 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -11,57 +11,46 @@ declare(strict_types=1); namespace Chill\MainBundle\Form\Type\Export; -use Chill\MainBundle\Center\GroupingCenterInterface; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\Regroupment; use Chill\MainBundle\Export\ExportManager; +use Chill\MainBundle\Form\DataMapper\ExportPickCenterDataMapper; +use Chill\MainBundle\Repository\RegroupmentRepository; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\CallbackTransformer; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\User\UserInterface; -use function array_intersect; -use function array_key_exists; -use function array_merge; -use function array_unique; use function count; -use function in_array; /** * Pick centers amongst available centers for the user. */ -class PickCenterType extends AbstractType +final class PickCenterType extends AbstractType { public const CENTERS_IDENTIFIERS = 'c'; - protected AuthorizationHelperInterface $authorizationHelper; + private AuthorizationHelperInterface $authorizationHelper; - protected ExportManager $exportManager; + private ExportManager $exportManager; - /** - * @var array|GroupingCenterInterface[] - */ - protected array $groupingCenters = []; + private RegroupmentRepository $regroupmentRepository; - protected UserInterface $user; + private UserInterface $user; public function __construct( TokenStorageInterface $tokenStorage, ExportManager $exportManager, + RegroupmentRepository $regroupmentRepository, AuthorizationHelperInterface $authorizationHelper ) { $this->exportManager = $exportManager; $this->user = $tokenStorage->getToken()->getUser(); $this->authorizationHelper = $authorizationHelper; - } - - public function addGroupingCenter(GroupingCenterInterface $grouping) - { - $this->groupingCenters[md5($grouping->getName())] = $grouping; + $this->regroupmentRepository = $regroupmentRepository; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -72,97 +61,32 @@ class PickCenterType extends AbstractType $export->requiredRole() ); - $builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [ + $builder->add('center', EntityType::class, [ 'class' => Center::class, + 'label' => 'center', 'choices' => $centers, 'multiple' => true, 'expanded' => true, - 'choice_label' => static function (Center $c) { - return $c->getName(); - }, - 'data' => count($this->groupingCenters) > 0 ? null : $centers, + 'choice_label' => static fn (Center $c) => $c->getName(), + 'data' => $centers, ]); - if (count($this->groupingCenters) > 0) { - $groupingBuilder = $builder->create('g', null, [ - 'compound' => true, + if (count($this->regroupmentRepository->findAllActive()) > 0) { + $builder->add('regroupment', EntityType::class, [ + 'class' => Regroupment::class, + 'label' => 'regroupment', + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->regroupmentRepository->findAllActive(), + 'choice_label' => static fn (Regroupment $r) => $r->getName(), ]); - - foreach ($this->groupingCenters as $key => $gc) { - $choices = $this->buildChoices($centers, $gc); - - if (count($choices) > 0) { - $groupingBuilder->add($key, ChoiceType::class, [ - 'choices' => $choices, - 'multiple' => true, - 'expanded' => true, - 'label' => $gc->getName(), - 'required' => false, - ]); - } - } - - if ($groupingBuilder->count() > 0) { - $builder->add($groupingBuilder); - } } - $builder->addModelTransformer(new CallbackTransformer( - function ($data) use ($centers) { - return $this->transform($data, $centers); - }, - function ($data) use ($centers) { - return $this->reverseTransform($data, $centers); - } - )); + $builder->setDataMapper(new ExportPickCenterDataMapper()); } public function configureOptions(OptionsResolver $resolver) { $resolver->setRequired('export_alias'); } - - protected function buildChoices($reachablesCenters, GroupingCenterInterface $gc) - { - $result = []; - - foreach ($gc->getGroups() as $group) { - foreach ($gc->getCentersForGroup($group) as $center) { - if (in_array($center, $reachablesCenters, true)) { - $result[$group] = $group; - } - } - } - - return $result; - } - - protected function reverseTransform($data, $centers) - { - $picked = $data[self::CENTERS_IDENTIFIERS] - instanceof \Doctrine\Common\Collections\Collection ? - $data[self::CENTERS_IDENTIFIERS]->toArray() - : - $data[self::CENTERS_IDENTIFIERS]; - - if (array_key_exists('g', $data)) { - foreach ($data['g'] as $gcid => $group) { - $picked = - array_merge( - array_intersect( - $this->groupingCenters[$gcid]->getCentersForGroup($group), - $centers - ), - $picked - ); - } - } - - return array_unique($picked); - } - - protected function transform($data, $centers) - { - return $data; - } } diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/PickCenterType.php index 0f6dd44bc..83e957623 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickCenterType.php @@ -90,9 +90,7 @@ class PickCenterType extends AbstractType return ['center' => $data]; }, - static function ($data) { - return $data['center']; - } + static fn ($data) => $data['center'] )); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickCivilityType.php b/src/Bundle/ChillMainBundle/Form/Type/PickCivilityType.php index 84342dfc3..adb0f2a67 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickCivilityType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickCivilityType.php @@ -34,17 +34,13 @@ class PickCivilityType extends AbstractType ->setDefault('label', 'Civility') ->setDefault( 'choice_label', - function (Civility $civility): string { - return $this->translatableStringHelper->localize($civility->getName()); - } + fn (Civility $civility): string => $this->translatableStringHelper->localize($civility->getName()) ) ->setDefault( 'query_builder', - static function (EntityRepository $er): QueryBuilder { - return $er->createQueryBuilder('c') - ->where('c.active = true') - ->orderBy('c.order'); - }, + static fn (EntityRepository $er): QueryBuilder => $er->createQueryBuilder('c') + ->where('c.active = true') + ->orderBy('c.order'), ) ->setDefault('placeholder', 'choose civility') ->setDefault('class', Civility::class); diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickLocationTypeType.php b/src/Bundle/ChillMainBundle/Form/Type/PickLocationTypeType.php index 6774e0941..3d993c9f1 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickLocationTypeType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickLocationTypeType.php @@ -31,9 +31,7 @@ class PickLocationTypeType extends AbstractType $resolver ->setDefaults([ 'class' => LocationType::class, - 'choice_label' => function (LocationType $type) { - return $this->translatableStringHelper->localize($type->getTitle()); - }, + 'choice_label' => fn (LocationType $type) => $this->translatableStringHelper->localize($type->getTitle()), 'placeholder' => 'Pick a location type', 'required' => false, 'attr' => ['class' => 'select2'], diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php b/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php index 2fbfdcf11..f6c2b7f4a 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickUserDynamicType.php @@ -19,6 +19,7 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\SerializerInterface; /** @@ -28,12 +29,15 @@ class PickUserDynamicType extends AbstractType { private DenormalizerInterface $denormalizer; + private NormalizerInterface $normalizer; + private SerializerInterface $serializer; - public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer) + public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, NormalizerInterface $normalizer) { $this->denormalizer = $denormalizer; $this->serializer = $serializer; + $this->normalizer = $normalizer; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -46,6 +50,11 @@ class PickUserDynamicType extends AbstractType $view->vars['multiple'] = $options['multiple']; $view->vars['types'] = ['user']; $view->vars['uniqid'] = uniqid('pick_user_dyn'); + $view->vars['suggested'] = []; + + foreach ($options['suggested'] as $user) { + $view->vars['suggested'][] = $this->normalizer->normalize($user, 'json', ['groups' => 'read']); + } } public function configureOptions(OptionsResolver $resolver) @@ -53,7 +62,8 @@ class PickUserDynamicType extends AbstractType $resolver ->setDefault('multiple', false) ->setAllowedTypes('multiple', ['bool']) - ->setDefault('compound', false); + ->setDefault('compound', false) + ->setDefault('suggested', []); } public function getBlockPrefix() diff --git a/src/Bundle/ChillMainBundle/Form/Type/PickUserLocationType.php b/src/Bundle/ChillMainBundle/Form/Type/PickUserLocationType.php index 792daa39e..d78957f29 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PickUserLocationType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PickUserLocationType.php @@ -36,11 +36,9 @@ class PickUserLocationType extends AbstractType ->setDefaults([ 'class' => Location::class, 'choices' => $this->locationRepository->findByPublicLocations(), - 'choice_label' => function (Location $entity) { - return $entity->getName() ? - $entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' : - $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()); - }, + 'choice_label' => fn (Location $entity) => $entity->getName() ? + $entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' : + $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()), 'placeholder' => 'Pick a location', 'required' => false, 'attr' => ['class' => 'select2'], diff --git a/src/Bundle/ChillMainBundle/Form/Type/PostalCodeType.php b/src/Bundle/ChillMainBundle/Form/Type/PostalCodeType.php index 60fefddfa..51a321be6 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PostalCodeType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PostalCodeType.php @@ -77,10 +77,8 @@ class PostalCodeType extends AbstractType $helper = $this->translatableStringHelper; $resolver ->setDefault('class', PostalCode::class) - ->setDefault('choice_label', static function (PostalCode $code) use ($helper) { - return $code->getCode() . ' ' . $code->getName() . ' [' . - $helper->localize($code->getCountry()->getName()) . ']'; - }) + ->setDefault('choice_label', static fn (PostalCode $code) => $code->getCode() . ' ' . $code->getName() . ' [' . + $helper->localize($code->getCountry()->getName()) . ']') ->setDefault('choice_loader', $this->choiceLoader) ->setDefault('placeholder', 'Select a postal code'); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php b/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php index 2ab318d9c..5c29f4d42 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/PrivateCommentType.php @@ -39,7 +39,7 @@ class PrivateCommentType extends AbstractType $builder ->add('comments', ChillTextareaType::class, [ 'disable_editor' => $options['disable_editor'], - 'label' => false, + 'label' => $options['label'], ]) ->setDataMapper($this->dataMapper); } diff --git a/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php b/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php index f65677dc7..c86684a8a 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/ScopePickerType.php @@ -60,15 +60,15 @@ class ScopePickerType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { - $items = array_filter( - $this->authorizationHelper->getReachableScopes( - $this->security->getUser(), - $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'], - $options['center'] - ), - static function (Scope $s) { - return $s->isActive(); - } + $items = array_values( + array_filter( + $this->authorizationHelper->getReachableScopes( + $this->security->getUser(), + $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'], + $options['center'] + ), + static fn (Scope $s) => $s->isActive() + ) ); if (0 === count($items)) { @@ -79,9 +79,7 @@ class ScopePickerType extends AbstractType $builder->add('scope', EntityType::class, [ 'class' => Scope::class, 'placeholder' => 'Choose the circle', - 'choice_label' => function (Scope $c) { - return $this->translatableStringHelper->localize($c->getName()); - }, + 'choice_label' => fn (Scope $c) => $this->translatableStringHelper->localize($c->getName()), 'choices' => $items, ]); $builder->setDataMapper(new ScopePickerDataMapper()); @@ -95,12 +93,7 @@ class ScopePickerType extends AbstractType public function buildView(FormView $view, FormInterface $form, array $options) { - $view->vars = array_replace( - $view->vars, - [ - 'fullWidth' => true, - ] - ); + $view->vars['fullWidth'] = true; } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php b/src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php index 5b4d49edd..bc4d7d3ef 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Select2CountryType.php @@ -77,7 +77,7 @@ class Select2CountryType extends AbstractType asort($choices, SORT_STRING | SORT_FLAG_CASE); $resolver->setDefaults([ - 'class' => 'Chill\MainBundle\Entity\Country', + 'class' => \Chill\MainBundle\Entity\Country::class, 'choices' => array_combine(array_values($choices), array_keys($choices)), 'preferred_choices' => array_combine(array_values($preferredChoices), array_keys($preferredChoices)), ]); diff --git a/src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php b/src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php index 164a138d9..328f3c174 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Select2LanguageType.php @@ -73,7 +73,7 @@ class Select2LanguageType extends AbstractType asort($choices, SORT_STRING | SORT_FLAG_CASE); $resolver->setDefaults([ - 'class' => 'Chill\MainBundle\Entity\Language', + 'class' => \Chill\MainBundle\Entity\Language::class, 'choices' => array_combine(array_values($choices), array_keys($choices)), 'preferred_choices' => array_combine(array_values($preferredChoices), array_keys($preferredChoices)), ]); diff --git a/src/Bundle/ChillMainBundle/Form/Type/UserPickerType.php b/src/Bundle/ChillMainBundle/Form/Type/UserPickerType.php index 6b1bb357a..c430a1053 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/UserPickerType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/UserPickerType.php @@ -79,9 +79,7 @@ class UserPickerType extends AbstractType ->setAllowedTypes('having_permissions_group_flag', ['string', 'null']) ->setDefault('class', User::class) ->setDefault('placeholder', 'Choose an user') - ->setDefault('choice_label', function (User $u) { - return $this->userRender->renderString($u, []); - }) + ->setDefault('choice_label', fn (User $u) => $this->userRender->renderString($u, [])) ->setDefault('scope', null) ->setAllowedTypes('scope', [Scope::class, 'array', 'null']) ->setNormalizer('choices', function (Options $options) { diff --git a/src/Bundle/ChillMainBundle/Form/UserType.php b/src/Bundle/ChillMainBundle/Form/UserType.php index b738cc8c7..f8485aa99 100644 --- a/src/Bundle/ChillMainBundle/Form/UserType.php +++ b/src/Bundle/ChillMainBundle/Form/UserType.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\PickCivilityType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\EntityRepository; @@ -76,18 +77,14 @@ class UserType extends AbstractType 'required' => false, 'placeholder' => 'Choose a main scope', 'class' => Scope::class, - 'choice_label' => function (Scope $c) { - return $this->translatableStringHelper->localize($c->getName()); - }, + 'choice_label' => fn (Scope $c) => $this->translatableStringHelper->localize($c->getName()), ]) ->add('userJob', EntityType::class, [ 'label' => 'user job', 'required' => false, 'placeholder' => 'choose a job', 'class' => UserJob::class, - 'choice_label' => function (UserJob $c) { - return $this->translatableStringHelper->localize($c->getLabel()); - }, + 'choice_label' => fn (UserJob $c) => $this->translatableStringHelper->localize($c->getLabel()), 'query_builder' => static function (EntityRepository $er) { $qb = $er->createQueryBuilder('uj'); $qb->where('uj.active = TRUE'); @@ -100,9 +97,7 @@ class UserType extends AbstractType 'required' => false, 'placeholder' => 'choose a location', 'class' => Location::class, - 'choice_label' => function (Location $l) { - return $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ' - ' . $l->getName(); - }, + 'choice_label' => fn (Location $l) => $this->translatableStringHelper->localize($l->getLocationType()->getTitle()) . ' - ' . $l->getName(), 'query_builder' => static function (EntityRepository $er) { $qb = $er->createQueryBuilder('l'); $qb->orderBy('l.locationType'); @@ -110,6 +105,11 @@ class UserType extends AbstractType return $qb; }, + ]) + ->add('absenceStart', ChillDateType::class, [ + 'required' => false, + 'input' => 'datetime_immutable', + 'label' => 'absence.Absence start', ]); // @phpstan-ignore-next-line @@ -161,7 +161,7 @@ class UserType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Chill\MainBundle\Entity\User', + 'data_class' => \Chill\MainBundle\Entity\User::class, ]); $resolver diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index e01c7d4b6..c6278d133 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -69,9 +69,7 @@ class WorkflowStepType extends AbstractType $choices = array_combine( array_map( - static function (Transition $transition) { - return $transition->getName(); - }, + static fn (Transition $transition) => $transition->getName(), $transitions ), $transitions @@ -88,14 +86,10 @@ class WorkflowStepType extends AbstractType 'backward' => 'backward', 'neutral' => 'neutral', ], - 'choice_label' => function (string $key) use ($inputLabels) { - return $this->translatableStringHelper->localize($inputLabels[$key]); - }, - 'choice_attr' => static function (string $key) { - return [ - $key => $key, - ]; - }, + 'choice_label' => fn (string $key) => $this->translatableStringHelper->localize($inputLabels[$key]), + 'choice_attr' => static fn (string $key) => [ + $key => $key, + ], 'mapped' => false, 'expanded' => true, 'data' => 'forward', @@ -137,8 +131,8 @@ class WorkflowStepType extends AbstractType $meta = $workflow->getMetadataStore()->getPlaceMetadata($to); if ( - !array_key_exists('isFinal', $meta) || false === $meta['isFinal'] - ) { + !array_key_exists('isFinal', $meta) || false === $meta['isFinal'] + ) { $toFinal = false; } } @@ -154,6 +148,14 @@ class WorkflowStepType extends AbstractType 'label' => 'workflow.dest for next steps', 'multiple' => true, 'mapped' => false, + 'suggested' => $options['suggested_users'], + ]) + ->add('future_cc_users', PickUserDynamicType::class, [ + 'label' => 'workflow.cc for next steps', + 'multiple' => true, + 'mapped' => false, + 'required' => false, + 'suggested' => $options['suggested_users'], ]) ->add('future_dest_emails', ChillCollectionType::class, [ 'label' => 'workflow.dest by email', @@ -195,11 +197,12 @@ class WorkflowStepType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver - ->setDefined('class', EntityWorkflowStep::class) + ->setDefined('class') ->setRequired('transition') ->setAllowedTypes('transition', 'bool') ->setRequired('entity_workflow') ->setAllowedTypes('entity_workflow', EntityWorkflow::class) + ->setDefault('suggested_users', []) ->setDefault('constraints', [ new Callback( function ($step, ExecutionContextInterface $context, $payload) { @@ -234,6 +237,20 @@ class WorkflowStepType extends AbstractType } } ), + new Callback( + function ($step, ExecutionContextInterface $context, $payload) { + $form = $context->getObject(); + + foreach ($form->get('future_dest_users')->getData() as $u) { + if (in_array($u, $form->get('future_cc_users')->getData(), true)) { + $context + ->buildViolation('workflow.The user in cc cannot be a dest user in the same workflow step') + ->atPath('ccUsers') + ->addViolation(); + } + } + } + ) ]); } } diff --git a/src/Bundle/ChillMainBundle/Notification/Counter/NotificationByUserCounter.php b/src/Bundle/ChillMainBundle/Notification/Counter/NotificationByUserCounter.php index 633dc10ee..a17ffbdae 100644 --- a/src/Bundle/ChillMainBundle/Notification/Counter/NotificationByUserCounter.php +++ b/src/Bundle/ChillMainBundle/Notification/Counter/NotificationByUserCounter.php @@ -17,6 +17,8 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Repository\NotificationRepository; use Chill\MainBundle\Templating\UI\NotificationCounterInterface; use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PostPersistEventArgs; +use Doctrine\ORM\Event\PostUpdateEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -68,7 +70,7 @@ final class NotificationByUserCounter implements NotificationCounterInterface return 'chill_main_notif_unread_by_' . $user->getId(); } - public function onEditNotificationComment(NotificationComment $notificationComment, LifecycleEventArgs $eventArgs): void + public function onEditNotificationComment(NotificationComment $notificationComment, PostPersistEventArgs $eventArgs): void { $this->resetCacheForNotification($notificationComment->getNotification()); } diff --git a/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php b/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php index 81496a9a9..5290492b1 100644 --- a/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php +++ b/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php @@ -14,6 +14,8 @@ namespace Chill\MainBundle\Notification\Email; use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Entity\NotificationComment; use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PostPersistEventArgs; +use Doctrine\ORM\Event\PostUpdateEventArgs; use Psr\Log\LoggerInterface; use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\Mailer\Exception\TransportExceptionInterface; @@ -36,7 +38,7 @@ class NotificationMailer $this->translator = $translator; } - public function postPersistComment(NotificationComment $comment, LifecycleEventArgs $eventArgs): void + public function postPersistComment(NotificationComment $comment, PostPersistEventArgs $eventArgs): void { foreach ( array_merge( @@ -72,13 +74,13 @@ class NotificationMailer /** * Send a email after a notification is persisted. */ - public function postPersistNotification(Notification $notification, LifecycleEventArgs $eventArgs): void + public function postPersistNotification(Notification $notification, PostPersistEventArgs $eventArgs): void { $this->sendNotificationEmailsToAddresses($notification); $this->sendNotificationEmailsToAddressesEmails($notification); } - public function postUpdateNotification(Notification $notification, LifecycleEventArgs $eventArgs): void + public function postUpdateNotification(Notification $notification, PostUpdateEventArgs $eventArgs): void { $this->sendNotificationEmailsToAddressesEmails($notification); } diff --git a/src/Bundle/ChillMainBundle/Notification/Mailer.php b/src/Bundle/ChillMainBundle/Notification/Mailer.php index c63a96f04..307d5d1df 100644 --- a/src/Bundle/ChillMainBundle/Notification/Mailer.php +++ b/src/Bundle/ChillMainBundle/Notification/Mailer.php @@ -15,7 +15,10 @@ use Chill\MainBundle\Entity\User; use Psr\Log\LoggerInterface; use Swift_Mailer; use Swift_Message; +use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Email; use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Templating\EngineInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; @@ -26,43 +29,34 @@ use function call_user_func; * Classe d'aide pour l'envoi de notification. * * Héberge toutes les méthodes pour ré-écrire les URL en fonction de la langue de l'utilisateur. + * + * @deprecated use the MailerInterface */ class Mailer { - /** - * @var Swift_Mailer - */ - protected $forcedMailer; - /** * @var LoggerInterface */ - protected $logger; - - /** - * @var Swift_Mailer - */ - protected $mailer; + private $logger; /** * @var array */ - protected $routeParameters; + private $routeParameters; /** * @var RouterInterface */ - protected $router; + private $router; /** * @var TranslatorInterface */ - protected $translator; + private $translator; - /** - * @var \Twig\Environment - */ - protected $twig; + private EngineInterface $twig; + + private MailerInterface $mailer; /** * Mailer constructor. @@ -70,11 +64,9 @@ class Mailer * @param $routeParameters */ public function __construct( + MailerInterface $mailer, LoggerInterface $logger, - Environment $twig, - Swift_Mailer $mailer, - // due to bug https://github.com/symfony/swiftmailer-bundle/issues/127 - // \Swift_Transport $mailerTransporter, + EngineInterface $twig, RouterInterface $router, TranslatorInterface $translator, $routeParameters @@ -82,7 +74,6 @@ class Mailer $this->logger = $logger; $this->twig = $twig; $this->mailer = $mailer; - //$this->forcedMailer = new \Swift_Mailer($mailerTransporter); $this->router = $router; $this->translator = $translator; $this->routeParameters = $routeParameters; @@ -115,20 +106,6 @@ class Mailer return $content; } - /** - * @param $force - * - * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface - */ - public function sendMessage(Swift_Message $message, $force) - { - if ($force) { - $this->forcedMailer->send($message); - } else { - $this->mailer->send($message); - } - } - /** * Envoie une notification à un utilisateur. * @@ -155,23 +132,25 @@ class Mailer $subject[2] ?? null ); - $message = (new Swift_Message($subjectI18n)) - ->setFrom($fromEmail, $fromName) - ->setTo($to); + $email = new Email(); + $email->addTo($to)->subject($subjectI18n); foreach ($bodies as $contentType => $content) { - $message->setBody($content, $contentType); + match ($contentType) { + 'text/plain' => $email->text($content), + default => $email->text($content), + }; } if (null !== $callback) { - call_user_func($callback, $message); + call_user_func($callback, $email); } $this->logger->info('[notification] Sending notification', [ - 'to' => $message->getTo(), - 'subject' => $message->getSubject(), + 'to' => $email->getTo(), + 'subject' => $email->getSubject() ]); - $this->sendMessage($message, $force); + $this->mailer->send($email); } } diff --git a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php index 8ccd420c5..0720c6da6 100644 --- a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php +++ b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php @@ -74,7 +74,8 @@ class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface } return $environment->render('@ChillMain/Notification/extension_list_notifications_for.html.twig', [ - 'notifications' => $notifications, 'appendCommentForms' => $appendCommentForms, + 'notifications' => $notifications, + 'appendCommentForms' => $appendCommentForms, ]); } } diff --git a/src/Bundle/ChillMainBundle/Pagination/Page.php b/src/Bundle/ChillMainBundle/Pagination/Page.php index bf6ae42b6..d7c47ebbd 100644 --- a/src/Bundle/ChillMainBundle/Pagination/Page.php +++ b/src/Bundle/ChillMainBundle/Pagination/Page.php @@ -21,37 +21,36 @@ class Page implements PageInterface /** * the number of item per page. * - * @var int */ - protected $itemPerPage; + protected int $itemPerPage; /** * the number of the current page. * * @var int */ - protected $number; + protected int $number; /** * The route for the current page. * * @var string */ - protected $route; + protected string $route; /** * Parameters for the route to the current page. * * @var array */ - protected $routeParameters; + protected array $routeParameters; /** * The number of items in the whole iteration. * * @var int */ - protected $totalItems; + protected int $totalItems; /** * @var UrlGeneratorInterface @@ -59,12 +58,12 @@ class Page implements PageInterface protected $urlGenerator; public function __construct( - $number, - $itemPerPage, + int $number, + int $itemPerPage, UrlGeneratorInterface $urlGenerator, - $route, + string $route, array $routeParameters, - $totalItems + int $totalItems ) { $this->urlGenerator = $urlGenerator; $this->number = $number; @@ -74,24 +73,24 @@ class Page implements PageInterface $this->totalItems = $totalItems; } - public function generateUrl() + public function generateUrl(): string { return $this->urlGenerator->generate($this->route, $this->routeParameters); } - public function getFirstItemNumber() + public function getFirstItemNumber(): int { return ($this->number - 1) * $this->itemPerPage; } - public function getLastItemNumber() + public function getLastItemNumber(): int { $last = $this->number * $this->itemPerPage - 1; return $last < $this->totalItems ? $last : $this->totalItems; } - public function getNumber() + public function getNumber(): int { return $this->number; } diff --git a/src/Bundle/ChillMainBundle/Pagination/PageGenerator.php b/src/Bundle/ChillMainBundle/Pagination/PageGenerator.php index ff2d317e3..4a10fde2a 100644 --- a/src/Bundle/ChillMainBundle/Pagination/PageGenerator.php +++ b/src/Bundle/ChillMainBundle/Pagination/PageGenerator.php @@ -27,27 +27,27 @@ class PageGenerator implements Iterator $this->paginator = $paginator; } - public function current() + public function current(): Page { - return $this->paginator->getPage($current); + return $this->paginator->getPage($this->current); } - public function key() + public function key(): int { return $this->current; } - public function next() + public function next(): void { ++$this->current; } - public function rewind() + public function rewind(): void { $this->current = 1; } - public function valid() + public function valid(): bool { return 0 < $this->current && $this->paginator->countPages() >= $this->current; diff --git a/src/Bundle/ChillMainBundle/Pagination/Paginator.php b/src/Bundle/ChillMainBundle/Pagination/Paginator.php index 9d6e31390..5427bf46d 100644 --- a/src/Bundle/ChillMainBundle/Pagination/Paginator.php +++ b/src/Bundle/ChillMainBundle/Pagination/Paginator.php @@ -26,21 +26,21 @@ class Paginator implements PaginatorInterface * * @var int */ - protected $currentPageNumber; + protected int $currentPageNumber; /** * the number of items on a single page. * * @var int */ - protected $itemPerPage; + protected int $itemPerPage; /** * the key in the GET parameter to indicate the number of item per page. * * @var string */ - protected $itemPerPageKey; + protected string $itemPerPageKey; /** * the key in the GET parameter to indicate the page number in @@ -48,45 +48,45 @@ class Paginator implements PaginatorInterface * * @var string */ - protected $pageKey; + protected string $pageKey; /** * the route of the pages. * * @var string */ - protected $route; + protected string $route; /** * the parameters of the route. * * @var string[] */ - protected $routeParameters; + protected array $routeParameters; /** * The number of total items. * * @var int */ - protected $totalItems; + protected int $totalItems; /** * the generator for url. * * @var UrlGeneratorInterface */ - protected $urlGenerator; + protected UrlGeneratorInterface $urlGenerator; public function __construct( - $totalItems, - $itemPerPage, - $currentPageNumber, - $route, + int $totalItems, + int $itemPerPage, + int $currentPageNumber, + string $route, array $routeParameters, UrlGeneratorInterface $urlGenerator, - $pageKey, - $itemPerPageKey + string $pageKey, + string $itemPerPageKey ) { $this->totalItems = $totalItems; $this->itemPerPage = $itemPerPage; @@ -98,12 +98,12 @@ class Paginator implements PaginatorInterface $this->itemPerPageKey = $itemPerPageKey; } - public function count() + public function count(): int { return $this->countPages(); } - public function countPages() + public function countPages(): int { if (0 === $this->itemPerPage) { return 1; @@ -122,20 +122,17 @@ class Paginator implements PaginatorInterface return 0 === $nb ? 1 : (int) $nb; } - /** - * @return \Chill\MainBundle\Pagination\Page - */ - public function getCurrentPage() + public function getCurrentPage(): Page { return $this->getPage($this->currentPageNumber); } - public function getCurrentPageFirstItemNumber() + public function getCurrentPageFirstItemNumber(): int { return $this->getCurrentPage()->getFirstItemNumber(); } - public function getItemsPerPage() + public function getItemsPerPage(): int { return $this->itemPerPage; } @@ -145,7 +142,7 @@ class Paginator implements PaginatorInterface * * @return \Chill\MainBundle\Pagination\Page */ - public function getNextPage() + public function getNextPage(): Page { if (!$this->hasNextPage()) { throw new RuntimeException('this page has no next page'); @@ -155,11 +152,10 @@ class Paginator implements PaginatorInterface } /** - * @param type $number * * @return \Chill\MainBundle\Pagination\Page */ - public function getPage($number) + public function getPage(int $number): Page { if (!$this->hasPage($number)) { throw new RuntimeException("The page with number {$number} does not " @@ -179,7 +175,7 @@ class Paginator implements PaginatorInterface ); } - public function getPagesGenerator() + public function getPagesGenerator(): iterable { for ($i = 1; $this->countPages() >= $i; ++$i) { yield $this->getPage($i); @@ -191,7 +187,7 @@ class Paginator implements PaginatorInterface * * @return \Chill\MainBundle\Pagination\Page */ - public function getPreviousPage() + public function getPreviousPage(): PageInterface { if (!$this->hasPreviousPage()) { throw new RuntimeException('this page has no previous page'); @@ -200,7 +196,7 @@ class Paginator implements PaginatorInterface return $this->getPage($this->currentPageNumber - 1); } - public function getTotalItems() + public function getTotalItems(): int { return $this->totalItems; } @@ -208,12 +204,12 @@ class Paginator implements PaginatorInterface /** * @return bool */ - public function hasNextPage() + public function hasNextPage(): bool { return $this->hasPage($this->currentPageNumber + 1); } - public function hasPage($number) + public function hasPage($number): bool { if (0 === $this->totalItems) { return 1 === $number; @@ -226,18 +222,18 @@ class Paginator implements PaginatorInterface /** * @return bool */ - public function hasPreviousPage() + public function hasPreviousPage(): bool { return $this->hasPage($this->currentPageNumber - 1); } - public function isCurrentPage(PageInterface $page) + public function isCurrentPage(PageInterface $page): bool { return $page->getNumber() === $this->currentPageNumber; } - public function setItemsPerPage($itemPerPage) + public function setItemsPerPage(int $itemsPerPage) { - $this->itemPerPage = $itemPerPage; + $this->itemPerPage = $itemsPerPage; } } diff --git a/src/Bundle/ChillMainBundle/Pagination/PaginatorFactory.php b/src/Bundle/ChillMainBundle/Pagination/PaginatorFactory.php index 6e1c077cf..7f06bf216 100644 --- a/src/Bundle/ChillMainBundle/Pagination/PaginatorFactory.php +++ b/src/Bundle/ChillMainBundle/Pagination/PaginatorFactory.php @@ -78,9 +78,8 @@ class PaginatorFactory $totalItems, $this->getCurrentItemsPerPage(), $this->getCurrentPageNumber(), - null === $route ? $this->getCurrentRoute() : $route, - null === $routeParameters ? $this->getCurrentRouteParameters() : - $routeParameters, + $route ?? $this->getCurrentRoute(), + $routeParameters ?? $this->getCurrentRouteParameters(), $this->router, self::DEFAULT_CURRENT_PAGE_KEY, self::DEFAULT_ITEM_PER_NUMBER_KEY @@ -124,12 +123,12 @@ class PaginatorFactory return array_merge( $this->router->getContext()->getParameters(), // get the route parameters - $this->requestStack - ->getCurrentRequest() - ->attributes->get('_route_params'), + $this->requestStack + ->getCurrentRequest() + ->attributes->get('_route_params'), // get the query parameters - $this->requestStack - ->getCurrentRequest()->query->all() + $this->requestStack + ->getCurrentRequest()->query->all() ); } } diff --git a/src/Bundle/ChillMainBundle/Pagination/PaginatorInterface.php b/src/Bundle/ChillMainBundle/Pagination/PaginatorInterface.php index 9b9b75591..cbdc12e6b 100644 --- a/src/Bundle/ChillMainBundle/Pagination/PaginatorInterface.php +++ b/src/Bundle/ChillMainBundle/Pagination/PaginatorInterface.php @@ -32,26 +32,26 @@ interface PaginatorInterface extends Countable * * @return int */ - public function countPages(); + public function countPages(): int; /** * get the current page. * * @return PageInterface */ - public function getCurrentPage(); + public function getCurrentPage(): PageInterface; /** * get the first result for the current page. * * @return int */ - public function getCurrentPageFirstItemNumber(); + public function getCurrentPageFirstItemNumber(): int; /* * get the number of items per page */ - public function getItemsPerPage(); + public function getItemsPerPage(): int; /** * get the next page. @@ -60,7 +60,7 @@ interface PaginatorInterface extends Countable * * @return PageInterface */ - public function getNextPage(); + public function getNextPage(): PageInterface; /** * get page by his number. @@ -69,14 +69,14 @@ interface PaginatorInterface extends Countable * * @throws RuntimeException if the pagination has no page with specified number */ - public function getPage($number); + public function getPage(int $number): PageInterface; /** * get a generator to generate pages. * * @return Generator which return PageInterface elements */ - public function getPagesGenerator(); + public function getPagesGenerator(): iterable; /** * get the previous page. @@ -85,35 +85,35 @@ interface PaginatorInterface extends Countable * * @return PageInterface */ - public function getPreviousPage(); + public function getPreviousPage(): PageInterface; /** * get the number of results for this paginator. * * @return int */ - public function getTotalItems(); + public function getTotalItems(): int; /** * check if the current page has a next page. * * @return bool */ - public function hasNextPage(); + public function hasNextPage(): bool; /** * check if the page with the given number exists. * - * @param int $number + * @param mixed $number */ - public function hasPage($number); + public function hasPage($number): bool; /** * check if the current page has a page before. * * @return bool */ - public function hasPreviousPage(); + public function hasPreviousPage(): bool; /** * check if the given page is the current page. @@ -122,10 +122,10 @@ interface PaginatorInterface extends Countable * * @return bool */ - public function isCurrentPage(PageInterface $page); + public function isCurrentPage(PageInterface $page): bool; /* * set the number of items per page */ - public function setItemsPerPage($itemsPerPage); + public function setItemsPerPage(int $itemsPerPage); } diff --git a/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php b/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php index 5b52f6819..a92db39ce 100644 --- a/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php +++ b/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php @@ -118,7 +118,7 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface * Return true if the phonenumber is a landline or voip phone. Return always true * if the validation is not configured. * - * @param string $phonenumber + * @param string|PhoneNumber $phonenumber */ public function isValidPhonenumberAny($phonenumber): bool { @@ -138,7 +138,7 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface * Return true if the phonenumber is a landline or voip phone. Return always true * if the validation is not configured. * - * @param string $phonenumber + * @param string|PhoneNumber $phonenumber */ public function isValidPhonenumberLandOrVoip($phonenumber): bool { @@ -159,7 +159,7 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface * REturn true if the phonenumber is a mobile phone. Return always true * if the validation is not configured. * - * @param string $phonenumber + * @param string|PhoneNumber $phonenumber */ public function isValidPhonenumberMobile($phonenumber): bool { @@ -182,8 +182,12 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface return null; } + if ($phonenumber instanceof PhoneNumber) { + $phonenumber = (string) $phonenumber; + } + // filter only number - $filtered = preg_replace('/[^0-9]/', '', $phonenumber); + $filtered = preg_replace('/[^0-9]/', '', (string) $phonenumber); $item = $this->cachePool->getItem('pnum_' . $filtered); @@ -220,7 +224,7 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface return null; } - $validation = json_decode($response->getBody()->getContents())->carrier->type; + $validation = json_decode($response->getBody()->getContents(), null, 512, JSON_THROW_ON_ERROR)->carrier->type; $item ->set($validation) diff --git a/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepository.php b/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepository.php new file mode 100644 index 000000000..a3c495d7d --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepository.php @@ -0,0 +1,57 @@ +repository = $entityManager->getRepository($this->getClassName()); + } + + public function find($id): ?CronJobExecution + { + return $this->repository->find($id); + } + + /** + * @return array|CronJobExecution[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + /** + * @return array|CronJobExecution[] + */ + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria): ?CronJobExecution + { + return $this->repository->findOneBy($criteria); + } + + public function getClassName(): string + { + return CronJobExecution::class; + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepositoryInterface.php new file mode 100644 index 000000000..df894bbfb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/CronJobExecutionRepositoryInterface.php @@ -0,0 +1,34 @@ +repository = $em->getRepository($this->getClassName()); - $this->em = $em; + } + + + public function countGeographicalUnitContainingAddress(Address $address): int + { + $qb = $this->buildQueryGeographicalUnitContainingAddress($address); + + return $qb + ->select('COUNT(gu)') + ->getQuery() + ->getSingleScalarResult(); + } + + public function findGeographicalUnitContainingAddress(Address $address, int $offset = 0, int $limit = 50): array + { + $qb = $this->buildQueryGeographicalUnitContainingAddress($address); + + return $qb + ->select(sprintf('NEW %s(gu.id, gu.unitName, gu.unitRefId, IDENTITY(gu.layer))', GeographicalUnit\SimpleGeographicalUnitDTO::class)) + ->addOrderBy('IDENTITY(gu.layer)') + ->addOrderBy(('gu.unitName')) + ->getQuery() + ->setFirstResult($offset) + ->setMaxResults($limit) + ->getResult(); + } + + private function buildQueryGeographicalUnitContainingAddress(Address $address): QueryBuilder + { + $qb = $this->repository + ->createQueryBuilder('gu') + ; + return $qb + ->select(sprintf('NEW %s(gu.id, gu.unitName, gu.unitRefId, IDENTITY(gu.layer))', GeographicalUnit\SimpleGeographicalUnitDTO::class)) + ->innerJoin(Address::class, 'address', Join::WITH, 'ST_CONTAINS(gu.geom, address.point) = TRUE') + ->where($qb->expr()->eq('address', ':address')) + ->setParameter('address', $address) + ; } public function find($id): ?GeographicalUnit diff --git a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepositoryInterface.php b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepositoryInterface.php index cdfb057e2..f2c102407 100644 --- a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepositoryInterface.php +++ b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepositoryInterface.php @@ -11,8 +11,23 @@ declare(strict_types=1); namespace Chill\MainBundle\Repository; +use Chill\MainBundle\Entity\Address; +use Chill\MainBundle\Entity\GeographicalUnit\SimpleGeographicalUnitDTO; use Doctrine\Persistence\ObjectRepository; interface GeographicalUnitRepositoryInterface extends ObjectRepository { + /** + * Return the geographical units as @link{SimpleGeographicalUnitDTO} whithin the address is contained. + * + * This query is executed in real time (without the refresh of the materialized view which load the addresses). + * + * @param Address $address + * @param int $offset + * @param int $limit + * @return SimpleGeographicalUnitDTO[] + */ + public function findGeographicalUnitContainingAddress(Address $address, int $offset = 0, int $limit = 50): array; + + public function countGeographicalUnitContainingAddress(Address $address): int; } diff --git a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php new file mode 100644 index 000000000..a28f2f341 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php @@ -0,0 +1,66 @@ +repository = $entityManager->getRepository(Regroupment::class); + } + + public function find($id, $lockMode = null, $lockVersion = null): ?Regroupment + { + return $this->repository->find($id, $lockMode, $lockVersion); + } + + /** + * @return Regroupment[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + public function findAllActive(): array + { + return $this->repository->findBy(['isActive' => true], ['name' => 'ASC']); + } + + /** + * @param mixed|null $limit + * @param mixed|null $offset + * + * @return Regroupment[] + */ + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria, ?array $orderBy = null): ?Regroupment + { + return $this->repository->findOneBy($criteria, $orderBy); + } + + public function getClassName() + { + return Regroupment::class; + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php b/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php index 1fc309d6e..a304ff6d7 100644 --- a/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php @@ -27,6 +27,13 @@ class EntityWorkflowRepository implements ObjectRepository $this->repository = $entityManager->getRepository(EntityWorkflow::class); } + public function countByCc(User $user): int + { + $qb = $this->buildQueryByCc($user)->select('count(ew)'); + + return (int) $qb->getQuery()->getSingleScalarResult(); + } + public function countByDest(User $user): int { $qb = $this->buildQueryByDest($user)->select('count(ew)'); @@ -103,6 +110,19 @@ class EntityWorkflowRepository implements ObjectRepository return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } + public function findByCc(User $user, ?array $orderBy = null, $limit = null, $offset = null): array + { + $qb = $this->buildQueryByCc($user)->select('ew'); + + foreach ($orderBy as $key => $sort) { + $qb->addOrderBy('ew.' . $key, $sort); + } + + $qb->setMaxResults($limit)->setFirstResult($offset); + + return $qb->getQuery()->getResult(); + } + public function findByDest(User $user, ?array $orderBy = null, $limit = null, $offset = null): array { $qb = $this->buildQueryByDest($user)->select('ew'); @@ -165,6 +185,25 @@ class EntityWorkflowRepository implements ObjectRepository return EntityWorkflow::class; } + private function buildQueryByCc(User $user): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('ew'); + + $qb->join('ew.steps', 'step'); + + $qb->where( + $qb->expr()->andX( + $qb->expr()->isMemberOf(':user', 'step.ccUser'), + $qb->expr()->isNull('step.transitionAfter'), + $qb->expr()->eq('step.isFinal', "'FALSE'") + ) + ); + + $qb->setParameter('user', $user); + + return $qb; + } + private function buildQueryByDest(User $user): QueryBuilder { $qb = $this->repository->createQueryBuilder('ew'); diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss index aa1d24844..2523ee202 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/chillmain.scss @@ -221,12 +221,8 @@ footer.footer { */ div.admin { - flex-direction: row-reverse; div.vertical-menu { - font-size: 0.9em; - .list-group-item { - padding: 0.3rem 0.7rem; - } + .list-group-item {} } } @@ -307,12 +303,12 @@ table.table-bordered { /// meta-data div.createdBy, div.updatedBy, -div.metadata { +.metadata { span.user, span.date { text-decoration: underline dotted; } } -div.metadata { +.metadata { font-size: smaller; color: $gray-600; span.user, span.date { @@ -368,6 +364,25 @@ div#flashMessages { } } +/// unbullet lists +ul.unbullet { + list-style-type: none; + padding-left: 0; +} +/// libellé +span.dt { + font-size: 90%; + font-weight: bolder; + background-color: var(--bs-chill-light-gray); +} +/// help text +.help-text { + margin-top: 0.25rem; + font-size: 0.875em; + color: var(--bs-gray); +} + + /* * SPECIFIC RULES */ diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/record_actions.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/record_actions.scss index b8f60e250..5158a826e 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/record_actions.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/record_actions.scss @@ -1,3 +1,11 @@ +/// mixin to set sticky area on bottom when scrolling +@mixin sticky-bottom { + position: sticky; + bottom: 0; + margin-top: 4em; + z-index: 1000; +} + ul.record_actions { display: flex; flex-direction: row; @@ -53,16 +61,30 @@ ul.record_actions { } } } + +.sticky-form { + background-color: $white; + padding-top: 1.25em; + margin: -1em; + box-shadow: 0 -20px 20px -20px rgba($chill-gray, .5); + @include sticky-bottom; + + .sticky-form-buttons { + position: initial; + bottom: unset; + margin-top: unset; + z-index: unset; + } +} + .sticky-form-buttons { - margin-top: 4em; - background-color: $beige; - position: sticky; - bottom: 0.3em; - text-align: center; - display: flex; - padding: 0.8em 1.6em; - border-radius: 0; - z-index: 1000; + display: flex; + background-color: $beige; + text-align: center; + padding: 0.8em 1.6em; + border-radius: 0; + @include sticky-bottom; + bottom: 0.3em; } /// EXCEPTIONS diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss index 4d0bfcf8e..57fa17648 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss @@ -64,6 +64,7 @@ section.chill-entity { margin: 0.7em 0; p { display: block; + margin-bottom: 0; } } &.delimiter { @@ -106,18 +107,5 @@ section.chill-entity { // used for comment-embeddable &.entity-comment-embeddable { width: 100%; - - /* already defined !! - div.metadata { - font-size: smaller; - color: $gray-600; - span.user, span.date { - text-decoration: underline dotted; - &:hover { - color: $gray-700; - } - } - } - */ } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts new file mode 100644 index 000000000..1499f4a6a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts @@ -0,0 +1,35 @@ +import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../types"; +import {fetchResults, makeFetch} from "./apiMethods"; + +export const getAddressById = async (address_id: number): Promise
      => +{ + const url = `/api/1.0/main/address/${address_id}.json`; + + const response = await fetch(url); + + if (response.ok) { + return response.json(); + } + + throw Error('Error with request resource response'); +}; + +export const getGeographicalUnitsByAddress = async (address: Address): Promise => { + return fetchResults(`/api/1.0/main/geographical-unit/by-address/${address.address_id}.json`); +} + +export const getAllGeographicalUnitLayers = async (): Promise => { + return fetchResults(`/api/1.0/main/geographical-unit-layer.json`); +} + +export const syncAddressWithReference = async (address: Address): Promise
      => { + return makeFetch("POST", `/api/1.0/main/address/reference-match/${address.address_id}/sync-with-reference`); +} + +export const markAddressReviewed = async (address: Address): Promise
      => { + return makeFetch("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/reviewed`); +} + +export const markAddressToReview = async (address: Address): Promise
      => { + return makeFetch("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/to_review`); +} diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts index d12871bdd..17ac8879e 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/apiMethods.ts @@ -67,14 +67,13 @@ export const makeFetch = (method: 'POST'|'GET'|'PUT'|'PATCH'|'DEL }, }; - if (body !== null || typeof body !== 'undefined') { + if (body !== null && typeof body !== 'undefined') { Object.assign(opts, {body: JSON.stringify(body)}) } if (typeof options !== 'undefined') { opts = Object.assign(opts, options); } - return fetch(url, opts) .then(response => { if (response.ok) { diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts new file mode 100644 index 000000000..9bc2409ee --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts @@ -0,0 +1,39 @@ +import AddressDetailsButton from "../../vuejs/_components/AddressDetails/AddressDetailsButton.vue"; +import {createApp} from "vue"; +import {createI18n} from "vue-i18n"; +import {_createI18n} from "../../vuejs/_js/i18n"; +import {Address} from "../../types"; + +const i18n = _createI18n({}); + +document.querySelectorAll('span[data-address-details]').forEach((el) => { + const dataset = el.dataset as { + addressId: string, + addressRefStatus: string, + }; + + const app = createApp({ + components: {AddressDetailsButton}, + data() { + return { + addressId: Number.parseInt(dataset.addressId), + addressRefStatus: dataset.addressRefStatus, + } + }, + template: '', + methods: { + onUpdateAddress: (address: Address): void => { + if (address.refStatus === 'to_review' || address.refStatus === 'reviewed') { + // in this two case, the address content do not change + return; + } + if (window.confirm("L'adresse a été modifiée. Vous pouvez continuer votre travail. Cependant, pour afficher les données immédiatement, veuillez recharger la page. \n\n Voulez-vous recharger la page immédiatement ?")) { + window.location.reload(); + } + } + } + }); + + app.use(i18n); + app.mount(el); +}); diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js index 890929c35..99f83e1e3 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js +++ b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js @@ -18,12 +18,13 @@ function loadDynamicPicker(element) { isMultiple = parseInt(el.dataset.multiple) === 1, uniqId = el.dataset.uniqid, input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'), + // the "picked" will always be an array, even if multiple is false picked = isMultiple ? JSON.parse(input.value) : ( (input.value === '[]' || input.value === '') ? null : [ JSON.parse(input.value) ] ) - ; + suggested = JSON.parse(el.dataset.suggested) if (!isMultiple) { if (input.value === '[]'){ @@ -37,6 +38,7 @@ function loadDynamicPicker(element) { ':types="types" ' + ':picked="picked" ' + ':uniqid="uniqid" ' + + ':suggested="notPickedSuggested" ' + '@addNewEntity="addNewEntity" ' + '@removeEntity="removeEntity">', components: { @@ -48,16 +50,27 @@ function loadDynamicPicker(element) { types: JSON.parse(el.dataset.types), picked: picked === null ? [] : picked, uniqid: el.dataset.uniqid, + suggested: suggested } }, + computed: { + notPickedSuggested() { + const pickedIds = new Set(); + for (const p of this.picked) { + pickedIds.add(`${p.type}${p.id}`); + } + return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`)) + } + }, methods: { - addNewEntity(entity) { + addNewEntity({entity}) { if (this.multiple) { if (!this.picked.some(el => { return el.type === entity.type && el.id === entity.id; })) { this.picked.push(entity); input.value = JSON.stringify(this.picked); + console.log(entity) } } else { if (!this.picked.some(el => { @@ -69,9 +82,16 @@ function loadDynamicPicker(element) { } } }, - removeEntity(entity) { + removeEntity({entity}) { + if (-1 === this.suggested.findIndex(e => e.type === entity.type && e.id === entity.id)) { + this.suggested.push(entity); + } this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id)); - input.value = JSON.stringify(this.picked); + if (this.multiple) { + input.value = JSON.stringify(this.picked); + } else { + input.value = ""; + } }, } }) diff --git a/src/Bundle/ChillMainBundle/Resources/public/types.ts b/src/Bundle/ChillMainBundle/Resources/public/types.ts index 142864393..b31b70897 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/types.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/types.ts @@ -35,6 +35,7 @@ export interface User { id: number; username: string; text: string; + text_without_absence: string; email: string; user_job: Job; label: string; @@ -69,6 +70,8 @@ export interface Country { code: string; } +export type AddressRefStatus = 'match'|'to_review'|'reviewed'; + export interface Address { type: "address"; address_id: number; @@ -89,6 +92,13 @@ export interface Address { addressReference: AddressReference | null; validFrom: DateTime; validTo: DateTime | null; + point: Point | null; + refStatus: AddressRefStatus; + isNoAddress: boolean; +} + +export interface AddressWithPoint extends Address { + point: Point } export interface AddressReference { @@ -105,6 +115,19 @@ export interface AddressReference { updatedAt: DateTime | null; } +export interface SimpleGeographicalUnit { + id: number; + layerId: number; + unitName: string; + unitRefId: string; +} + +export interface GeographicalUnitLayer { + id: number; + name: TranslatableString; + refId: string; +} + export interface Location { type: "location"; id: number; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js index b1489bfb6..294ea9480 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js @@ -1,3 +1,5 @@ +import {getAddressById} from 'ChillMainAssets/lib/api/address'; + /** * Endpoint chill_api_single_country__index * method GET, get Country Object @@ -188,13 +190,7 @@ const postPostalCode = (postalCode) => { //<-- * @returns {Promise} a promise containing a Address object */ const getAddress = (id) => { - //console.log('<< get address'); - const url = `/api/1.0/main/address/${id}.json`; - return fetch(url) - .then(response => { - if (response.ok) { return response.json(); } - throw Error('Error with request resource response'); - }); + return getAddressById(id); }; export { diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index fcd64ed70..41279771f 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -48,33 +48,35 @@ -
      - + @@ -118,40 +120,42 @@ -
      - + @@ -192,32 +196,34 @@ -
      - + @@ -309,8 +315,11 @@ export default { addressMap: { // Note: LeafletJs demands [lat, lon] // cfr https://macwright.com/lonlat/ - center : [48.8589, 2.3469], - zoom: 12 + center : [ + this.context.defaults.map_center.x, + this.context.defaults.map_center.y, + ], + zoom: this.context.defaults.map_center.z }, }, errorMsg: [] @@ -571,15 +580,15 @@ export default { this.entity.selected.city = this.context.edit ? this.entity.address.postcode : {}; this.entity.selected.address = {}; - this.entity.selected.address.street = this.context.edit ? this.entity.address.street: null; - this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: null; - this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: null; - this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: null; - this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: null; - this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: null; - this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: null; - this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: null; - this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: null; + this.entity.selected.address.street = this.context.edit ? this.entity.address.street: ''; + this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: ''; + this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: ''; + this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: ''; + this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: ''; + this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: ''; + this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: ''; + this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: ''; + this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: ''; this.entity.selected.writeNew.address = this.context.edit && this.entity.address.addressReference === null && this.entity.address.street.length > 0 this.entity.selected.writeNew.postcode = false // NB: this used to be this.context.edit, but think it was erroneous; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue index 80d2ca01a..d3c04260f 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMap.vue @@ -8,8 +8,12 @@ import L from 'leaflet'; import markerIconPng from 'leaflet/dist/images/marker-icon.png' import 'leaflet/dist/leaflet.css'; +const lonLatForLeaflet = (coordinates) => { + return [coordinates[1], coordinates[0]]; +} + export default { - name: 'AddressMap', + name: 'AddressMap', props: ['entity'], data() { return { @@ -19,12 +23,49 @@ export default { }, computed: { center() { - return this.entity.selected.addressMap.center; + return this.entity.addressMap.center; + }, + hasAddressPoint() { + if (Object.keys(this.entity.address).length === 0) { + return false; + } + if (null !== this.entity.address.addressReference) { + return true; + } + if (null !== this.entity.address.postcode && null !== this.entity.address.postcode.center) { + return true; + } + return false; + }, + /** + * + * @returns {coordinates: [float, float], type: "Point"} + */ + addressPoint() { + if (Object.keys(this.entity.address).length === 0) { + return null; + } + + if (null !== this.entity.address.addressReference) { + return this.entity.address.addressReference.point; + } + + if (null !== this.entity.address.postcode && null !== this.entity.address.postcode.center) { + return this.entity.address.postcode.center; + } + + return null; }, }, methods:{ init() { - this.map = L.map('address_map').setView([46.67059, -1.42683], 12); + this.map = L.map('address_map'); + + if (!this.hasAddressPoint) { + this.map.setView(lonLatForLeaflet(this.entity.addressMap.center), this.entity.addressMap.zoom); + } else { + this.map.setView(lonLatForLeaflet(this.addressPoint.coordinates), 15); + } this.map.scrollWheelZoom.disable(); @@ -37,20 +78,22 @@ export default { iconAnchor: [12, 41], }); - this.marker = L.marker([48.8589, 2.3469], {icon: markerIcon}); + if (!this.hasAddressPoint) { + this.marker = L.marker(lonLatForLeaflet(this.entity.addressMap.center), {icon: markerIcon}); + } else { + this.marker = L.marker(lonLatForLeaflet(this.addressPoint.coordinates), {icon: markerIcon}); + } this.marker.addTo(this.map); }, update() { - //console.log('update map with : ', this.entity.addressMap.center) if (this.marker && this.entity.addressMap.center) { - this.marker.setLatLng(this.entity.addressMap.center); - this.map.setView(this.entity.addressMap.center, 15); + this.marker.setLatLng(lonLatForLeaflet(this.entity.addressMap.center)); + this.map.panTo(lonLatForLeaflet(this.entity.addressMap.center)); } } }, - mounted(){ + mounted() { this.init(); - this.update(); - } + }, } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue index 292b0de16..ca10285d1 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue @@ -104,7 +104,7 @@ export default { this.entity.selected.postcode.name = this.value.name; this.entity.selected.postcode.code = this.value.code; this.$emit('getReferenceAddresses', this.value); - if (this.value.center) { + if (typeof this.value.center !== 'undefined') { this.updateMapCenter(this.value.center); if (this.value.center.coordinates) { this.entity.selected.postcode.coordinates = this.value.center.coordinates; diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue index 6e64b2985..1b220ff00 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue @@ -30,7 +30,7 @@ export default { data() { return { value: this.selectCountryByCode( - this.context.edit ? this.entity.selected.country.code : 'FR' + this.context.edit ? this.entity.selected.country.code : this.context.defaults.default_country ) } }, @@ -45,14 +45,12 @@ export default { }, }, mounted() { - this.init(); + console.log('country selection mounted', this.value); + if (this.value !== undefined) { + this.selectCountry(this.value); + } }, - methods: { - init() { - if (this.value !== undefined) { - this.selectCountry(this.value); - } - }, + methods: { selectCountryByCode(countryCode) { return this.entity.loaded.countries.filter(c => c.countryCode === countryCode)[0]; }, diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue index 9636a173f..c0e42a7b1 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue @@ -174,8 +174,8 @@ export default { }, updateMapCenter(point) { console.log('point', point); - this.addressMap.center[0] = point.coordinates[1]; // TODO use reverse() - this.addressMap.center[1] = point.coordinates[0]; + this.addressMap.center[0] = point.coordinates[0]; + this.addressMap.center[1] = point.coordinates[1]; this.$refs.addressMap.update(); // cast child methods } } @@ -187,6 +187,7 @@ div.address-form { div#address_map { height: 400px; width: 100%; + z-index: 1; } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue index 7f7b1b529..5048815e2 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowPane.vue @@ -1,6 +1,6 @@