diff --git a/.changes/unreleased/Feature-20230920-175207.yaml b/.changes/unreleased/Feature-20230920-175207.yaml new file mode 100644 index 000000000..ec8b51f77 --- /dev/null +++ b/.changes/unreleased/Feature-20230920-175207.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: | + Add history to scopes and to jobs in administrator section. When user job or main scope of user is changed, automaticaly add a new row in history. +time: 2023-09-20T17:52:07.160601133+02:00 +custom: + Issue: "147" diff --git a/.changes/unreleased/Feature-20231004-120857.yaml b/.changes/unreleased/Feature-20231004-120857.yaml new file mode 100644 index 000000000..b3cff5e82 --- /dev/null +++ b/.changes/unreleased/Feature-20231004-120857.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Allow closing motives to be identified as 'canceling the accompanying period' + + don't take canceled accompanying periods into account +time: 2023-10-04T12:08:57.586865276+02:00 +custom: + Issue: "146" diff --git a/.changes/unreleased/Feature-20231011-155115.yaml b/.changes/unreleased/Feature-20231011-155115.yaml new file mode 100644 index 000000000..77aac142b --- /dev/null +++ b/.changes/unreleased/Feature-20231011-155115.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[export] add an aggregator for activities: group by job scope aggregator' +time: 2023-10-11T15:51:15.022779832+02:00 +custom: + Issue: "" diff --git a/.env.test b/.env.test index 914deb541..9245579c0 100644 --- a/.env.test +++ b/.env.test @@ -3,3 +3,39 @@ # Run tests from root to adapt your own environment KERNEL_CLASS='App\Kernel' APP_SECRET='$ecretf0rt3st' + +ADMIN_PASSWORD=password + +LOCALE=fr +REDIS_URL=redis +REDIS_PORT=6379 +REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} + +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem +JWT_PASSPHRASE=2a30f6ba26521a2613821da35f28386e + +TWILIO_SID=~ +TWILIO_SECRET=~ +DEFAULT_CARRIER_CODE=BE + +ADD_ADDRESS_DEFAULT_COUNTRY=BE + +ADD_ADDRESS_MAP_CENTER_X=50.8443 +ADD_ADDRESS_MAP_CENTER_Y=4.3523 +ADD_ADDRESS_MAP_CENTER_Z=15 + +SHORT_MESSAGE_DSN=null://null +MESSENGER_TRANSPORT_DSN=sync:// +###< symfony/messenger ### + +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +DATABASE_URL="postgresql://postgres:postgres@db:5432/test?serverVersion=14&charset=utf8" +###< doctrine/doctrine-bundle ### + +ASYNC_UPLOAD_TEMP_URL_KEY= +ASYNC_UPLOAD_TEMP_URL_BASE_PATH= +ASYNC_UPLOAD_TEMP_URL_CONTAINER= diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aa1eff8b1..389955c30 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ # Select what we should cache between builds cache: paths: - - tests/app/vendor/ + - /vendor/ - .cache # Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service @@ -23,12 +23,10 @@ variables: # configure database access DATABASE_URL: postgresql://postgres:postgres@db:5432/postgres?serverVersion=14&charset=utf8 # fetch the chill-app using git submodules - GIT_SUBMODULE_STRATEGY: recursive + # GIT_SUBMODULE_STRATEGY: recursive REDIS_HOST: redis REDIS_PORT: 6379 REDIS_URL: redis://redis:6379 - # change vendor dir to make the app install into tests/apps - COMPOSER_VENDOR_DIR: tests/app/vendor DEFAULT_CARRIER_CODE: BE stages: @@ -50,7 +48,7 @@ build: expire_in: 30 min paths: - bin - - tests/app/vendor/ + - vendor/ code_style: stage: Tests @@ -64,7 +62,7 @@ code_style: expire_in: 30 min paths: - bin - - tests/app/vendor/ + - vendor/ phpstan_tests: stage: Tests @@ -78,13 +76,14 @@ phpstan_tests: expire_in: 30 min paths: - bin - - tests/app/vendor/ + - vendor/ rector_tests: stage: Tests image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82 script: - - bin/rector --dry-run + - tests/console cache:clear + - bin/rector process --dry-run cache: paths: - .cache/ @@ -92,7 +91,7 @@ rector_tests: expire_in: 30 min paths: - bin - - tests/app/vendor/ + - vendor/ # psalm_tests: # stage: Tests @@ -109,19 +108,17 @@ rector_tests: unit_tests: stage: Tests 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 - - php -d memory_limit=3G tests/app/bin/console doctrine:fixtures:load -n - - php -d memory_limit=2G tests/app/bin/console cache:clear --env=test - - php -d memory_limit=4G bin/phpunit --colors=never + - php tests/console doctrine:migrations:migrate -n --env=test + - php tests/console chill:db:sync-views --env=test + - php -d memory_limit=2G tests/console cache:clear --env=test + - php -d memory_limit=3G tests/console doctrine:fixtures:load -n + - php -d memory_limit=4G bin/phpunit --colors=never --exclude-group dbIntensive artifacts: expire_in: 30 min paths: - bin - - tests/app/vendor/ + - vendor/ release: stage: Deploy diff --git a/.gitmodules b/.gitmodules index 560ba7980..7bc519c88 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "_exts/sphinx-php"] path = _exts/sphinx-php url = https://github.com/fabpot/sphinx-php.git -[submodule "tests/app"] - path = tests/app - url = https://gitlab.com/Chill-projet/chill-app.git diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 31d64e600..9aae1c43f 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -91,7 +91,7 @@ $rules = array_merge( [ '@PhpCsFixer' => true, '@PhpCsFixer:risky' => false, - '@Symfony' => false, + '@Symfony' => true, '@Symfony:risky' => false, 'ordered_class_elements' => [ 'order' => [ @@ -111,13 +111,13 @@ $rules = array_merge( 'method_private', ], 'sort_algorithm' => 'alpha', - ] + ], ], $rules, $riskyRules, $untilFullSwitchToPhp8, ); -$rules['header_comment']['header'] = trim(file_get_contents(__DIR__ . '/resource/header.txt')); +$rules['header_comment']['header'] = trim(file_get_contents(__DIR__.'/resource/header.txt')); return $config->setRules($rules); diff --git a/composer.json b/composer.json index 0ea1979fa..3195f732b 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "social worker" ], "require": { - "php": "^7.4|^8.2", + "php": "^8.2", "ext-json": "*", "ext-openssl": "*", "ext-redis": "*", @@ -48,7 +48,6 @@ "symfony/monolog-bundle": "^3.5", "symfony/security-bundle": "^4.4", "symfony/serializer": "^5.3", - "symfony/templating": "^4.4", "symfony/translation": "^4.4", "symfony/twig-bundle": "^4.4", "symfony/validator": "^4.4", @@ -76,7 +75,7 @@ "phpunit/phpunit": ">= 7.5", "psalm/plugin-phpunit": "^0.18.4", "psalm/plugin-symfony": "^4.0.2", - "rector/rector": "^0.15.23", + "rector/rector": "^0.17.7", "symfony/debug-bundle": "^5.1", "symfony/dotenv": "^4.4", "symfony/maker-bundle": "^1.20", @@ -98,7 +97,6 @@ "Chill\\DocGeneratorBundle\\": "src/Bundle/ChillDocGeneratorBundle", "Chill\\DocStoreBundle\\": "src/Bundle/ChillDocStoreBundle", "Chill\\EventBundle\\": "src/Bundle/ChillEventBundle", - "Chill\\FamilyMemberBundle\\": "src/Bundle/ChillFamilyMemberBundle", "Chill\\MainBundle\\": "src/Bundle/ChillMainBundle", "Chill\\PersonBundle\\": "src/Bundle/ChillPersonBundle", "Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle", @@ -110,7 +108,7 @@ }, "autoload-dev": { "psr-4": { - "App\\": "tests/app/src/", + "App\\": "tests/", "Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests", "Chill\\Utils\\Rector\\Tests\\": "utils/rector/tests" @@ -128,12 +126,10 @@ }, "bin-dir": "bin", "optimize-autoloader": true, - "sort-packages": true, - "vendor-dir": "tests/app/vendor" + "sort-packages": true }, "scripts": { "auto-scripts": { - "assets:install %PUBLIC_DIR%": "symfony-cmd", "cache:clear": "symfony-cmd" } } diff --git a/docs/source/_static/code/exports/CountPerson.php b/docs/source/_static/code/exports/CountPerson.php index 5d9cb2c2f..a0f6931ac 100644 --- a/docs/source/_static/code/exports/CountPerson.php +++ b/docs/source/_static/code/exports/CountPerson.php @@ -54,18 +54,9 @@ class CountPerson implements ExportInterface public function getLabels($key, array $values, $data) { // the Closure which will be executed by the formatter. - return function ($value) { - switch ($value) { - case '_header': - // we have to process specifically the '_header' string, - // which will be used by the formatter to show a column title - return $this->getTitle(); - - default: - // for all value, we do not process them and return them - // immediatly - return $value; - } + return fn($value) => match ($value) { + '_header' => $this->getTitle(), + default => $value, }; } diff --git a/docs/source/development/pagination/example.php b/docs/source/development/pagination/example.php index 0d79395a7..964da8764 100644 --- a/docs/source/development/pagination/example.php +++ b/docs/source/development/pagination/example.php @@ -13,7 +13,7 @@ namespace Chill\MyBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; -class example extends Controller +class example extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { public function yourAction() { diff --git a/docs/source/development/useful-snippets/controller-secured-for-person.php b/docs/source/development/useful-snippets/controller-secured-for-person.php index 7c8ec1931..da2078a7a 100644 --- a/docs/source/development/useful-snippets/controller-secured-for-person.php +++ b/docs/source/development/useful-snippets/controller-secured-for-person.php @@ -16,7 +16,7 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Security\Core\Role\Role; -class ConsultationController extends Controller +class ConsultationController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { /** * @param int $id personId @@ -43,7 +43,7 @@ class ConsultationController extends Controller $circles = $authorizationHelper->getReachableCircles( $this->getUser(), - new Role(ConsultationVoter::SEE), + ConsultationVoter::SEE, $person->getCenter() ); diff --git a/docs/source/development/user-interface/widgets/ChillMainConfiguration.php b/docs/source/development/user-interface/widgets/ChillMainConfiguration.php index cdad6b42b..c3a90dfee 100644 --- a/docs/source/development/user-interface/widgets/ChillMainConfiguration.php +++ b/docs/source/development/user-interface/widgets/ChillMainConfiguration.php @@ -23,25 +23,18 @@ class ChillMainConfiguration implements ConfigurationInterface { use AddWidgetConfigurationTrait; - /** - * @var ContainerBuilder - */ - private $containerBuilder; - public function __construct( array $widgetFactories, - ContainerBuilder $containerBuilder + private readonly ContainerBuilder $containerBuilder ) { // we register here widget factories (see below) $this->setWidgetFactories($widgetFactories); - // we will need the container builder later... - $this->containerBuilder = $containerBuilder; } public function getConfigTreeBuilder() { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('chill_main'); + $treeBuilder = new TreeBuilder('chill_main'); + $rootNode = $treeBuilder->getRootNode(); $rootNode ->children() diff --git a/docs/source/development/user-interface/widgets/ChillPersonAddAPersonWidget.php b/docs/source/development/user-interface/widgets/ChillPersonAddAPersonWidget.php index 0c8ed3782..0c3f2c182 100644 --- a/docs/source/development/user-interface/widgets/ChillPersonAddAPersonWidget.php +++ b/docs/source/development/user-interface/widgets/ChillPersonAddAPersonWidget.php @@ -87,7 +87,7 @@ class ChillPersonAddAPersonWidget implements WidgetInterface // show only the person from the authorized centers $and = $qb->expr()->andX(); $centers = $this->authorizationHelper - ->getReachableCenters($this->getUser(), new Role(PersonVoter::SEE)); + ->getReachableCenters($this->getUser(), PersonVoter::SEE); $and->add($qb->expr()->in('person.center', ':centers')); $qb->setParameter('centers', $centers); diff --git a/exports_alias_conventions.csv b/exports_alias_conventions.csv deleted file mode 100644 index ab32cda8e..000000000 --- a/exports_alias_conventions.csv +++ /dev/null @@ -1,63 +0,0 @@ -Entity,Join,Attribute,Alias -AccompanyingPeriod::class,,,acp -,AccompanyingPeriodWork::class,acp.works,acpw -,AccompanyingPeriodParticipation::class,acp.participations,acppart -,Location::class,acp.administrativeLocation,acploc -,ClosingMotive::class,acp.closingMotive,acpmotive -,UserJob::class,acp.job,acpjob -,Origin::class,acp.origin,acporigin -,Scope::class,acp.scopes,acpscope -,SocialIssue::class,acp.socialIssues,acpsocialissue -,User::class,acp.user,acpuser -AccompanyingPeriodWork::class,,,acpw -,AccompanyingPeriodWorkEvaluation::class,acpw.accompanyingPeriodWorkEvaluations,workeval -,User::class,acpw.referrers,acpwuser -,SocialAction::class,acpw.socialAction,acpwsocialaction -,Goal::class,acpw.goals,goal -,Result::class,acpw.results,result -AccompanyingPeriodParticipation::class,,,acppart -,Person::class,acppart.person,partperson -AccompanyingPeriodWorkEvaluation::class,,,workeval -,Evaluation::class,workeval.evaluation,eval -Goal::class,,,goal -,Result::class,goal.results,goalresult -Person::class,,,person -,Center::class,person.center,center -,HouseholdMember::class,partperson.householdParticipations,householdmember -,MaritalStatus::class,person.maritalStatus,personmarital -,VendeePerson::class,,vp -,VendeePersonMineur::class,,vpm -ResidentialAddress::class,,,resaddr -,ThirdParty::class,resaddr.hostThirdParty,tparty -ThirdParty::class,,,tparty -,ThirdPartyCategory::class,tparty.categories,tpartycat -HouseholdMember::class,,,householdmember -,Household::class,householdmember.household,household -,Person::class,householdmember.person,memberperson -,,memberperson.center,membercenter -Household::class,,,household -,HouseholdComposition::class,household.compositions,composition -Activity::class,,,activity -,Person::class,activity.person,actperson -,AccompanyingPeriod::class,activity.accompanyingPeriod,acp -,Person::class,activity_person_having_activity.person,person_person_having_activity -,ActivityReason::class,activity_person_having_activity.reasons,reasons_person_having_activity -,ActivityType::class,activity.activityType,acttype -,Location::class,activity.location,actloc -,SocialAction::class,activity.socialActions,actsocialaction -,SocialIssue::class,activity.socialIssues,actsocialssue -,ThirdParty::class,activity.thirdParties,acttparty -,User::class,activity.user,actuser -,User::class,activity.users,actusers -,ActivityReason::class,activity.reasons,actreasons -,Center::class,actperson.center,actcenter -ActivityReason::class,,,actreasons -,ActivityReasonCategory::class,actreason.category,actreasoncat -Calendar::class,,,cal -,CancelReason::class,cal.cancelReason,calcancel -,Location::class,cal.location,calloc -,User::class,cal.user,caluser -VendeePerson::class,,,vp -,SituationProfessionelle::class,vp.situationProfessionelle,vpprof -,StatutLogement::class,vp.statutLogement,vplog -,TempsDeTravail::class,vp.tempsDeTravail,vptt diff --git a/exports_alias_conventions.md b/exports_alias_conventions.md index 64df91030..eb0545702 100644 --- a/exports_alias_conventions.md +++ b/exports_alias_conventions.md @@ -21,7 +21,6 @@ These are alias conventions : | | AccompanyingPeriodInfo::class | not existing (using custom WITH clause) | acpinfo | | AccompanyingPeriodWork::class | | | acpw | | | AccompanyingPeriodWorkEvaluation::class | acpw.accompanyingPeriodWorkEvaluations | workeval | -| | User::class | acpw.referrers | acpwuser | | | SocialAction::class | acpw.socialAction | acpwsocialaction | | | Goal::class | acpw.goals | goal | | | Result::class | acpw.results | result | diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8f157fcc5..aa519e376 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,26 +2,51 @@ - + + + + + src/Bundle/ChillAsideActivityBundle/src/Tests/ + + + src/Bundle/ChillBudgetBundle/Tests/ + + + src/Bundle/ChillCalendarBundle/Tests/ + + + + src/Bundle/ChillDocGeneratorBundle/tests/ + + + src/Bundle/ChillDocStoreBundle/Tests/ + + src/Bundle/ChillMainBundle/Tests/ src/Bundle/ChillPersonBundle/Tests/ - - src/Bundle/ChillPersonBundle/Tests/Export/* src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodControllerTest.php @@ -31,14 +56,18 @@ src/Bundle/ChillPersonBundle/Tests/Controller/PersonDuplicateControllerViewTest.php - - src/Bundle/ChillAsideActivityBundle/src/Tests/ + + + + src/Bundle/ChillThirdPartyBundle/Tests src/Bundle/ChillWopiBundle/tests/ diff --git a/rector.php b/rector.php index b8975b970..0dd8e355c 100644 --- a/rector.php +++ b/rector.php @@ -19,6 +19,9 @@ return static function (RectorConfig $rectorConfig): void { __DIR__ . '/src', ]); + $rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/testsApp_KernelDevDebugContainer.xml'); + $rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php'); + //$rectorConfig->cacheClass(\Rector\Caching\ValueObject\Storage\FileCacheStorage::class); //$rectorConfig->cacheDirectory(__DIR__ . '/.cache/rector'); @@ -28,43 +31,25 @@ return static function (RectorConfig $rectorConfig): void { //define sets of rules $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_74 + LevelSetList::UP_TO_PHP_82, + \Rector\Symfony\Set\SymfonyLevelSetList::UP_TO_SYMFONY_44, + \Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_CODE_QUALITY, + \Rector\PHPUnit\Set\PHPUnitLevelSetList::UP_TO_PHPUNIT_90, ]); + // some routes are added twice if it remains activated + // $rectorConfig->rule(\Rector\Symfony\Configs\Rector\ClassMethod\AddRouteAnnotationRector::class); + // chill rules - $rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); + //$rectorConfig->rule(\Chill\Utils\Rector\Rector\ChillBundleAddFormDefaultDataOnExportFilterAggregatorRector::class); // 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 + // we must adapt service definition + \Rector\Symfony\Symfony28\Rector\MethodCall\GetToConstructorInjectionRector::class, + \Rector\Symfony\Symfony34\Rector\Closure\ContainerGetNameToTypeInTestsRector::class, ]); }; diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index d81e33bcc..43c0b13bb 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -18,7 +18,6 @@ use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface; use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityTypeCategoryRepository; use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; -use Chill\ActivityBundle\Repository\ActivityUserJobRepository; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\UserJob; @@ -35,11 +34,8 @@ use Chill\PersonBundle\Privacy\PrivacyEvent; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; use Chill\PersonBundle\Repository\PersonRepository; use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; -use DateTime; use Doctrine\ORM\EntityManagerInterface; -use InvalidArgumentException; use Psr\Log\LoggerInterface; -use RuntimeException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Form\Extension\Core\Type\HiddenType; @@ -49,7 +45,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\Translation\TranslatorInterface; -use function array_key_exists; final class ActivityController extends AbstractController { @@ -77,9 +72,9 @@ final class ActivityController extends AbstractController /** * Deletes a Activity entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/{id}/delete", name="chill_activity_activity_delete", methods={"GET", "POST", "DELETE"}) */ - public function deleteAction(Request $request, $id) + public function deleteAction(Request $request, mixed $id) { $view = null; @@ -92,10 +87,10 @@ final class ActivityController extends AbstractController } if ($activity->getAccompanyingPeriod() instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/confirm_deleteAccompanyingCourse.html.twig'; $accompanyingPeriod = $activity->getAccompanyingPeriod(); } else { - $view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig'; + $view = '@ChillActivity/Activity/confirm_deletePerson.html.twig'; } // TODO @@ -103,7 +98,7 @@ final class ActivityController extends AbstractController $form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod); - if ($request->getMethod() === Request::METHOD_DELETE) { + if (Request::METHOD_DELETE === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -136,10 +131,6 @@ final class ActivityController extends AbstractController } } - if (null === $view) { - throw $this->createNotFoundException('Template not found'); - } - return $this->render($view, [ 'activity' => $activity, 'delete_form' => $form->createView(), @@ -150,6 +141,8 @@ final class ActivityController extends AbstractController /** * Displays a form to edit an existing Activity entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/{id}/edit", name="chill_activity_activity_edit", methods={"GET", "POST", "PUT"}) */ public function editAction(int $id, Request $request): Response { @@ -165,10 +158,10 @@ final class ActivityController extends AbstractController $person = $entity->getPerson(); if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/editAccompanyingCourse.html.twig'; $accompanyingPeriod = $entity->getAccompanyingPeriod(); } else { - $view = 'ChillActivityBundle:Activity:editPerson.html.twig'; + $view = '@ChillActivity/Activity/editPerson.html.twig'; } // TODO // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity); @@ -229,10 +222,6 @@ final class ActivityController extends AbstractController $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); */ - if (null === $view) { - throw $this->createNotFoundException('Template not found'); - } - $activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); return $this->render($view, [ @@ -247,6 +236,8 @@ final class ActivityController extends AbstractController /** * Lists all Activity entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/", name="chill_activity_activity_list") */ public function listAction(Request $request): Response { @@ -282,9 +273,9 @@ final class ActivityController extends AbstractController 'element_class' => Activity::class, 'action' => 'list', ]); - $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); + $this->eventDispatcher->dispatch($event, PrivacyEvent::PERSON_PRIVACY_EVENT); - $view = 'ChillActivityBundle:Activity:listPerson.html.twig'; + $view = '@ChillActivity/Activity/listPerson.html.twig'; } elseif ($accompanyingPeriod instanceof AccompanyingPeriod) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod); @@ -300,9 +291,9 @@ final class ActivityController extends AbstractController $filterArgs ); - $view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/listAccompanyingCourse.html.twig'; } else { - throw new \LogicException("Unsupported"); + throw new \LogicException('Unsupported'); } return $this->render( @@ -332,25 +323,28 @@ final class ActivityController extends AbstractController ->addEntityChoice('activity_types', 'activity_filter.Types', \Chill\ActivityBundle\Entity\ActivityType::class, $types, [ 'choice_label' => function (\Chill\ActivityBundle\Entity\ActivityType $activityType) { $text = match ($activityType->hasCategory()) { - true => $this->translatableStringHelper->localize($activityType->getCategory()->getName()) . ' > ', + true => $this->translatableStringHelper->localize($activityType->getCategory()->getName()).' > ', false => '', }; - return $text . $this->translatableStringHelper->localize($activityType->getName()); - } + return $text.$this->translatableStringHelper->localize($activityType->getName()); + }, ]); } if (1 < count($jobs)) { $filterBuilder ->addEntityChoice('jobs', 'activity_filter.Jobs', UserJob::class, $jobs, [ - 'choice_label' => fn (UserJob $u) => $this->translatableStringHelper->localize($u->getLabel()) + 'choice_label' => fn (UserJob $u) => $this->translatableStringHelper->localize($u->getLabel()), ]); } return $filterBuilder->build(); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/new", name="chill_activity_activity_new", methods={"POST", "GET"}) + */ public function newAction(Request $request): Response { $view = null; @@ -358,16 +352,16 @@ final class ActivityController extends AbstractController [$person, $accompanyingPeriod] = $this->getEntity($request); if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:newAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/newAccompanyingCourse.html.twig'; } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:newPerson.html.twig'; + $view = '@ChillActivity/Activity/newPerson.html.twig'; } $activityType_id = $request->get('activityType_id', 0); $activityType = $this->activityTypeRepository->find($activityType_id); if (isset($activityType) && !$activityType->isActive()) { - throw new InvalidArgumentException('Activity type must be active'); + throw new \InvalidArgumentException('Activity type must be active'); } $activityData = null; @@ -402,45 +396,45 @@ final class ActivityController extends AbstractController } $entity->setActivityType($activityType); - $entity->setDate(new DateTime('now')); + $entity->setDate(new \DateTime('now')); if ($request->query->has('activityData')) { $activityData = $request->query->get('activityData'); - if (array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) { + if (\array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) { $durationTimeInMinutes = $activityData['durationTime']; $hours = floor($durationTimeInMinutes / 60); $minutes = $durationTimeInMinutes % 60; - $duration = DateTime::createFromFormat('H:i', $hours . ':' . $minutes); + $duration = \DateTime::createFromFormat('H:i', $hours.':'.$minutes); if ($duration) { $entity->setDurationTime($duration); } } - if (array_key_exists('date', $activityData)) { - $date = DateTime::createFromFormat('Y-m-d', $activityData['date']); + if (\array_key_exists('date', $activityData)) { + $date = \DateTime::createFromFormat('Y-m-d', $activityData['date']); if ($date) { $entity->setDate($date); } } - if (array_key_exists('personsId', $activityData) && $activityType->getPersonsVisible() > 0) { + if (\array_key_exists('personsId', $activityData) && $activityType->getPersonsVisible() > 0) { foreach ($activityData['personsId'] as $personId) { $concernedPerson = $this->personRepository->find($personId); $entity->addPerson($concernedPerson); } } - if (array_key_exists('professionalsId', $activityData) && $activityType->getThirdPartiesVisible() > 0) { + if (\array_key_exists('professionalsId', $activityData) && $activityType->getThirdPartiesVisible() > 0) { foreach ($activityData['professionalsId'] as $professionalsId) { $professional = $this->thirdPartyRepository->find($professionalsId); $entity->addThirdParty($professional); } } - if (array_key_exists('usersId', $activityData) && $activityType->getUsersVisible() > 0) { + if (\array_key_exists('usersId', $activityData) && $activityType->getUsersVisible() > 0) { foreach ($activityData['usersId'] as $userId) { $user = $this->userRepository->find($userId); @@ -450,16 +444,16 @@ final class ActivityController extends AbstractController } } - if (array_key_exists('location', $activityData) && $activityType->getLocationVisible() > 0) { + if (\array_key_exists('location', $activityData) && $activityType->getLocationVisible() > 0) { $location = $this->locationRepository->find($activityData['location']); $entity->setLocation($location); } - if (array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) { + if (\array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) { $comment = new CommentEmbeddable(); $comment->setComment($activityData['comment']); $comment->setUserId($this->getUser()->getid()); - $comment->setDate(new DateTime('now')); + $comment->setDate(new \DateTime('now')); $entity->setComment($comment); } } @@ -531,6 +525,9 @@ final class ActivityController extends AbstractController ]); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/select-type", name="chill_activity_activity_select_type") + */ public function selectTypeAction(Request $request): Response { $view = null; @@ -538,9 +535,9 @@ final class ActivityController extends AbstractController [$person, $accompanyingPeriod] = $this->getEntity($request); if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:selectTypeAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/selectTypeAccompanyingCourse.html.twig'; } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:selectTypePerson.html.twig'; + $view = '@ChillActivity/Activity/selectTypePerson.html.twig'; } $data = []; @@ -575,6 +572,9 @@ final class ActivityController extends AbstractController ]); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/activity/{id}/show", name="chill_activity_activity_show") + */ public function showAction(Request $request, int $id): Response { $entity = $this->activityRepository->find($id); @@ -587,11 +587,11 @@ final class ActivityController extends AbstractController $person = $entity->getPerson(); if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:showAccompanyingCourse.html.twig'; + $view = '@ChillActivity/Activity/showAccompanyingCourse.html.twig'; } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:showPerson.html.twig'; + $view = '@ChillActivity/Activity/showPerson.html.twig'; } else { - throw new RuntimeException('the activity should be linked with a period or person'); + throw new \RuntimeException('the activity should be linked with a period or person'); } if (null !== $accompanyingPeriod) { @@ -614,10 +614,6 @@ final class ActivityController extends AbstractController $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); */ - if (null === $view) { - throw $this->createNotFoundException('Template not found'); - } - return $this->render($view, [ 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php index 32cec74a5..6d0b825cc 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonCategoryController.php @@ -24,6 +24,8 @@ class ActivityReasonCategoryController extends AbstractController { /** * Creates a new ActivityReasonCategory entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/create", name="chill_activity_activityreasoncategory_create", methods={"POST"}) */ public function createAction(Request $request) { @@ -31,15 +33,15 @@ class ActivityReasonCategoryController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_show', ['id' => $entity->getId()])); + return $this->redirectToRoute('chill_activity_activityreasoncategory_show', ['id' => $entity->getId()]); } - return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -48,9 +50,9 @@ class ActivityReasonCategoryController extends AbstractController /** * Displays a form to edit an existing ActivityReasonCategory entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/{id}/edit", name="chill_activity_activityreasoncategory_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -62,7 +64,7 @@ class ActivityReasonCategoryController extends AbstractController $editForm = $this->createEditForm($entity); - return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -70,6 +72,8 @@ class ActivityReasonCategoryController extends AbstractController /** * Lists all ActivityReasonCategory entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/", name="chill_activity_activityreasoncategory") */ public function indexAction() { @@ -77,20 +81,22 @@ class ActivityReasonCategoryController extends AbstractController $entities = $em->getRepository(\Chill\ActivityBundle\Entity\ActivityReasonCategory::class)->findAll(); - return $this->render('ChillActivityBundle:ActivityReasonCategory:index.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/index.html.twig', [ 'entities' => $entities, ]); } /** * Displays a form to create a new ActivityReasonCategory entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/new", name="chill_activity_activityreasoncategory_new") */ public function newAction() { $entity = new ActivityReasonCategory(); $form = $this->createCreateForm($entity); - return $this->render('ChillActivityBundle:ActivityReasonCategory:new.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -99,9 +105,9 @@ class ActivityReasonCategoryController extends AbstractController /** * Finds and displays a ActivityReasonCategory entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/{id}/show", name="chill_activity_activityreasoncategory_show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -111,7 +117,7 @@ class ActivityReasonCategoryController extends AbstractController throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.'); } - return $this->render('ChillActivityBundle:ActivityReasonCategory:show.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/show.html.twig', [ 'entity' => $entity, ]); } @@ -119,9 +125,9 @@ class ActivityReasonCategoryController extends AbstractController /** * Edits an existing ActivityReasonCategory entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreasoncategory/{id}/update", name="chill_activity_activityreasoncategory_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -134,13 +140,13 @@ class ActivityReasonCategoryController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); - return $this->redirect($this->generateUrl('chill_activity_activityreasoncategory_edit', ['id' => $id])); + return $this->redirectToRoute('chill_activity_activityreasoncategory_edit', ['id' => $id]); } - return $this->render('ChillActivityBundle:ActivityReasonCategory:edit.html.twig', [ + return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php index 95a49d0ba..141398cc4 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityReasonController.php @@ -24,15 +24,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; */ class ActivityReasonController extends AbstractController { - private ActivityReasonRepository $activityReasonRepository; - - public function __construct(ActivityReasonRepository $activityReasonRepository) - { - $this->activityReasonRepository = $activityReasonRepository; - } + public function __construct(private readonly ActivityReasonRepository $activityReasonRepository) {} /** * Creates a new ActivityReason entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/create", name="chill_activity_activityreason_create", methods={"POST"}) */ public function createAction(Request $request) { @@ -40,15 +37,15 @@ class ActivityReasonController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl('chill_activity_activityreason', ['id' => $entity->getId()])); + return $this->redirectToRoute('chill_activity_activityreason', ['id' => $entity->getId()]); } - return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -57,9 +54,9 @@ class ActivityReasonController extends AbstractController /** * Displays a form to edit an existing ActivityReason entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/{id}/edit", name="chill_activity_activityreason_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -71,7 +68,7 @@ class ActivityReasonController extends AbstractController $editForm = $this->createEditForm($entity); - return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -79,6 +76,8 @@ class ActivityReasonController extends AbstractController /** * Lists all ActivityReason entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/", name="chill_activity_activityreason") */ public function indexAction() { @@ -86,20 +85,22 @@ class ActivityReasonController extends AbstractController $entities = $this->activityReasonRepository->findAll(); - return $this->render('ChillActivityBundle:ActivityReason:index.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/index.html.twig', [ 'entities' => $entities, ]); } /** * Displays a form to create a new ActivityReason entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/new", name="chill_activity_activityreason_new") */ public function newAction() { $entity = new ActivityReason(); $form = $this->createCreateForm($entity); - return $this->render('ChillActivityBundle:ActivityReason:new.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -108,9 +109,9 @@ class ActivityReasonController extends AbstractController /** * Finds and displays a ActivityReason entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/{id}/show", name="chill_activity_activityreason_show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -120,7 +121,7 @@ class ActivityReasonController extends AbstractController throw $this->createNotFoundException('Unable to find ActivityReason entity.'); } - return $this->render('ChillActivityBundle:ActivityReason:show.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/show.html.twig', [ 'entity' => $entity, ]); } @@ -128,9 +129,9 @@ class ActivityReasonController extends AbstractController /** * Edits an existing ActivityReason entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activityreason/{id}/update", name="chill_activity_activityreason_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -143,13 +144,13 @@ class ActivityReasonController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); - return $this->redirect($this->generateUrl('chill_activity_activityreason', ['id' => $id])); + return $this->redirectToRoute('chill_activity_activityreason', ['id' => $id]); } - return $this->render('ChillActivityBundle:ActivityReason:edit.html.twig', [ + return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); diff --git a/src/Bundle/ChillActivityBundle/Controller/AdminActivityPresenceController.php b/src/Bundle/ChillActivityBundle/Controller/AdminActivityPresenceController.php index 3a39ca072..8a1ccda44 100644 --- a/src/Bundle/ChillActivityBundle/Controller/AdminActivityPresenceController.php +++ b/src/Bundle/ChillActivityBundle/Controller/AdminActivityPresenceController.php @@ -24,7 +24,7 @@ class AdminActivityPresenceController extends CRUDController */ protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var \Doctrine\ORM\QueryBuilder $query */ + /* @var \Doctrine\ORM\QueryBuilder $query */ return $query->orderBy('e.id', 'ASC'); } } diff --git a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeCategoryController.php b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeCategoryController.php index 666f8721c..887749406 100644 --- a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeCategoryController.php +++ b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeCategoryController.php @@ -24,7 +24,7 @@ class AdminActivityTypeCategoryController extends CRUDController */ protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var \Doctrine\ORM\QueryBuilder $query */ + /* @var \Doctrine\ORM\QueryBuilder $query */ return $query->orderBy('e.ordering', 'ASC'); } } diff --git a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php index 5f245e9c4..ff75e5909 100644 --- a/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php +++ b/src/Bundle/ChillActivityBundle/Controller/AdminActivityTypeController.php @@ -24,7 +24,7 @@ class AdminActivityTypeController extends CRUDController */ protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var \Doctrine\ORM\QueryBuilder $query */ + /* @var \Doctrine\ORM\QueryBuilder $query */ return $query->orderBy('e.ordering', 'ASC') ->addOrderBy('e.id', 'ASC'); } diff --git a/src/Bundle/ChillActivityBundle/Controller/AdminController.php b/src/Bundle/ChillActivityBundle/Controller/AdminController.php index 4f96bb36f..deca96bd7 100644 --- a/src/Bundle/ChillActivityBundle/Controller/AdminController.php +++ b/src/Bundle/ChillActivityBundle/Controller/AdminController.php @@ -18,11 +18,18 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; */ class AdminController extends AbstractController { + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activity", name="chill_activity_admin_index") + */ public function indexActivityAction() { - return $this->render('ChillActivityBundle:Admin:layout_activity.html.twig'); + return $this->render('@ChillActivity/Admin/layout_activity.html.twig'); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activity_redirect_to_main", name="chill_admin_aside_activity_redirect_to_admin_index", options={null}) + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/activity_redirect_to_main", name="chill_admin_activity_redirect_to_admin_index") + */ public function redirectToAdminIndexAction() { return $this->redirectToRoute('chill_main_admin_central'); diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php index 82949d635..b205384e6 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php @@ -25,17 +25,11 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface { use \Symfony\Component\DependencyInjection\ContainerAwareTrait; - private EntityManagerInterface $em; + private readonly \Faker\Generator $faker; - /** - * @var \Faker\Generator - */ - private $faker; - - public function __construct(EntityManagerInterface $em) + public function __construct(private readonly EntityManagerInterface $em) { $this->faker = FakerFactory::create('fr_FR'); - $this->em = $em; } public function getOrder() diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReason.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReason.php index d006a624c..af674be9e 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReason.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReason.php @@ -52,13 +52,13 @@ class LoadActivityReason extends AbstractFixture implements OrderedFixtureInterf ]; foreach ($reasons as $r) { - echo 'Creating activity reason : ' . $r['name']['en'] . "\n"; + echo 'Creating activity reason : '.$r['name']['en']."\n"; $activityReason = (new ActivityReason()) - ->setName(($r['name'])) + ->setName($r['name']) ->setActive(true) ->setCategory($this->getReference($r['category'])); $manager->persist($activityReason); - $reference = 'activity_reason_' . $r['name']['en']; + $reference = 'activity_reason_'.$r['name']['en']; $this->addReference($reference, $activityReason); static::$references[] = $reference; } diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReasonCategory.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReasonCategory.php index 63d9a2ee0..a78ae3972 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReasonCategory.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityReasonCategory.php @@ -34,13 +34,13 @@ class LoadActivityReasonCategory extends AbstractFixture implements OrderedFixtu ]; foreach ($categs as $c) { - echo 'Creating activity reason category : ' . $c['name']['en'] . "\n"; + echo 'Creating activity reason category : '.$c['name']['en']."\n"; $activityReasonCategory = (new ActivityReasonCategory()) - ->setName(($c['name'])) + ->setName($c['name']) ->setActive(true); $manager->persist($activityReasonCategory); $this->addReference( - 'cat_' . $c['name']['en'], + 'cat_'.$c['name']['en'], $activityReasonCategory ); } diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityType.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityType.php index d0cd9d2be..891f2c979 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityType.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityType.php @@ -54,14 +54,14 @@ class LoadActivityType extends Fixture implements OrderedFixtureInterface ]; foreach ($types as $t) { - echo 'Creating activity type : ' . $t['name']['fr'] . ' (cat:' . $t['category'] . " \n"; + echo 'Creating activity type : '.$t['name']['fr'].' (cat:'.$t['category']." \n"; $activityType = (new ActivityType()) - ->setName(($t['name'])) - ->setCategory($this->getReference('activity_type_cat_' . $t['category'])) + ->setName($t['name']) + ->setCategory($this->getReference('activity_type_cat_'.$t['category'])) ->setSocialIssuesVisible(1) ->setSocialActionsVisible(1); $manager->persist($activityType); - $reference = 'activity_type_' . $t['name']['fr']; + $reference = 'activity_type_'.$t['name']['fr']; $this->addReference($reference, $activityType); static::$references[] = $reference; } diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityTypeCategory.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityTypeCategory.php index 4fb5a3e38..2f15a2676 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityTypeCategory.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivityTypeCategory.php @@ -42,13 +42,13 @@ class LoadActivityTypeCategory extends Fixture implements OrderedFixtureInterfac ]; foreach ($categories as $cat) { - echo 'Creating activity type category : ' . $cat['ref'] . "\n"; + echo 'Creating activity type category : '.$cat['ref']."\n"; $newCat = (new ActivityTypeCategory()) - ->setName(($cat['name'])); + ->setName($cat['name']); $manager->persist($newCat); - $reference = 'activity_type_cat_' . $cat['ref']; + $reference = 'activity_type_cat_'.$cat['ref']; $this->addReference($reference, $newCat); static::$references[] = $reference; diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivitytACL.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivitytACL.php index 0ffb2ed0e..e7c893cd9 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivitytACL.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivitytACL.php @@ -20,8 +20,6 @@ use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Persistence\ObjectManager; -use function in_array; - /** * Add a role CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE for all groups except administrative, * and a role CHILL_ACTIVITY_SEE for administrative. @@ -40,10 +38,10 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac foreach (LoadScopes::$references as $scopeRef) { $scope = $this->getReference($scopeRef); - //create permission group + // create permission group switch ($permissionsGroup->getName()) { case 'social': - if ($scope->getName()['en'] === 'administrative') { + if ('administrative' === $scope->getName()['en']) { break 2; // we do not want any power on administrative } @@ -51,7 +49,7 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac case 'administrative': case 'direction': - if (in_array($scope->getName()['en'], ['administrative', 'social'], true)) { + if (\in_array($scope->getName()['en'], ['administrative', 'social'], true)) { break 2; // we do not want any power on social or administrative } @@ -60,7 +58,7 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac printf( 'Adding CHILL_ACTIVITY_UPDATE & CHILL_ACTIVITY_CREATE & CHILL_ACTIVITY_DELETE, and stats and list permissions to %s ' - . "permission group, scope '%s' \n", + ."permission group, scope '%s' \n", $permissionsGroup->getName(), $scope->getName()['en'] ); diff --git a/src/Bundle/ChillActivityBundle/DependencyInjection/ChillActivityExtension.php b/src/Bundle/ChillActivityBundle/DependencyInjection/ChillActivityExtension.php index 49b3927ed..15e7e7e4b 100644 --- a/src/Bundle/ChillActivityBundle/DependencyInjection/ChillActivityExtension.php +++ b/src/Bundle/ChillActivityBundle/DependencyInjection/ChillActivityExtension.php @@ -32,7 +32,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf $container->setParameter('chill_activity.form.time_duration', $config['form']['time_duration']); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/export.yaml'); $loader->load('services/repositories.yaml'); @@ -73,7 +73,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf */ public function prependRoutes(ContainerBuilder $container) { - //add routes for custom bundle + // add routes for custom bundle $container->prependExtensionConfig('chill_main', [ 'routing' => [ 'resources' => [ diff --git a/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php index 57a1ec578..112d49f60 100644 --- a/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillActivityBundle/DependencyInjection/Configuration.php @@ -13,7 +13,6 @@ namespace Chill\ActivityBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; - use function is_int; /** @@ -59,7 +58,7 @@ class Configuration implements ConfigurationInterface ->info('The number of seconds of this duration. Must be an integer.') ->cannotBeEmpty() ->validate() - ->ifTrue(static fn ($data) => !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 32ceb2e74..9407aecbe 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -36,7 +36,6 @@ use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\SerializedName; @@ -46,11 +45,15 @@ use Symfony\Component\Validator\Constraints as Assert; * Class Activity. * * @ORM\Entity(repositoryClass="Chill\ActivityBundle\Repository\ActivityRepository") + * * @ORM\Table(name="activity") + * * @ORM\HasLifecycleCallbacks + * * @DiscriminatorMap(typeProperty="type", mapping={ * "activity": Activity::class * }) + * * @ActivityValidator\ActivityValidity * * TODO see if necessary @@ -65,69 +68,84 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac use TrackUpdateTrait; - public const SENTRECEIVED_RECEIVED = 'received'; + final public const SENTRECEIVED_RECEIVED = 'received'; - public const SENTRECEIVED_SENT = 'sent'; + final public const SENTRECEIVED_SENT = 'sent'; /** * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod") + * * @Groups({"read"}) */ private ?AccompanyingPeriod $accompanyingPeriod = null; /** * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityType") + * * @Groups({"read", "docgen:read"}) + * * @SerializedName("activityType") + * * @ORM\JoinColumn(name="type_id") */ private ActivityType $activityType; /** * @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityPresence") + * * @Groups({"docgen:read"}) */ private ?ActivityPresence $attendee = null; /** * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_") + * * @Groups({"docgen:read"}) */ private CommentEmbeddable $comment; /** * @ORM\Column(type="datetime") + * * @Groups({"docgen:read"}) */ - private DateTime $date; + private \DateTime $date; /** * @ORM\ManyToMany(targetEntity="Chill\DocStoreBundle\Entity\StoredObject", cascade={"persist"}) + * * @Assert\Valid(traverse=true) + * + * @var Collection */ private Collection $documents; /** * @ORM\Column(type="time", nullable=true) */ - private ?DateTime $durationTime = null; + private ?\DateTime $durationTime = null; /** * @ORM\Column(type="boolean", options={"default": false}) + * * @Groups({"docgen:read"}) */ private bool $emergency = false; /** * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") + * * @Groups({"read", "docgen:read"}) */ private ?int $id = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location") + * * @groups({"read", "docgen:read"}) */ private ?Location $location = null; @@ -139,9 +157,12 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\Person") + * * @Groups({"read", "docgen:read"}) + * + * @var Collection */ - private ?Collection $persons = null; + private Collection $persons; /** * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\PrivateCommentEmbeddable", columnPrefix="privateComment_") @@ -150,58 +171,78 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac /** * @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason") + * * @Groups({"docgen:read"}) + * + * @var Collection */ private Collection $reasons; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope") + * * @Groups({"docgen:read"}) */ private ?Scope $scope = null; /** * @ORM\Column(type="string", options={"default": ""}) + * * @Groups({"docgen:read"}) */ private string $sentReceived = ''; /** * @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialAction") + * * @ORM\JoinTable(name="chill_activity_activity_chill_person_socialaction") + * * @Groups({"read", "docgen:read"}) + * + * @var Collection */ private Collection $socialActions; /** * @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\SocialWork\SocialIssue") + * * @ORM\JoinTable(name="chill_activity_activity_chill_person_socialissue") + * * @Groups({"read", "docgen:read"}) + * + * @var Collection */ private Collection $socialIssues; /** * @ORM\ManyToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty") + * * @Groups({"read", "docgen:read"}) + * + * @var Collection */ - private ?Collection $thirdParties = null; + private Collection $thirdParties; /** * @ORM\Column(type="time", nullable=true) */ - private ?DateTime $travelTime = null; + private ?\DateTime $travelTime = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") + * * @Groups({"docgen:read"}) */ private ?User $user = null; /** * @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User") + * * @Groups({"read", "docgen:read"}) + * + * @var Collection */ - private ?Collection $users = null; + private Collection $users; public function __construct() { @@ -268,7 +309,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac $this->socialIssues[] = $socialIssue; } - if ($this->getAccompanyingPeriod() !== null) { + if (null !== $this->getAccompanyingPeriod()) { $this->getAccompanyingPeriod()->addSocialIssue($socialIssue); } @@ -334,7 +375,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this->comment; } - public function getDate(): DateTime + public function getDate(): \DateTime { return $this->date; } @@ -356,7 +397,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return (int) round(($this->durationTime->getTimestamp() + $this->durationTime->getOffset()) / 60.0, 0); } - public function getDurationTime(): ?DateTime + public function getDurationTime(): ?\DateTime { return $this->durationTime; } @@ -410,7 +451,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac // TODO better semantic with: return $this->persons->filter(...); foreach ($this->persons as $person) { - if ($this->accompanyingPeriod->getOpenParticipationContainsPerson($person) === null) { + if (null === $this->accompanyingPeriod->getOpenParticipationContainsPerson($person)) { $personsNotAssociated[] = $person; } } @@ -469,7 +510,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this->thirdParties; } - public function getTravelTime(): ?DateTime + public function getTravelTime(): ?\DateTime { return $this->travelTime; } @@ -580,7 +621,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this; } - public function setDate(DateTime $date): self + public function setDate(\DateTime $date): self { $this->date = $date; @@ -594,7 +635,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this; } - public function setDurationTime(?DateTime $durationTime): self + public function setDurationTime(?\DateTime $durationTime): self { $this->durationTime = $durationTime; @@ -664,7 +705,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac return $this; } - public function setTravelTime(DateTime $travelTime): self + public function setTravelTime(\DateTime $travelTime): self { $this->travelTime = $travelTime; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php index b0154e509..c181b7c6b 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityPresence.php @@ -18,7 +18,9 @@ use Symfony\Component\Serializer\Annotation as Serializer; * Class ActivityPresence. * * @ORM\Entity + * * @ORM\Table(name="activitytpresence") + * * @ORM\HasLifecycleCallbacks */ class ActivityPresence @@ -30,15 +32,20 @@ class ActivityPresence /** * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") + * * @Serializer\Groups({"docgen:read"}) */ private ?int $id = null; /** * @ORM\Column(type="json") + * * @Serializer\Groups({"docgen:read"}) + * * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) */ private array $name = []; diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php index e6da6b7e0..90d088f6f 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php @@ -17,39 +17,38 @@ use Doctrine\ORM\Mapping as ORM; * Class ActivityReason. * * @ORM\Entity + * * @ORM\Table(name="activityreason") + * * @ORM\HasLifecycleCallbacks */ class ActivityReason { /** - * @var bool * @ORM\Column(type="boolean") */ - private $active = true; + private bool $active = true; /** - * @var ActivityReasonCategory * @ORM\ManyToOne( * targetEntity="Chill\ActivityBundle\Entity\ActivityReasonCategory", * inversedBy="reasons") */ - private $category; + private ?ActivityReasonCategory $category = null; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** - * @var array * @ORM\Column(type="json") */ - private $name; + private array $name; /** * Get active. @@ -81,27 +80,9 @@ class ActivityReason /** * Get name. - * - * @param mixed|null $locale - * - * @return array | string */ - public function getName($locale = null) + public function getName(): array { - if ($locale) { - if (isset($this->name[$locale])) { - return $this->name[$locale]; - } - - foreach ($this->name as $name) { - if (!empty($name)) { - return $name; - } - } - - return ''; - } - return $this->name; } diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php b/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php index e8c2e245d..64d7f9672 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php @@ -12,34 +12,37 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** * Class ActivityReasonCategory. * * @ORM\Entity + * * @ORM\Table(name="activityreasoncategory") + * * @ORM\HasLifecycleCallbacks */ -class ActivityReasonCategory +class ActivityReasonCategory implements \Stringable { /** - * @var bool * @ORM\Column(type="boolean") */ - private $active = true; + private bool $active = true; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** * @var string + * * @ORM\Column(type="json") */ private $name; @@ -47,12 +50,13 @@ class ActivityReasonCategory /** * Array of ActivityReason. * - * @var ArrayCollection + * @var Collection + * * @ORM\OneToMany( * targetEntity="Chill\ActivityBundle\Entity\ActivityReason", * mappedBy="category") */ - private $reasons; + private Collection $reasons; /** * ActivityReasonCategory constructor. @@ -62,12 +66,9 @@ class ActivityReasonCategory $this->reasons = new ArrayCollection(); } - /** - * @return string - */ - public function __toString() + public function __toString(): string { - return 'ActivityReasonCategory(' . $this->getName('x') . ')'; + return 'ActivityReasonCategory('.$this->getName('x').')'; } /** @@ -121,11 +122,9 @@ class ActivityReasonCategory * as unactive, all the reason have this entity as category is also * set as unactive. * - * @param bool $active - * * @return ActivityReasonCategory */ - public function setActive($active) + public function setActive(bool $active) { if ($this->active !== $active && !$active) { foreach ($this->reasons as $reason) { diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php index ed8260a4d..c14c8292b 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityType.php @@ -12,7 +12,6 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Entity; use Doctrine\ORM\Mapping as ORM; -use InvalidArgumentException; use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; @@ -22,31 +21,36 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; * Class ActivityType. * * @ORM\Entity + * * @ORM\Table(name="activitytype") + * * @ORM\HasLifecycleCallbacks */ class ActivityType { - public const FIELD_INVISIBLE = 0; + final public const FIELD_INVISIBLE = 0; - public const FIELD_OPTIONAL = 1; + final public const FIELD_OPTIONAL = 1; - public const FIELD_REQUIRED = 2; + final public const FIELD_REQUIRED = 2; /** * @deprecated not in use + * * @ORM\Column(type="string", nullable=false, options={"default": ""}) */ private string $accompanyingPeriodLabel = ''; /** * @deprecated not in use + * * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) */ private int $accompanyingPeriodVisible = self::FIELD_INVISIBLE; /** * @ORM\Column(type="boolean") + * * @Groups({"read"}) */ private bool $active = true; @@ -118,8 +122,11 @@ class ActivityType /** * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") + * * @Groups({"docgen:read"}) */ private ?int $id = null; @@ -136,7 +143,9 @@ class ActivityType /** * @ORM\Column(type="json") + * * @Groups({"read", "docgen:read"}) + * * @Serializer\Context({"is-translatable": true}, groups={"docgen:read"}) */ private array $name = []; @@ -158,6 +167,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + * * @Groups({"read"}) */ private int $personsVisible = self::FIELD_OPTIONAL; @@ -238,6 +248,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + * * @Groups({"read"}) */ private int $thirdPartiesVisible = self::FIELD_INVISIBLE; @@ -264,6 +275,7 @@ class ActivityType /** * @ORM\Column(type="smallint", nullable=false, options={"default": 1}) + * * @Groups({"read"}) */ private int $usersVisible = self::FIELD_OPTIONAL; @@ -275,10 +287,8 @@ class ActivityType /** * @Assert\Callback - * - * @param mixed $payload */ - public function checkSocialActionsVisibility(ExecutionContextInterface $context, $payload) + public function checkSocialActionsVisibility(ExecutionContextInterface $context, mixed $payload) { if ($this->socialIssuesVisible !== $this->socialActionsVisible) { if (!(2 === $this->socialIssuesVisible && 1 === $this->socialActionsVisible)) { @@ -374,13 +384,13 @@ class ActivityType public function getLabel(string $field): ?string { - $property = $field . 'Label'; + $property = $field.'Label'; if (!property_exists($this, $property)) { - throw new InvalidArgumentException('Field "' . $field . '" not found'); + throw new \InvalidArgumentException('Field "'.$field.'" not found'); } - /** @phpstan-ignore-next-line */ + /* @phpstan-ignore-next-line */ return $this->{$property}; } @@ -533,25 +543,25 @@ class ActivityType public function isRequired(string $field): bool { - $property = $field . 'Visible'; + $property = $field.'Visible'; if (!property_exists($this, $property)) { - throw new InvalidArgumentException('Field "' . $field . '" not found'); + throw new \InvalidArgumentException('Field "'.$field.'" not found'); } - /** @phpstan-ignore-next-line */ + /* @phpstan-ignore-next-line */ return self::FIELD_REQUIRED === $this->{$property}; } public function isVisible(string $field): bool { - $property = $field . 'Visible'; + $property = $field.'Visible'; if (!property_exists($this, $property)) { - throw new InvalidArgumentException('Field "' . $field . '" not found'); + throw new \InvalidArgumentException('Field "'.$field.'" not found'); } - /** @phpstan-ignore-next-line */ + /* @phpstan-ignore-next-line */ return self::FIELD_INVISIBLE !== $this->{$property}; } diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityTypeCategory.php b/src/Bundle/ChillActivityBundle/Entity/ActivityTypeCategory.php index 2cf6972c7..680a15fa7 100644 --- a/src/Bundle/ChillActivityBundle/Entity/ActivityTypeCategory.php +++ b/src/Bundle/ChillActivityBundle/Entity/ActivityTypeCategory.php @@ -15,7 +15,9 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity + * * @ORM\Table(name="activitytypecategory") + * * @ORM\HasLifecycleCallbacks */ class ActivityTypeCategory @@ -27,7 +29,9 @@ class ActivityTypeCategory /** * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ private ?int $id = null; diff --git a/src/Bundle/ChillActivityBundle/EntityListener/ActivityEntityListener.php b/src/Bundle/ChillActivityBundle/EntityListener/ActivityEntityListener.php index 76fb440e7..31fac3be8 100644 --- a/src/Bundle/ChillActivityBundle/EntityListener/ActivityEntityListener.php +++ b/src/Bundle/ChillActivityBundle/EntityListener/ActivityEntityListener.php @@ -15,22 +15,11 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; -use function in_array; - class ActivityEntityListener { - private EntityManagerInterface $em; - - private AccompanyingPeriodWorkRepository $workRepository; - - public function __construct(EntityManagerInterface $em, AccompanyingPeriodWorkRepository $workRepository) - { - $this->em = $em; - $this->workRepository = $workRepository; - } + public function __construct(private readonly EntityManagerInterface $em, private readonly AccompanyingPeriodWorkRepository $workRepository) {} public function persistActionToCourse(Activity $activity) { @@ -39,11 +28,11 @@ class ActivityEntityListener $accompanyingCourseWorks = $this->workRepository->findByAccompanyingPeriod($period); $periodActions = []; - $now = new DateTimeImmutable(); + $now = new \DateTimeImmutable(); foreach ($accompanyingCourseWorks as $key => $work) { // take only the actions which are still opened - if ($work->getEndDate() === null || $work->getEndDate() > ($activity->getDate() ?? $now)) { + if (null === $work->getEndDate() || $work->getEndDate() > ($activity->getDate() ?? $now)) { $periodActions[$key] = spl_object_hash($work->getSocialAction()); } } @@ -52,14 +41,14 @@ class ActivityEntityListener $associatedThirdparties = $activity->getThirdParties(); foreach ($activity->getSocialActions() as $action) { - if (in_array(spl_object_hash($action), $periodActions, true)) { + if (\in_array(spl_object_hash($action), $periodActions, true)) { continue; } $newAction = new AccompanyingPeriodWork(); $newAction->setSocialAction($action); $period->addWork($newAction); - $date = DateTimeImmutable::createFromMutable($activity->getDate()); + $date = \DateTimeImmutable::createFromMutable($activity->getDate()); $newAction->setStartDate($date); foreach ($associatedPersons as $person) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index c23db738e..e9e8fb474 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -27,7 +27,7 @@ class ByActivityNumberAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data): void { $qb - ->addSelect('(SELECT COUNT(activity.id) FROM ' . Activity::class . ' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator') + ->addSelect('(SELECT COUNT(activity.id) FROM '.Activity::class.' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator') ->addGroupBy('activity_by_number_aggregator'); } @@ -40,6 +40,7 @@ class ByActivityNumberAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php index 1a75357ae..9282f92e4 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php @@ -17,21 +17,10 @@ use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class BySocialActionAggregator implements AggregatorInterface { - private SocialActionRender $actionRender; - - private SocialActionRepository $actionRepository; - - public function __construct( - SocialActionRender $actionRender, - SocialActionRepository $actionRepository - ) { - $this->actionRender = $actionRender; - $this->actionRepository = $actionRepository; - } + public function __construct(private readonly SocialActionRender $actionRender, private readonly SocialActionRepository $actionRepository) {} public function addRole(): ?string { @@ -40,7 +29,7 @@ class BySocialActionAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actsocialaction', $qb->getAllAliases(), true)) { + if (!\in_array('actsocialaction', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.socialActions', 'actsocialaction'); } @@ -57,6 +46,7 @@ class BySocialActionAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php index 9100a8c8f..bbdadf4d6 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php @@ -17,21 +17,10 @@ use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class BySocialIssueAggregator implements AggregatorInterface { - private SocialIssueRender $issueRender; - - private SocialIssueRepository $issueRepository; - - public function __construct( - SocialIssueRepository $issueRepository, - SocialIssueRender $issueRender - ) { - $this->issueRepository = $issueRepository; - $this->issueRender = $issueRender; - } + public function __construct(private readonly SocialIssueRepository $issueRepository, private readonly SocialIssueRender $issueRender) {} public function addRole(): ?string { @@ -40,7 +29,7 @@ class BySocialIssueAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actsocialissue', $qb->getAllAliases(), true)) { + if (!\in_array('actsocialissue', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.socialIssues', 'actsocialissue'); } @@ -57,6 +46,7 @@ class BySocialIssueAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php index 9103943e4..ab07afca7 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php @@ -12,14 +12,9 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; -use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\AggregatorInterface; -use Chill\MainBundle\Repository\LocationRepository; -use Chill\MainBundle\Templating\TranslatableStringHelperInterface; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; final readonly class ActivityLocationAggregator implements AggregatorInterface { @@ -32,7 +27,7 @@ final readonly class ActivityLocationAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actloc', $qb->getAllAliases(), true)) { + if (!\in_array('actloc', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.location', 'actloc'); } $qb->addSelect(sprintf('actloc.name AS %s', self::KEY)); @@ -48,12 +43,13 @@ final readonly class ActivityLocationAggregator implements AggregatorInterface { // no form required for this aggregator } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php index a74428b4a..fa658635b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php @@ -15,26 +15,14 @@ use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class ActivityTypeAggregator implements AggregatorInterface { - public const KEY = 'activity_type_aggregator'; + final public const KEY = 'activity_type_aggregator'; - protected ActivityTypeRepositoryInterface $activityTypeRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct( - ActivityTypeRepositoryInterface $activityTypeRepository, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->activityTypeRepository = $activityTypeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(protected ActivityTypeRepositoryInterface $activityTypeRepository, protected TranslatableStringHelperInterface $translatableStringHelper) {} public function addRole(): ?string { @@ -43,7 +31,7 @@ class ActivityTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acttype', $qb->getAllAliases(), true)) { + if (!\in_array('acttype', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.activityType', 'acttype'); } @@ -60,12 +48,13 @@ class ActivityTypeAggregator implements AggregatorInterface { // no form required for this aggregator } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { // for performance reason, we load data from db only once $this->activityTypeRepository->findBy(['id' => $values]); diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php index 2fab2af83..61452af22 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php @@ -15,25 +15,14 @@ use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Entity\UserRender; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; class ActivityUserAggregator implements AggregatorInterface { - public const KEY = 'activity_user_id'; + final public const KEY = 'activity_user_id'; - private UserRender $userRender; - - private UserRepository $userRepository; - - public function __construct( - UserRepository $userRepository, - UserRender $userRender - ) { - $this->userRepository = $userRepository; - $this->userRender = $userRender; - } + public function __construct(private readonly UserRepository $userRepository, private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -58,12 +47,13 @@ class ActivityUserAggregator implements AggregatorInterface { // nothing to add } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, $values, $data): Closure + public function getLabels($key, $values, $data): \Closure { return function ($value) { if ('_header' === $value) { diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php index e1e9f161d..cc4ab9d14 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php @@ -17,19 +17,10 @@ use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Templating\Entity\UserRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class ActivityUsersAggregator implements AggregatorInterface { - private UserRender $userRender; - - private UserRepositoryInterface $userRepository; - - public function __construct(UserRepositoryInterface $userRepository, UserRender $userRender) - { - $this->userRepository = $userRepository; - $this->userRender = $userRender; - } + public function __construct(private readonly UserRepositoryInterface $userRepository, private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -38,7 +29,7 @@ class ActivityUsersAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actusers', $qb->getAllAliases(), true)) { + if (!\in_array('actusers', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.users', 'actusers'); } @@ -56,6 +47,7 @@ class ActivityUsersAggregator implements AggregatorInterface { // nothing to add on the form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php index 721078989..3628206ec 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php @@ -12,23 +12,22 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; +use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\UserJobRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorInterface +class ActivityUsersJobAggregator implements AggregatorInterface { - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'act_agg_user_job'; - private UserJobRepositoryInterface $userJobRepository; - - public function __construct(UserJobRepositoryInterface $userJobRepository, TranslatableStringHelperInterface $translatableStringHelper) - { - $this->userJobRepository = $userJobRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly UserJobRepositoryInterface $userJobRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -37,24 +36,37 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actusers', $qb->getAllAliases(), true)) { - $qb->leftJoin('activity.users', 'actusers'); - } + $p = self::PREFIX; $qb - ->addSelect('IDENTITY(actusers.userJob) AS activity_users_job_aggregator') - ->addGroupBy('activity_users_job_aggregator'); + ->leftJoin('activity.users', "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Expr\Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // job_at based on activity.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'activity.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'activity.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.job) AS {$p}_select") + ->addGroupBy("{$p}_select"); } - public function applyOn() + public function applyOn(): string { return Declarations::ACTIVITY; } - public function buildForm(FormBuilderInterface $builder) - { - // nothing to add in the form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -81,11 +93,11 @@ class ActivityUsersJobAggregator implements \Chill\MainBundle\Export\AggregatorI public function getQueryKeys($data): array { - return ['activity_users_job_aggregator']; + return [self::PREFIX.'_select']; } - public function getTitle() + public function getTitle(): string { - return 'Aggregate by users job'; + return 'export.aggregator.activity.by_user_job.Aggregate by users job'; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php index d7932e9e8..bffce629f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php @@ -12,23 +12,22 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserScopeHistory; +use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\AggregatorInterface +class ActivityUsersScopeAggregator implements AggregatorInterface { - private ScopeRepositoryInterface $scopeRepository; + private const PREFIX = 'act_agg_user_scope'; - private TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct(ScopeRepositoryInterface $scopeRepository, TranslatableStringHelperInterface $translatableStringHelper) - { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly ScopeRepositoryInterface $scopeRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -37,24 +36,37 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actusers', $qb->getAllAliases(), true)) { - $qb->leftJoin('activity.users', 'actusers'); - } + $p = self::PREFIX; $qb - ->addSelect('IDENTITY(actusers.mainScope) AS activity_users_main_scope_aggregator') - ->addGroupBy('activity_users_main_scope_aggregator'); + ->leftJoin('activity.users', "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Expr\Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // scope_at based on activity.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'activity.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'activity.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select") + ->addGroupBy("{$p}_select"); } - public function applyOn() + public function applyOn(): string { return Declarations::ACTIVITY; } - public function buildForm(FormBuilderInterface $builder) - { - // nothing to add in the form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -81,11 +93,11 @@ class ActivityUsersScopeAggregator implements \Chill\MainBundle\Export\Aggregato public function getQueryKeys($data): array { - return ['activity_users_main_scope_aggregator']; + return [self::PREFIX.'_select']; } - public function getTitle() + public function getTitle(): string { - return 'Aggregate by users scope'; + return 'export.aggregator.activity.by_user_scope.Aggregate by users scope'; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ByCreatorAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ByCreatorAggregator.php index 10f8b2f09..09bdab89e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ByCreatorAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ByCreatorAggregator.php @@ -20,17 +20,7 @@ use Symfony\Component\Form\FormBuilderInterface; class ByCreatorAggregator implements AggregatorInterface { - private UserRender $userRender; - - private UserRepositoryInterface $userRepository; - - public function __construct( - UserRepositoryInterface $userRepository, - UserRender $userRender - ) { - $this->userRepository = $userRepository; - $this->userRender = $userRender; - } + public function __construct(private readonly UserRepositoryInterface $userRepository, private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -52,6 +42,7 @@ class ByCreatorAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ByThirdpartyAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ByThirdpartyAggregator.php index 5e19f961c..13224bade 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ByThirdpartyAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ByThirdpartyAggregator.php @@ -17,21 +17,10 @@ use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class ByThirdpartyAggregator implements AggregatorInterface { - private ThirdPartyRender $thirdPartyRender; - - private ThirdPartyRepository $thirdPartyRepository; - - public function __construct( - ThirdPartyRepository $thirdPartyRepository, - ThirdPartyRender $thirdPartyRender - ) { - $this->thirdPartyRepository = $thirdPartyRepository; - $this->thirdPartyRender = $thirdPartyRender; - } + public function __construct(private readonly ThirdPartyRepository $thirdPartyRepository, private readonly ThirdPartyRender $thirdPartyRender) {} public function addRole(): ?string { @@ -40,7 +29,7 @@ class ByThirdpartyAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('acttparty', $qb->getAllAliases(), true)) { + if (!\in_array('acttparty', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.thirdParties', 'acttparty'); } @@ -57,6 +46,7 @@ class ByThirdpartyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php index cc5f5d4b5..6641f0807 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php @@ -12,26 +12,22 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\ScopeRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class CreatorScopeAggregator implements AggregatorInterface { - private ScopeRepository $scopeRepository; - - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'acp_agg_creator_scope'; public function __construct( - ScopeRepository $scopeRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly ScopeRepository $scopeRepository, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -40,12 +36,28 @@ class CreatorScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actcreator', $qb->getAllAliases(), true)) { - $qb->leftJoin('activity.createdBy', 'actcreator'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(actcreator.mainScope) AS creatorscope_aggregator'); - $qb->addGroupBy('creatorscope_aggregator'); + $qb + ->leftJoin('activity.createdBy', "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // scope_at based on activity.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'activity.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'activity.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select") + ->addGroupBy("{$p}_select"); } public function applyOn(): string @@ -53,10 +65,8 @@ class CreatorScopeAggregator implements AggregatorInterface return Declarations::ACTIVITY; } - public function buildForm(FormBuilderInterface $builder) - { - // no form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -83,11 +93,11 @@ class CreatorScopeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['creatorscope_aggregator']; + return [self::PREFIX.'_select']; } public function getTitle(): string { - return 'Group activity by creator scope'; + return 'export.aggregator.activity.by_creator_scope.Group activity by creator scope'; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/DateAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/DateAggregator.php index e1c4591cd..f7315140e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/DateAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/DateAggregator.php @@ -14,10 +14,8 @@ namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Doctrine\ORM\QueryBuilder; -use RuntimeException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Contracts\Translation\TranslatorInterface; class DateAggregator implements AggregatorInterface { @@ -56,7 +54,7 @@ class DateAggregator implements AggregatorInterface break; // order DESC does not works ! default: - throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); + throw new \RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency'])); } $qb->addSelect(sprintf("TO_CHAR(activity.date, '%s') AS date_aggregator", $fmt)); @@ -78,6 +76,7 @@ class DateAggregator implements AggregatorInterface 'empty_data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array { return ['frequency' => self::DEFAULT_CHOICE]; @@ -87,24 +86,16 @@ class DateAggregator implements AggregatorInterface { return static function ($value) use ($data): string { if ('_header' === $value) { - return 'by ' . $data['frequency']; + return 'by '.$data['frequency']; } if (null === $value) { return ''; } - switch ($data['frequency']) { - case 'month': - case 'week': - //return $this->translator->trans('for week') .' '. $value ; - - case 'year': - //return $this->translator->trans('in year') .' '. $value ; - - default: - return $value; - } + return match ($data['frequency']) { + default => $value, + }; }; } diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/JobScopeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/JobScopeAggregator.php new file mode 100644 index 000000000..e43f430d5 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/JobScopeAggregator.php @@ -0,0 +1,103 @@ +leftJoin('activity.createdBy', "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // job_at based on activity.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'activity.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'activity.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.job) AS {$p}_select") + ->addGroupBy("{$p}_select"); + } + + public function applyOn(): string + { + return Declarations::ACTIVITY; + } + + public function buildForm(FormBuilderInterface $builder) {} + + public function getFormDefaultData(): array + { + return []; + } + + public function getLabels($key, array $values, $data) + { + return function ($value): string { + if ('_header' === $value) { + return 'Scope'; + } + + if (null === $value || '' === $value) { + return ''; + } + + $s = $this->scopeRepository->find($value); + + return $this->translatableStringHelper->localize( + $s->getName() + ); + }; + } + + public function getQueryKeys($data): array + { + return [self::PREFIX.'_select']; + } + + public function getTitle(): string + { + return 'export.aggregator.activity.by_creator_job.Group activity by creator job'; + } +} diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/LocationTypeAggregator.php index ce9302e9e..da2d74f64 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/LocationTypeAggregator.php @@ -17,21 +17,10 @@ use Chill\MainBundle\Repository\LocationTypeRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class LocationTypeAggregator implements AggregatorInterface { - private LocationTypeRepository $locationTypeRepository; - - private TranslatableStringHelper $translatableStringHelper; - - public function __construct( - LocationTypeRepository $locationTypeRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->locationTypeRepository = $locationTypeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly LocationTypeRepository $locationTypeRepository, private readonly TranslatableStringHelper $translatableStringHelper) {} public function addRole(): ?string { @@ -40,7 +29,7 @@ class LocationTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actloc', $qb->getAllAliases(), true)) { + if (!\in_array('actloc', $qb->getAllAliases(), true)) { $qb->leftJoin('activity.location', 'actloc'); } @@ -57,6 +46,7 @@ class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php index 2537f2cf6..4b1f4894e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/ActivityReasonAggregator.php @@ -17,34 +17,15 @@ use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; -use RuntimeException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use function count; -use function in_array; - class ActivityReasonAggregator implements AggregatorInterface, ExportElementValidatedInterface { - protected ActivityReasonCategoryRepository $activityReasonCategoryRepository; - - protected ActivityReasonRepository $activityReasonRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct( - ActivityReasonCategoryRepository $activityReasonCategoryRepository, - ActivityReasonRepository $activityReasonRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->activityReasonCategoryRepository = $activityReasonCategoryRepository; - $this->activityReasonRepository = $activityReasonRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(protected ActivityReasonCategoryRepository $activityReasonCategoryRepository, protected ActivityReasonRepository $activityReasonRepository, protected TranslatableStringHelper $translatableStringHelper) {} public function addRole(): ?string { @@ -61,20 +42,20 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali $elem = 'actreasoncat.id'; $alias = 'activity_categories_id'; } else { - throw new RuntimeException('The data provided are not recognized.'); + throw new \RuntimeException('The data provided are not recognized.'); } - $qb->addSelect($elem . ' as ' . $alias); + $qb->addSelect($elem.' as '.$alias); // make a jointure only if needed - if (!in_array('actreasons', $qb->getAllAliases(), true)) { + if (!\in_array('actreasons', $qb->getAllAliases(), true)) { $qb->innerJoin('activity.reasons', 'actreasons'); } // join category if necessary if ('activity_categories_id' === $alias) { // add join only if needed - if (!in_array('actreasoncat', $qb->getAllAliases(), true)) { + if (!\in_array('actreasoncat', $qb->getAllAliases(), true)) { $qb->join('actreasons.category', 'actreasoncat'); } } @@ -82,7 +63,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali // add the "group by" part $groupBy = $qb->getDQLPart('groupBy'); - if (count($groupBy) > 0) { + if (\count($groupBy) > 0) { $qb->addGroupBy($alias); } else { $qb->groupBy($alias); @@ -110,6 +91,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali ] ); } + public function getFormDefaultData(): array { return []; @@ -117,21 +99,11 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali public function getLabels($key, array $values, $data) { - // for performance reason, we load data from db only once - switch ($data['level']) { - case 'reasons': - $this->activityReasonRepository->findBy(['id' => $values]); - - break; - - case 'categories': - $this->activityReasonCategoryRepository->findBy(['id' => $values]); - - break; - - default: - throw new RuntimeException(sprintf("The level data '%s' is invalid.", $data['level'])); - } + match ($data['level']) { + 'reasons' => $this->activityReasonRepository->findBy(['id' => $values]), + 'categories' => $this->activityReasonCategoryRepository->findBy(['id' => $values]), + default => throw new \RuntimeException(sprintf("The level data '%s' is invalid.", $data['level'])), + }; return function ($value) use ($data) { if ('_header' === $value) { @@ -171,7 +143,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali return ['activity_categories_id']; } - throw new RuntimeException('The data provided are not recognised.'); + throw new \RuntimeException('The data provided are not recognised.'); } public function getTitle() diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php index ae1dae375..774968544 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/SentReceivedAggregator.php @@ -14,18 +14,12 @@ namespace Chill\ActivityBundle\Export\Aggregator; use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; class SentReceivedAggregator implements AggregatorInterface { - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } + public function __construct(private readonly TranslatorInterface $translator) {} public function addRole(): ?string { @@ -47,6 +41,7 @@ class SentReceivedAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array { return []; @@ -71,7 +66,7 @@ class SentReceivedAggregator implements AggregatorInterface return $this->translator->trans('export.aggregator.activity.by_sent_received.is received'); default: - throw new LogicException(sprintf('The value %s is not valid', $value)); + throw new \LogicException(sprintf('The value %s is not valid', $value)); } }; } diff --git a/src/Bundle/ChillActivityBundle/Export/Declarations.php b/src/Bundle/ChillActivityBundle/Export/Declarations.php index 79afb09c8..210988770 100644 --- a/src/Bundle/ChillActivityBundle/Export/Declarations.php +++ b/src/Bundle/ChillActivityBundle/Export/Declarations.php @@ -16,9 +16,9 @@ namespace Chill\ActivityBundle\Export; */ abstract class Declarations { - public const ACTIVITY = 'activity'; + final public const ACTIVITY = 'activity'; - public const ACTIVITY_ACP = 'activity_linked_to_acp'; + final public const ACTIVITY_ACP = 'activity_linked_to_acp'; - public const ACTIVITY_PERSON = 'activity_linked_to_person'; + final public const ACTIVITY_PERSON = 'activity_linked_to_person'; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php index 128704296..9cdbc183d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityDuration.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Export\LinkedToACP; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; @@ -23,7 +24,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class AvgActivityDuration implements ExportInterface, GroupedExportInterface @@ -31,12 +31,13 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface protected EntityRepository $repository; public function __construct( - EntityManagerInterface $em + EntityManagerInterface $em, ) { $this->repository = $em->getRepository(Activity::class); } public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -60,7 +61,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_avg_activity_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period duration' : $value; @@ -100,14 +101,16 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part - JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) ' ) ) ->setParameter('authorized_centers', $centers); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php index f1e926c64..58ac6e829 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/AvgActivityVisitDuration.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Export\LinkedToACP; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; @@ -23,7 +24,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterface @@ -31,7 +31,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac protected EntityRepository $repository; public function __construct( - EntityManagerInterface $em + EntityManagerInterface $em, ) { $this->repository = $em->getRepository(Activity::class); } @@ -40,6 +40,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array { return []; @@ -63,7 +64,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function getLabels($key, array $values, $data) { if ('export_avg_activity_visit_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period visit duration' : $value; @@ -103,14 +104,16 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part - JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) ' ) ) ->setParameter('authorized_centers', $centers); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php index 28a318541..39c79cf1f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/CountActivity.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Export\LinkedToACP; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; @@ -23,7 +24,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class CountActivity implements ExportInterface, GroupedExportInterface @@ -31,12 +31,13 @@ class CountActivity implements ExportInterface, GroupedExportInterface protected EntityRepository $repository; public function __construct( - EntityManagerInterface $em + EntityManagerInterface $em, ) { $this->repository = $em->getRepository(Activity::class); } public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -60,7 +61,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_count_activity' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Number of activities linked to an accompanying period' : $value; @@ -97,14 +98,16 @@ class CountActivity implements ExportInterface, GroupedExportInterface $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part - JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) ' ) ) ->setParameter('authorized_centers', $centers); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + $qb->select('COUNT(DISTINCT activity.id) as export_count_activity'); return $qb; diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php index e7bd27d82..45233d97f 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/ListActivity.php @@ -16,6 +16,7 @@ use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Export\Export\ListActivityHelper; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper; use Chill\MainBundle\Export\ListInterface; @@ -25,26 +26,13 @@ use Symfony\Component\Form\FormBuilderInterface; class ListActivity implements ListInterface, GroupedExportInterface { - private EntityManagerInterface $entityManager; - - private ListActivityHelper $helper; - - private TranslatableStringExportLabelHelper $translatableStringExportLabelHelper; - - public function __construct( - ListActivityHelper $helper, - EntityManagerInterface $entityManager, - TranslatableStringExportLabelHelper $translatableStringExportLabelHelper - ) { - $this->helper = $helper; - $this->entityManager = $entityManager; - $this->translatableStringExportLabelHelper = $translatableStringExportLabelHelper; - } + public function __construct(private readonly ListActivityHelper $helper, private readonly EntityManagerInterface $entityManager, private readonly TranslatableStringExportLabelHelper $translatableStringExportLabelHelper) {} public function buildForm(FormBuilderInterface $builder) { $this->helper->buildForm($builder); } + public function getFormDefaultData(): array { return []; @@ -57,7 +45,7 @@ class ListActivity implements ListInterface, GroupedExportInterface public function getDescription() { - return ListActivityHelper::MSG_KEY . 'List activities linked to an accompanying course'; + return ListActivityHelper::MSG_KEY.'List activities linked to an accompanying course'; } public function getGroup(): string @@ -67,22 +55,17 @@ class ListActivity implements ListInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { - switch ($key) { - case 'acpId': - return static function ($value) { - if ('_header' === $value) { - return ListActivityHelper::MSG_KEY . 'accompanying course id'; - } + return match ($key) { + 'acpId' => static function ($value) { + if ('_header' === $value) { + return ListActivityHelper::MSG_KEY.'accompanying course id'; + } - return $value ?? ''; - }; - - case 'scopesNames': - return $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, ListActivityHelper::MSG_KEY . 'course circles'); - - default: - return $this->helper->getLabels($key, $values, $data); - } + return $value ?? ''; + }, + 'scopesNames' => $this->translatableStringExportLabelHelper->getLabelMulti($key, $values, ListActivityHelper::MSG_KEY.'course circles'), + default => $this->helper->getLabels($key, $values, $data), + }; } public function getQueryKeys($data) @@ -104,7 +87,7 @@ class ListActivity implements ListInterface, GroupedExportInterface public function getTitle() { - return ListActivityHelper::MSG_KEY . 'List activity linked to a course'; + return ListActivityHelper::MSG_KEY.'List activity linked to a course'; } public function getType() @@ -128,7 +111,7 @@ class ListActivity implements ListInterface, GroupedExportInterface ->andWhere( $qb->expr()->exists( 'SELECT 1 - FROM ' . PersonCenterHistory::class . ' acl_count_person_history + FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person AND acl_count_person_history.center IN (:authorized_centers) ' @@ -145,9 +128,11 @@ class ListActivity implements ListInterface, GroupedExportInterface // add select for this step $qb ->addSelect('acp.id AS acpId') - ->addSelect('(SELECT AGGREGATE(acpScope.name) FROM ' . Scope::class . ' acpScope WHERE acpScope MEMBER OF acp.scopes) AS scopesNames') + ->addSelect('(SELECT AGGREGATE(acpScope.name) FROM '.Scope::class.' acpScope WHERE acpScope MEMBER OF acp.scopes) AS scopesNames') ->addGroupBy('scopesNames'); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php index 8adb3b77f..a8d6f10fd 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Export\LinkedToACP; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; @@ -23,7 +24,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class SumActivityDuration implements ExportInterface, GroupedExportInterface @@ -31,7 +31,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface protected EntityRepository $repository; public function __construct( - EntityManagerInterface $em + EntityManagerInterface $em, ) { $this->repository = $em->getRepository(Activity::class); } @@ -40,6 +40,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array { return []; @@ -63,7 +64,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_sum_activity_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period duration' : $value; @@ -103,14 +104,16 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part - JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) ' ) ) ->setParameter('authorized_centers', $centers); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php index cc424e68b..dae572ba5 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Export\LinkedToACP; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; @@ -23,7 +24,6 @@ use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class SumActivityVisitDuration implements ExportInterface, GroupedExportInterface @@ -31,7 +31,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac protected EntityRepository $repository; public function __construct( - EntityManagerInterface $em + EntityManagerInterface $em, ) { $this->repository = $em->getRepository(Activity::class); } @@ -40,6 +40,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac { // TODO: Implement buildForm() method. } + public function getFormDefaultData(): array { return []; @@ -63,7 +64,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac public function getLabels($key, array $values, $data) { if ('export_sum_activity_visit_duration' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period visit duration' : $value; @@ -103,14 +104,16 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . AccompanyingPeriodParticipation::class . ' acl_count_part - JOIN ' . PersonCenterHistory::class . ' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) + 'SELECT 1 FROM '.AccompanyingPeriodParticipation::class.' acl_count_part + JOIN '.PersonCenterHistory::class.' acl_count_person_history WITH IDENTITY(acl_count_person_history.person) = IDENTITY(acl_count_part.person) WHERE acl_count_part.accompanyingPeriod = acp.id AND acl_count_person_history.center IN (:authorized_centers) ' ) ) ->setParameter('authorized_centers', $centers); + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); + return $qb; } diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php index 5b0fe2d2c..dbc7e3fde 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/CountActivity.php @@ -19,20 +19,14 @@ use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class CountActivity implements ExportInterface, GroupedExportInterface { - protected ActivityRepository $activityRepository; - - public function __construct( - ActivityRepository $activityRepository - ) { - $this->activityRepository = $activityRepository; - } + public function __construct(protected ActivityRepository $activityRepository) {} public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -56,7 +50,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_count_activity' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Number of activities linked to a person' : $value; diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php index 129ec53fb..50b8ace2a 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/ListActivity.php @@ -20,7 +20,6 @@ use Chill\MainBundle\Export\GroupedExportInterface; use Chill\MainBundle\Export\ListInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Export\Declarations as PersonDeclarations; -use DateTime; use Doctrine\DBAL\Exception\InvalidArgumentException; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query; @@ -30,14 +29,8 @@ use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Contracts\Translation\TranslatorInterface; -use function array_key_exists; -use function count; -use function in_array; - class ListActivity implements ListInterface, GroupedExportInterface { - protected EntityManagerInterface $entityManager; - protected array $fields = [ 'id', 'date', @@ -52,23 +45,7 @@ class ListActivity implements ListInterface, GroupedExportInterface 'person_id', ]; - protected TranslatableStringHelperInterface $translatableStringHelper; - - protected TranslatorInterface $translator; - - private ActivityRepository $activityRepository; - - public function __construct( - EntityManagerInterface $em, - TranslatorInterface $translator, - TranslatableStringHelperInterface $translatableStringHelper, - ActivityRepository $activityRepository - ) { - $this->entityManager = $em; - $this->translator = $translator; - $this->translatableStringHelper = $translatableStringHelper; - $this->activityRepository = $activityRepository; - } + public function __construct(protected EntityManagerInterface $entityManager, protected TranslatorInterface $translator, protected TranslatableStringHelperInterface $translatableStringHelper, private readonly ActivityRepository $activityRepository) {} public function buildForm(FormBuilderInterface $builder) { @@ -79,7 +56,7 @@ class ListActivity implements ListInterface, GroupedExportInterface 'label' => 'Fields to include in export', 'constraints' => [new Callback([ 'callback' => static function ($selected, ExecutionContextInterface $context) { - if (count($selected) === 0) { + if (0 === \count($selected)) { $context->buildViolation('You must select at least one element') ->atPath('fields') ->addViolation(); @@ -88,6 +65,7 @@ class ListActivity implements ListInterface, GroupedExportInterface ])], ]); } + public function getFormDefaultData(): array { return []; @@ -117,7 +95,7 @@ class ListActivity implements ListInterface, GroupedExportInterface return 'date'; } - $date = DateTime::createFromFormat('Y-m-d H:i:s', $value); + $date = \DateTime::createFromFormat('Y-m-d H:i:s', $value); return $date->format('d-m-Y'); }; @@ -141,11 +119,11 @@ class ListActivity implements ListInterface, GroupedExportInterface $activity = $activityRepository->find($value); - return implode(', ', array_map(fn (ActivityReason $r) => '"' . + return implode(', ', array_map(fn (ActivityReason $r) => '"'. $this->translatableStringHelper->localize($r->getCategory()->getName()) - . ' > ' . + .' > '. $this->translatableStringHelper->localize($r->getName()) - . '"', $activity->getReasons()->toArray())); + .'"', $activity->getReasons()->toArray())); }; case 'circle_name': @@ -154,7 +132,7 @@ class ListActivity implements ListInterface, GroupedExportInterface return 'circle'; } - return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); + return $this->translatableStringHelper->localize(json_decode((string) $value, true, 512, JSON_THROW_ON_ERROR)); }; case 'type_name': @@ -163,7 +141,7 @@ class ListActivity implements ListInterface, GroupedExportInterface return 'activity type'; } - return $this->translatableStringHelper->localize(json_decode($value, true, 512, JSON_THROW_ON_ERROR)); + return $this->translatableStringHelper->localize(json_decode((string) $value, true, 512, JSON_THROW_ON_ERROR)); }; default: @@ -202,7 +180,7 @@ class ListActivity implements ListInterface, GroupedExportInterface $centers = array_map(static fn ($el) => $el['center'], $acl); // throw an error if any fields are present - if (!array_key_exists('fields', $data)) { + if (!\array_key_exists('fields', $data)) { throw new InvalidArgumentException('Any fields have been checked.'); } @@ -226,7 +204,7 @@ class ListActivity implements ListInterface, GroupedExportInterface ->setParameter('centers', $centers); foreach ($this->fields as $f) { - if (in_array($f, $data['fields'], true)) { + if (\in_array($f, $data['fields'], true)) { switch ($f) { case 'id': $qb->addSelect('activity.id AS id'); diff --git a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php index 3e7d86c89..6f254bb08 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/LinkedToPerson/StatActivityDuration.php @@ -20,7 +20,6 @@ use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\PersonBundle\Export\Declarations as PersonDeclarations; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; /** @@ -30,27 +29,21 @@ use Symfony\Component\Form\FormBuilderInterface; */ class StatActivityDuration implements ExportInterface, GroupedExportInterface { - public const SUM = 'sum'; - - /** - * The action for this report. - */ - protected string $action; - - private ActivityRepository $activityRepository; + final public const SUM = 'sum'; /** * @param string $action the stat to perform */ public function __construct( - ActivityRepository $activityRepository, - string $action = 'sum' - ) { - $this->action = $action; - $this->activityRepository = $activityRepository; - } + private readonly ActivityRepository $activityRepository, + /** + * The action for this report. + */ + protected string $action = 'sum' + ) {} public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -67,7 +60,7 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface return 'Sum activities linked to a person duration by various parameters.'; } - throw new LogicException('this action is not supported: ' . $this->action); + throw new \LogicException('this action is not supported: '.$this->action); } public function getGroup(): string @@ -78,7 +71,7 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_stat_activity' !== $key) { - throw new LogicException(sprintf('The key %s is not used by this export', $key)); + throw new \LogicException(sprintf('The key %s is not used by this export', $key)); } $header = self::SUM === $this->action ? 'Sum activities linked to a person duration' : false; @@ -102,7 +95,7 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface return 'Sum activity linked to a person duration'; } - throw new LogicException('This action is not supported: ' . $this->action); + throw new \LogicException('This action is not supported: '.$this->action); } public function getType(): string diff --git a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php index d1be2f662..75d2c3fd0 100644 --- a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php +++ b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php @@ -23,54 +23,24 @@ use Chill\PersonBundle\Export\Helper\LabelPersonHelper; use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; -use const SORT_NUMERIC; class ListActivityHelper { - public const MSG_KEY = 'export.list.activity.'; - - private ActivityPresenceRepositoryInterface $activityPresenceRepository; - - private ActivityTypeRepositoryInterface $activityTypeRepository; - - private DateTimeHelper $dateTimeHelper; - - private LabelPersonHelper $labelPersonHelper; - - private LabelThirdPartyHelper $labelThirdPartyHelper; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private TranslatableStringExportLabelHelper $translatableStringLabelHelper; - - private TranslatorInterface $translator; - - private UserHelper $userHelper; + final public const MSG_KEY = 'export.list.activity.'; public function __construct( - ActivityPresenceRepositoryInterface $activityPresenceRepository, - ActivityTypeRepositoryInterface $activityTypeRepository, - DateTimeHelper $dateTimeHelper, - LabelPersonHelper $labelPersonHelper, - LabelThirdPartyHelper $labelThirdPartyHelper, - TranslatorInterface $translator, - TranslatableStringHelperInterface $translatableStringHelper, - TranslatableStringExportLabelHelper $translatableStringLabelHelper, - UserHelper $userHelper - ) { - $this->activityPresenceRepository = $activityPresenceRepository; - $this->activityTypeRepository = $activityTypeRepository; - $this->dateTimeHelper = $dateTimeHelper; - $this->labelPersonHelper = $labelPersonHelper; - $this->labelThirdPartyHelper = $labelThirdPartyHelper; - $this->translator = $translator; - $this->translatableStringHelper = $translatableStringHelper; - $this->translatableStringLabelHelper = $translatableStringLabelHelper; - $this->userHelper = $userHelper; - } + private readonly ActivityPresenceRepositoryInterface $activityPresenceRepository, + private readonly ActivityTypeRepositoryInterface $activityTypeRepository, + private readonly DateTimeHelper $dateTimeHelper, + private readonly LabelPersonHelper $labelPersonHelper, + private readonly LabelThirdPartyHelper $labelThirdPartyHelper, + private readonly TranslatorInterface $translator, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly TranslatableStringExportLabelHelper $translatableStringLabelHelper, + private readonly UserHelper $userHelper + ) {} public function addSelect(QueryBuilder $qb): void { @@ -85,7 +55,7 @@ class ListActivityHelper ->addSelect('AGGREGATE(actPerson.id) AS personsNames') ->leftJoin('activity.users', 'users_u') ->addSelect('AGGREGATE(users_u.id) AS usersIds') - ->addSelect('AGGREGATE(users_u.id) AS usersNames') + ->addSelect('AGGREGATE(JSON_BUILD_OBJECT(\'uid\', users_u.id, \'d\', activity.date)) AS usersNames') ->leftJoin('activity.thirdParties', 'thirdparty') ->addSelect('AGGREGATE(thirdparty.id) AS thirdPartiesIds') ->addSelect('AGGREGATE(thirdparty.id) AS thirdPartiesNames') @@ -96,9 +66,9 @@ class ListActivityHelper ->leftJoin('activity.location', 'location') ->addSelect('location.name AS locationName') ->addSelect('activity.sentReceived') - ->addSelect('IDENTITY(activity.createdBy) AS createdBy') + ->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.createdBy), \'d\', activity.createdAt) AS createdBy') ->addSelect('activity.createdAt') - ->addSelect('IDENTITY(activity.updatedBy) AS updatedBy') + ->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.updatedBy), \'d\', activity.updatedAt) AS updatedBy') ->addSelect('activity.updatedAt') ->addGroupBy('activity.id') ->addGroupBy('location.id'); @@ -113,113 +83,78 @@ class ListActivityHelper public function getLabels($key, array $values, $data) { - switch ($key) { - case 'createdAt': - case 'updatedAt': - return $this->dateTimeHelper->getLabel($key); + return match ($key) { + 'createdAt', 'updatedAt' => $this->dateTimeHelper->getLabel($key), + 'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, $key), + 'date' => $this->dateTimeHelper->getLabel(self::MSG_KEY.$key), + 'attendeeName' => function ($value) { + if ('_header' === $value) { + return 'Attendee'; + } - case 'createdBy': - case 'updatedBy': - return $this->userHelper->getLabel($key, $values, $key); + if (null === $value || null === $presence = $this->activityPresenceRepository->find($value)) { + return ''; + } - case 'date': - return $this->dateTimeHelper->getLabel(self::MSG_KEY . $key); + return $this->translatableStringHelper->localize($presence->getName()); + }, + 'listReasons' => $this->translatableStringLabelHelper->getLabelMulti($key, $values, 'Activity Reasons'), + 'typeName' => function ($value) { + if ('_header' === $value) { + return 'Activity type'; + } - case 'attendeeName': - return function ($value) { - if ('_header' === $value) { - return 'Attendee'; - } + if (null === $value || null === $type = $this->activityTypeRepository->find($value)) { + return ''; + } - if (null === $value || null === $presence = $this->activityPresenceRepository->find($value)) { - return ''; - } + return $this->translatableStringHelper->localize($type->getName()); + }, + 'usersNames' => $this->userHelper->getLabelMulti($key, $values, self::MSG_KEY.'users name'), + 'usersIds', 'thirdPartiesIds', 'personsIds' => static function ($value) use ($key) { + if ('_header' === $value) { + return match ($key) { + 'usersIds' => self::MSG_KEY.'users ids', + 'thirdPartiesIds' => self::MSG_KEY.'third parties ids', + 'personsIds' => self::MSG_KEY.'persons ids', + }; + } - return $this->translatableStringHelper->localize($presence->getName()); - }; + $decoded = json_decode((string) $value, null, 512, JSON_THROW_ON_ERROR); - case 'listReasons': - return $this->translatableStringLabelHelper->getLabelMulti($key, $values, 'Activity Reasons'); + return implode( + '|', + array_unique( + array_filter($decoded, static fn (?int $id) => null !== $id), + \SORT_NUMERIC + ) + ); + }, + 'personsNames' => $this->labelPersonHelper->getLabelMulti($key, $values, self::MSG_KEY.'persons name'), + 'thirdPartiesNames' => $this->labelThirdPartyHelper->getLabelMulti($key, $values, self::MSG_KEY.'thirds parties'), + 'sentReceived' => function ($value) { + if ('_header' === $value) { + return self::MSG_KEY.'sent received'; + } - case 'typeName': - return function ($value) { - if ('_header' === $value) { - return 'Activity type'; - } + if (null === $value) { + return ''; + } - if (null === $value || null === $type = $this->activityTypeRepository->find($value)) { - return ''; - } + return $this->translator->trans($value); + }, + default => function ($value) use ($key) { + if ('_header' === $value) { + return self::MSG_KEY.$key; + } - return $this->translatableStringHelper->localize($type->getName()); - }; + if (null === $value) { + return ''; + } - case 'usersNames': - return $this->userHelper->getLabelMulti($key, $values, self::MSG_KEY . 'users name'); - - case 'usersIds': - case 'thirdPartiesIds': - case 'personsIds': - return static function ($value) use ($key) { - if ('_header' === $value) { - switch ($key) { - case 'usersIds': - return self::MSG_KEY . 'users ids'; - - case 'thirdPartiesIds': - return self::MSG_KEY . 'third parties ids'; - - case 'personsIds': - return self::MSG_KEY . 'persons ids'; - - default: - throw new LogicException('key not supported'); - } - } - - $decoded = json_decode($value, null, 512, JSON_THROW_ON_ERROR); - - return implode( - '|', - array_unique( - array_filter($decoded, static fn (?int $id) => null !== $id), - SORT_NUMERIC - ) - ); - }; - - case 'personsNames': - return $this->labelPersonHelper->getLabelMulti($key, $values, self::MSG_KEY . 'persons name'); - - case 'thirdPartiesNames': - return $this->labelThirdPartyHelper->getLabelMulti($key, $values, self::MSG_KEY . 'thirds parties'); - - case 'sentReceived': - return function ($value) { - if ('_header' === $value) { - return self::MSG_KEY . 'sent received'; - } - - if (null === $value) { - return ''; - } - - return $this->translator->trans($value); - }; - - default: - return function ($value) use ($key) { - if ('_header' === $value) { - return self::MSG_KEY . $key; - } - - if (null === $value) { - return ''; - } - - return $this->translator->trans($value); - }; - } + return $this->translator->trans($value); + }, + }; } public function getQueryKeys($data) diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php index 72528170f..31a29c2eb 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php @@ -21,9 +21,6 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; -/** - * Filter accompanying period to keep only the one having at list one activity from the given ActivityType. - */ class ActivityTypeFilter implements FilterInterface { public function __construct( @@ -40,7 +37,7 @@ class ActivityTypeFilter implements FilterInterface { $qb->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . Activity::class . ' act_type_filter_activity + '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' ) ); @@ -57,13 +54,14 @@ class ActivityTypeFilter implements FilterInterface $builder->add('accepted_activitytypes', EntityType::class, [ 'class' => ActivityType::class, 'choices' => $this->activityTypeRepository->findAllActive(), - 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()).' > ' : '') . $this->translatableStringHelper->localize($aty->getName()), 'multiple' => true, 'expanded' => true, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php index 08f6bbbc3..13349baa5 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php @@ -18,16 +18,10 @@ use Chill\PersonBundle\Form\Type\PickSocialActionType; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class BySocialActionFilter implements FilterInterface { - private SocialActionRender $actionRender; - - public function __construct(SocialActionRender $actionRender) - { - $this->actionRender = $actionRender; - } + public function __construct(private readonly SocialActionRender $actionRender) {} public function addRole(): ?string { @@ -36,7 +30,7 @@ class BySocialActionFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actsocialaction', $qb->getAllAliases(), true)) { + if (!\in_array('actsocialaction', $qb->getAllAliases(), true)) { $qb->join('activity.socialActions', 'actsocialaction'); } @@ -60,6 +54,7 @@ class BySocialActionFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php index bd6e2ef4a..bef40290e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php @@ -18,16 +18,10 @@ use Chill\PersonBundle\Form\Type\PickSocialIssueType; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class BySocialIssueFilter implements FilterInterface { - private SocialIssueRender $issueRender; - - public function __construct(SocialIssueRender $issueRender) - { - $this->issueRender = $issueRender; - } + public function __construct(private readonly SocialIssueRender $issueRender) {} public function addRole(): ?string { @@ -36,7 +30,7 @@ class BySocialIssueFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actsocialissue', $qb->getAllAliases(), true)) { + if (!\in_array('actsocialissue', $qb->getAllAliases(), true)) { $qb->join('activity.socialIssues', 'actsocialissue'); } @@ -60,6 +54,7 @@ class BySocialIssueFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php index ab7331a65..afd708d33 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php @@ -18,7 +18,7 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; /** - * Filter accompanying periods to keep only the one without any activity + * Filter accompanying periods to keep only the one without any activity. */ class HasNoActivityFilter implements FilterInterface { @@ -32,7 +32,7 @@ class HasNoActivityFilter implements FilterInterface $qb ->andWhere(' NOT EXISTS ( - SELECT 1 FROM ' . Activity::class . ' activity + SELECT 1 FROM '.Activity::class.' activity WHERE activity.accompanyingPeriod = acp ) '); @@ -45,8 +45,9 @@ class HasNoActivityFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { - //no form needed + // no form needed } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php index 20d0452fa..2d3282ad1 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php @@ -34,10 +34,10 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt { $builder ->add('start_date', PickRollingDateType::class, [ - 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity after' + 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity after', ]) ->add('end_date', PickRollingDateType::class, [ - 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity before' + 'label' => 'export.filter.activity.course_having_activity_between_date.Receiving an activity before', ]); } @@ -45,7 +45,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt { return [ 'start_date' => new RollingDate(RollingDate::T_YEAR_CURRENT_START), - 'end_date' => new RollingDate(RollingDate::T_TODAY) + 'end_date' => new RollingDate(RollingDate::T_TODAY), ]; } @@ -56,7 +56,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt [ 'from' => $this->rollingDateConverter->convert($data['start_date']), 'to' => $this->rollingDateConverter->convert($data['end_date']), - ] + ], ]; } @@ -73,7 +73,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt $qb->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . Activity::class . " {$alias} WHERE {$alias}.date >= :{$from} AND {$alias}.date < :{$to} AND {$alias}.accompanyingPeriod = acp" + 'SELECT 1 FROM '.Activity::class." {$alias} WHERE {$alias}.date >= :{$from} AND {$alias}.date < :{$to} AND {$alias}.accompanyingPeriod = acp" ) ); diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php index e582acc12..a67d0155d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php @@ -27,17 +27,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ActivityDateFilter implements FilterInterface { - protected TranslatorInterface $translator; - - private RollingDateConverterInterface $rollingDateConverter; - - public function __construct( - TranslatorInterface $translator, - RollingDateConverterInterface $rollingDateConverter - ) { - $this->translator = $translator; - $this->rollingDateConverter = $rollingDateConverter; - } + public function __construct(protected TranslatorInterface $translator, private readonly RollingDateConverterInterface $rollingDateConverter) {} public function addRole(): ?string { @@ -100,14 +90,14 @@ class ActivityDateFilter implements FilterInterface if (null === $date_from) { $form->get('date_from')->addError(new FormError( $this->translator->trans('This field ' - . 'should not be empty') + .'should not be empty') )); } if (null === $date_to) { $form->get('date_to')->addError(new FormError( $this->translator->trans('This field ' - . 'should not be empty') + .'should not be empty') )); } @@ -118,13 +108,14 @@ class ActivityDateFilter implements FilterInterface ) { $form->get('date_to')->addError(new FormError( $this->translator->trans('This date should be after ' - . 'the date given in "Implied in an activity after ' - . 'this date" field') + .'the date given in "Implied in an activity after ' + .'this date" field') )); } } }); } + public function getFormDefaultData(): array { return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php index 8dfcb543c..43f9ba0da 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php @@ -22,21 +22,12 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use function count; - class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInterface { - protected ActivityTypeRepositoryInterface $activityTypeRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - public function __construct( - TranslatableStringHelperInterface $translatableStringHelper, - ActivityTypeRepositoryInterface $activityTypeRepository - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->activityTypeRepository = $activityTypeRepository; - } + protected TranslatableStringHelperInterface $translatableStringHelper, + protected ActivityTypeRepositoryInterface $activityTypeRepository + ) {} public function addRole(): ?string { @@ -61,7 +52,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter $builder->add('types', EntityType::class, [ 'choices' => $this->activityTypeRepository->findAllActive(), 'class' => ActivityType::class, - 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()) . ' > ' : '') + 'choice_label' => fn (ActivityType $aty) => ($aty->hasCategory() ? $this->translatableStringHelper->localize($aty->getCategory()->getName()).' > ' : '') . $this->translatableStringHelper->localize($aty->getName()), 'group_by' => function (ActivityType $type) { @@ -78,6 +69,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter ], ]); } + public function getFormDefaultData(): array { return []; @@ -103,7 +95,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter public function validateForm($data, ExecutionContextInterface $context) { - if (null === $data['types'] || count($data['types']) === 0) { + if (null === $data['types'] || 0 === \count($data['types'])) { $context ->buildViolation('At least one type must be chosen') ->addViolation(); diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php index a63ca2629..56285c026 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php @@ -20,12 +20,7 @@ use Symfony\Component\Form\FormBuilderInterface; class ActivityUsersFilter implements FilterInterface { - private UserRender $userRender; - - public function __construct(UserRender $userRender) - { - $this->userRender = $userRender; - } + public function __construct(private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -37,8 +32,8 @@ class ActivityUsersFilter implements FilterInterface $orX = $qb->expr()->orX(); foreach ($data['accepted_users'] as $key => $user) { - $orX->add($qb->expr()->isMemberOf(':activity_users_filter_u' . $key, 'activity.users')); - $qb->setParameter('activity_users_filter_u' . $key, $user); + $orX->add($qb->expr()->isMemberOf(':activity_users_filter_u'.$key, 'activity.users')); + $qb->setParameter('activity_users_filter_u'.$key, $user); } $qb->andWhere($orX); @@ -56,6 +51,7 @@ class ActivityUsersFilter implements FilterInterface 'label' => 'Users', ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ByCreatorFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ByCreatorFilter.php index 4c1e13f10..f75c5a817 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ByCreatorFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ByCreatorFilter.php @@ -20,12 +20,7 @@ use Symfony\Component\Form\FormBuilderInterface; class ByCreatorFilter implements FilterInterface { - private UserRender $userRender; - - public function __construct(UserRender $userRender) - { - $this->userRender = $userRender; - } + public function __construct(private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -52,6 +47,7 @@ class ByCreatorFilter implements FilterInterface 'multiple' => true, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/EmergencyFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/EmergencyFilter.php index 47fb3b027..b74be2552 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/EmergencyFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/EmergencyFilter.php @@ -28,12 +28,7 @@ class EmergencyFilter implements FilterInterface private const DEFAULT_CHOICE = 'false'; - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } + public function __construct(private readonly TranslatorInterface $translator) {} public function addRole(): ?string { @@ -70,6 +65,7 @@ class EmergencyFilter implements FilterInterface 'empty_data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array { return ['accepted_emergency' => self::DEFAULT_CHOICE]; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/LocationFilter.php index f5c7b4d16..77b4ce20d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/LocationFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/LocationFilter.php @@ -14,7 +14,6 @@ namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\PickUserLocationType; -use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -46,6 +45,7 @@ class LocationFilter implements FilterInterface 'label' => 'pick location', ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php index bff5a0491..771dfca30 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php @@ -18,16 +18,10 @@ use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class LocationTypeFilter implements FilterInterface { - private TranslatableStringHelper $translatableStringHelper; - - public function __construct(TranslatableStringHelper $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {} public function addRole(): ?string { @@ -36,7 +30,7 @@ class LocationTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actloc', $qb->getAllAliases(), true)) { + if (!\in_array('actloc', $qb->getAllAliases(), true)) { $qb->join('activity.location', 'actloc'); } @@ -62,9 +56,10 @@ class LocationTypeFilter implements FilterInterface { $builder->add('accepted_locationtype', PickLocationTypeType::class, [ 'multiple' => true, - //'label' => false, + // 'label' => false, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php index 31cfde6b6..3f71add31 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php @@ -17,29 +17,15 @@ use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use function count; -use function in_array; - class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInterface { - protected ActivityReasonRepository $activityReasonRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct( - TranslatableStringHelper $helper, - ActivityReasonRepository $activityReasonRepository - ) { - $this->translatableStringHelper = $helper; - $this->activityReasonRepository = $activityReasonRepository; - } + public function __construct(protected TranslatableStringHelper $translatableStringHelper, protected ActivityReasonRepository $activityReasonRepository) {} public function addRole(): ?string { @@ -52,7 +38,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt $join = $qb->getDQLPart('join'); $clause = $qb->expr()->in('actreasons', ':selected_activity_reasons'); - if (!in_array('actreasons', $qb->getAllAliases(), true)) { + if (!\in_array('actreasons', $qb->getAllAliases(), true)) { $qb->join('activity.reasons', 'actreasons'); } @@ -82,6 +68,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt 'expanded' => false, ]); } + public function getFormDefaultData(): array { return []; @@ -91,7 +78,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt { // collect all the reasons'name used in this filter in one array $reasonsNames = array_map( - fn (ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"', + fn (ActivityReason $r): string => '"'.$this->translatableStringHelper->localize($r->getName()).'"', $this->activityReasonRepository->findBy(['id' => $data['reasons']->toArray()]) ); @@ -110,7 +97,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt public function validateForm($data, ExecutionContextInterface $context) { - if (null === $data['reasons'] || count($data['reasons']) === 0) { + if (null === $data['reasons'] || 0 === \count($data['reasons'])) { $context ->buildViolation('At least one reason must be chosen') ->addViolation(); diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php index bd010e1ff..eb2312c0e 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilter.php @@ -16,46 +16,23 @@ use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\FilterInterface; -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 Chill\MainBundle\Templating\TranslatableStringHelper; -use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Export\Declarations; -use DateTime; -use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; -use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormError; -use Symfony\Component\Form\FormEvent; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\FormInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Contracts\Translation\TranslatorInterface; -use function count; - -class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInterface, FilterInterface +final readonly class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInterface, FilterInterface { - protected ActivityReasonRepository $activityReasonRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - - protected TranslatorInterface $translator; - public function __construct( - TranslatableStringHelper $translatableStringHelper, - ActivityReasonRepository $activityReasonRepository, - TranslatorInterface $translator, - private readonly RollingDateConverterInterface $rollingDateConverter, - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->activityReasonRepository = $activityReasonRepository; - $this->translator = $translator; - } + private TranslatableStringHelper $translatableStringHelper, + private ActivityReasonRepository $activityReasonRepository, + private RollingDateConverterInterface $rollingDateConverter, + ) {} public function addRole(): ?string { @@ -72,11 +49,11 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt // add clause between date $sqb->where('activity_person_having_activity.date BETWEEN ' - . ':person_having_activity_between_date_from' - . ' AND ' - . ':person_having_activity_between_date_to' - . ' AND ' - . '(person_person_having_activity.id = person.id OR person MEMBER OF activity_person_having_activity.persons)'); + .':person_having_activity_between_date_from' + .' AND ' + .':person_having_activity_between_date_to' + .' AND ' + .'(person_person_having_activity.id = person.id OR person MEMBER OF activity_person_having_activity.persons)'); if (isset($data['reasons']) && [] !== $data['reasons']) { // add clause activity reason @@ -134,6 +111,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt ]); } } + public function getFormDefaultData(): array { return [ @@ -155,7 +133,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt 'reasons' => implode( ', ', array_map( - fn (ActivityReason $r): string => '"' . $this->translatableStringHelper->localize($r->getName()) . '"', + fn (ActivityReason $r): string => '"'.$this->translatableStringHelper->localize($r->getName()).'"', $data['reasons'] ) ), diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/SentReceivedFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/SentReceivedFilter.php index 8d1e8baf0..640f33592 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/SentReceivedFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/SentReceivedFilter.php @@ -29,12 +29,7 @@ class SentReceivedFilter implements FilterInterface private const DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT; - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } + public function __construct(private readonly TranslatorInterface $translator) {} public function addRole(): ?string { @@ -71,6 +66,7 @@ class SentReceivedFilter implements FilterInterface 'empty_data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array { return ['accepted_sentreceived' => self::DEFAULT_CHOICE]; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UserFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UserFilter.php index c32b60f96..6e6b745b9 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UserFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UserFilter.php @@ -21,12 +21,7 @@ use Symfony\Component\Form\FormBuilderInterface; class UserFilter implements FilterInterface { - private UserRender $userRender; - - public function __construct(UserRender $userRender) - { - $this->userRender = $userRender; - } + public function __construct(private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -61,6 +56,7 @@ class UserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UserScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UserScopeFilter.php index d29dea970..d205e2d30 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UserScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UserScopeFilter.php @@ -13,22 +13,21 @@ namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\Query\Expr\Andx; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class UserScopeFilter implements FilterInterface { - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'acp_act_filter_user_scope'; // creator ? cfr translation - public function __construct(TranslatableStringHelper $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -37,22 +36,33 @@ class UserScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('actuser', $qb->getAllAliases(), true)) { - $qb->join('activity.user', 'actuser'); - } + $p = self::PREFIX; - $where = $qb->getDQLPart('where'); - - $clause = $qb->expr()->in('actuser.mainScope', ':userscope'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('userscope', $data['accepted_userscope']); + $qb + ->leftJoin('activity.user', "{$p}_user") // createdBy ? cfr translation + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // scope_at based on activity.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'activity.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'activity.date') + ) + ) + ) + ->andWhere( + $qb->expr()->in("{$p}_history.scope", ":{$p}_scopes") + ) + ->setParameter( + "{$p}_scopes", + $data['scopes'], + ); } public function applyOn(): string @@ -62,37 +72,41 @@ class UserScopeFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('accepted_userscope', EntityType::class, [ - 'class' => Scope::class, - 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( - $s->getName() - ), - 'multiple' => true, - 'expanded' => true, - ]); - } - public function getFormDefaultData(): array - { - return []; + $builder + ->add('scopes', EntityType::class, [ + 'class' => Scope::class, + 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( + $s->getName() + ), + 'multiple' => true, + 'expanded' => true, + ]); } public function describeAction($data, $format = 'string'): array { $scopes = []; - foreach ($data['accepted_userscope'] as $s) { + foreach ($data['scopes'] as $s) { $scopes[] = $this->translatableStringHelper->localize( $s->getName() ); } - return ['Filtered activity by userscope: only %scopes%', [ + return ['export.filter.activity.by_creator_scope.Filtered activity by user scope: only %scopes%', [ '%scopes%' => implode(', ', $scopes), ]]; } + public function getFormDefaultData(): array + { + return [ + 'scopes' => [], + ]; + } + public function getTitle(): string { - return 'Filter activity by userscope'; + return 'export.filter.activity.by_creator_scope.Filter activity by user scope'; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php index e85b2d247..b65994b9d 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php @@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; @@ -22,12 +23,11 @@ use Symfony\Component\Form\FormBuilderInterface; class UsersJobFilter implements FilterInterface { - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'act_filter_user_job'; - public function __construct(TranslatableStringHelperInterface $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -36,14 +36,25 @@ class UsersJobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { + $p = self::PREFIX; + $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . Activity::class . ' activity_users_job_filter_act - JOIN activity_users_job_filter_act.users users WHERE users.userJob IN (:activity_users_job_filter_jobs) AND activity_users_job_filter_act = activity ' + 'SELECT 1 FROM '.Activity::class." {$p}_act " + ."JOIN {$p}_act.users {$p}_user " + .'JOIN '.UserJobHistory::class." {$p}_history WITH {$p}_history.user = {$p}_user " + ."WHERE {$p}_act = activity " + // job_at based on activity.date + ."AND {$p}_history.startDate <= activity.date " + ."AND ({$p}_history.endDate IS NULL OR {$p}_history.endDate > activity.date) " + ."AND {$p}_history.job IN ( :{$p}_jobs )" ) ) - ->setParameter('activity_users_job_filter_jobs', $data['jobs']); + ->setParameter( + "{$p}_jobs", + $data['jobs'] + ); } public function applyOn() @@ -53,21 +64,18 @@ class UsersJobFilter implements FilterInterface 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 getFormDefaultData(): array - { - return []; + $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.activity.by_usersjob.Filtered activity by users job: only %jobs%', [ + return ['export.filter.activity.by_users_job.Filtered activity by users job: only %jobs%', [ '%jobs%' => implode( ', ', array_map( @@ -78,8 +86,15 @@ class UsersJobFilter implements FilterInterface ]]; } + public function getFormDefaultData(): array + { + return [ + 'jobs' => [], + ]; + } + public function getTitle() { - return 'export.filter.activity.by_usersjob.Filter by users job'; + return 'export.filter.activity.by_users_job.Filter by users job'; } } diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php index 07ff509ce..4c4a83c20 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php @@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Declarations; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; @@ -23,17 +24,12 @@ use Symfony\Component\Form\FormBuilderInterface; class UsersScopeFilter implements FilterInterface { - private ScopeRepositoryInterface $scopeRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'act_filter_user_scope'; public function __construct( - ScopeRepositoryInterface $scopeRepository, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly ScopeRepositoryInterface $scopeRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -42,39 +38,47 @@ class UsersScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { + $p = self::PREFIX; + $qb ->andWhere( $qb->expr()->exists( - 'SELECT 1 FROM ' . Activity::class . ' activity_users_scope_filter_act - JOIN activity_users_scope_filter_act.users users WHERE users.mainScope IN (:activity_users_scope_filter_scopes) AND activity_users_scope_filter_act = activity ' + 'SELECT 1 FROM '.Activity::class." {$p}_act " + ."JOIN {$p}_act.users {$p}_user " + .'JOIN '.UserScopeHistory::class." {$p}_history WITH {$p}_history.user = {$p}_user " + ."WHERE {$p}_act = activity " + // scope_at based on activity.date + ."AND {$p}_history.startDate <= activity.date " + ."AND ({$p}_history.endDate IS NULL OR {$p}_history.endDate > activity.date) " + ."AND {$p}_history.scope IN ( :{$p}_scopes )" ) ) - ->setParameter('activity_users_scope_filter_scopes', $data['scopes']); + ->setParameter( + "{$p}_scopes", + $data['scopes'] + ); } - public function applyOn() + public function applyOn(): string { return Declarations::ACTIVITY; } 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 getFormDefaultData(): array - { - return []; + $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') + public function describeAction($data, $format = 'string'): array { - return ['export.filter.activity.by_usersscope.Filtered activity by users scope: only %scopes%', [ + return ['export.filter.activity.by_users_scope.Filtered activity by users scope: only %scopes%', [ '%scopes%' => implode( ', ', array_map( @@ -85,8 +89,15 @@ class UsersScopeFilter implements FilterInterface ]]; } - public function getTitle() + public function getFormDefaultData(): array { - return 'export.filter.activity.by_usersscope.Filter by users scope'; + return [ + 'scopes' => [], + ]; + } + + public function getTitle(): string + { + return 'export.filter.activity.by_users_scope.Filter by users scope'; } } diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityType.php b/src/Bundle/ChillActivityBundle/Form/ActivityType.php index a74178afd..8ea117c4a 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityType.php @@ -34,12 +34,8 @@ use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; use Chill\ThirdPartyBundle\Entity\ThirdParty; -use DateInterval; -use DateTime; -use DateTimeZone; use Doctrine\ORM\EntityRepository; use Doctrine\Persistence\ObjectManager; -use RuntimeException; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; @@ -53,45 +49,24 @@ use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Role\Role; -use function in_array; - class ActivityType extends AbstractType { - protected AuthorizationHelper $authorizationHelper; - - protected ObjectManager $om; - - protected SocialActionRender $socialActionRender; - - protected SocialIssueRender $socialIssueRender; - - protected array $timeChoices; - - protected TranslatableStringHelper $translatableStringHelper; - protected User $user; public function __construct( TokenStorageInterface $tokenStorage, - AuthorizationHelper $authorizationHelper, - ObjectManager $om, - TranslatableStringHelper $translatableStringHelper, - array $timeChoices, - SocialIssueRender $socialIssueRender, - SocialActionRender $socialActionRender + protected AuthorizationHelper $authorizationHelper, + protected ObjectManager $om, + protected TranslatableStringHelper $translatableStringHelper, + protected array $timeChoices, + protected SocialIssueRender $socialIssueRender, + protected SocialActionRender $socialActionRender ) { if (!$tokenStorage->getToken()->getUser() instanceof User) { - throw new RuntimeException('you should have a valid user'); + throw new \RuntimeException('you should have a valid user'); } $this->user = $tokenStorage->getToken()->getUser(); - $this->authorizationHelper = $authorizationHelper; - $this->om = $om; - $this->translatableStringHelper = $translatableStringHelper; - $this->timeChoices = $timeChoices; - $this->socialIssueRender = $socialIssueRender; - $this->socialActionRender = $socialActionRender; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -121,16 +96,16 @@ class ActivityType extends AbstractType ]); } - /** @var ? \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingPeriod */ + /** @var \Chill\PersonBundle\Entity\AccompanyingPeriod|null $accompanyingPeriod */ $accompanyingPeriod = null; if ($options['accompanyingPeriod'] instanceof AccompanyingPeriod) { $accompanyingPeriod = $options['accompanyingPeriod']; } - if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) { + if ($activityType->isVisible('socialIssues') && null !== $accompanyingPeriod) { $builder->add('socialIssues', HiddenType::class, [ - 'required' => $activityType->getSocialIssuesVisible() === 2, + 'required' => 2 === $activityType->getSocialIssuesVisible(), ]); $builder->get('socialIssues') ->addModelTransformer(new CallbackTransformer( @@ -156,9 +131,9 @@ class ActivityType extends AbstractType )); } - if ($activityType->isVisible('socialActions') && $accompanyingPeriod) { + if ($activityType->isVisible('socialActions') && null !== $accompanyingPeriod) { $builder->add('socialActions', HiddenType::class, [ - 'required' => $activityType->getSocialActionsVisible() === 2, + 'required' => 2 === $activityType->getSocialActionsVisible(), ]); $builder->get('socialActions') ->addModelTransformer(new CallbackTransformer( @@ -342,7 +317,7 @@ class ActivityType extends AbstractType if ($activityType->isVisible('location')) { $builder->add('location', HiddenType::class, [ - 'required' => $activityType->getLocationVisible() === 2, + 'required' => 2 === $activityType->getLocationVisible(), ]) ->get('location') ->addModelTransformer(new CallbackTransformer( @@ -393,16 +368,16 @@ class ActivityType extends AbstractType ) { // set the timezone to GMT, and fix the difference between current and GMT // the datetimetransformer will then handle timezone as GMT - $timezoneUTC = new DateTimeZone('GMT'); - /** @var DateTime $data */ - $data = $formEvent->getData() ?? DateTime::createFromFormat('U', '300'); + $timezoneUTC = new \DateTimeZone('GMT'); + /** @var \DateTime $data */ + $data = $formEvent->getData() ?? \DateTime::createFromFormat('U', '300'); $seconds = $data->getTimezone()->getOffset($data); $data->setTimeZone($timezoneUTC); - $data->add(new DateInterval('PT' . $seconds . 'S')); + $data->add(new \DateInterval('PT'.$seconds.'S')); // test if the timestamp is in the choices. // If not, recreate the field with the new timestamp - if (!in_array($data->getTimestamp(), $timeChoices, true)) { + if (!\in_array($data->getTimestamp(), $timeChoices, true)) { // the data are not in the possible values. add them $timeChoices[$data->format('H:i')] = $data->getTimestamp(); $form = $builder->create($fieldName, ChoiceType::class, array_merge( @@ -428,7 +403,7 @@ class ActivityType extends AbstractType $resolver ->setRequired(['center', 'role', 'activityType', 'accompanyingPeriod']) ->setAllowedTypes('center', ['null', Center::class]) - ->setAllowedTypes('role', [Role::class, 'string']) + ->setAllowedTypes('role', ['string']) ->setAllowedTypes('activityType', \Chill\ActivityBundle\Entity\ActivityType::class) ->setAllowedTypes('accompanyingPeriod', [\Chill\PersonBundle\Entity\AccompanyingPeriod::class, 'null']); } diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php index 073b8099f..8e8ae51f7 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityTypeType.php @@ -25,12 +25,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class ActivityTypeType extends AbstractType { - private TranslatableStringHelper $translatableStringHelper; - - public function __construct(TranslatableStringHelper $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -61,8 +56,8 @@ class ActivityTypeType extends AbstractType foreach ($fields as $field) { $builder - ->add($field . 'Visible', ActivityFieldPresence::class) - ->add($field . 'Label', TextType::class, [ + ->add($field.'Visible', ActivityFieldPresence::class) + ->add($field.'Label', TextType::class, [ 'required' => false, 'empty_data' => '', ]); diff --git a/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php b/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php index 35da7e02f..be1e372f1 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/PickActivityReasonType.php @@ -24,21 +24,11 @@ use Symfony\Component\OptionsResolver\OptionsResolver; */ class PickActivityReasonType extends AbstractType { - private ActivityReasonRepository $activityReasonRepository; - - private ActivityReasonRender $reasonRender; - - private TranslatableStringHelperInterface $translatableStringHelper; - public function __construct( - ActivityReasonRepository $activityReasonRepository, - ActivityReasonRender $reasonRender, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->activityReasonRepository = $activityReasonRepository; - $this->reasonRender = $reasonRender; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly ActivityReasonRepository $activityReasonRepository, + private readonly ActivityReasonRender $reasonRender, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function configureOptions(OptionsResolver $resolver) { diff --git a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php index 4aa259097..ee1417bfb 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityReasonCategoryType.php @@ -23,15 +23,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class TranslatableActivityReasonCategoryType extends AbstractType { - private TranslatableStringHelperInterface $translatableStringHelper; - - private TranslatorInterface $translator; - - public function __construct(TranslatableStringHelperInterface $translatableStringHelper, TranslatorInterface $translator) - { - $this->translatableStringHelper = $translatableStringHelper; - $this->translator = $translator; - } + public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {} public function configureOptions(OptionsResolver $resolver) { @@ -39,16 +31,11 @@ class TranslatableActivityReasonCategoryType extends AbstractType [ 'class' => ActivityReasonCategory::class, 'choice_label' => fn (ActivityReasonCategory $category) => $this->translatableStringHelper->localize($category->getName()) - . (!$category->getActive() ? ' (' . $this->translator->trans('inactive') . ')' : ''), + .(!$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 d4807b82d..5c77e500d 100644 --- a/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/Type/TranslatableActivityType.php @@ -20,17 +20,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class TranslatableActivityType extends AbstractType { - protected ActivityTypeRepositoryInterface $activityTypeRepository; - - protected TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct( - TranslatableStringHelperInterface $helper, - ActivityTypeRepositoryInterface $activityTypeRepository - ) { - $this->translatableStringHelper = $helper; - $this->activityTypeRepository = $activityTypeRepository; - } + public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, protected ActivityTypeRepositoryInterface $activityTypeRepository) {} public function configureOptions(OptionsResolver $resolver) { diff --git a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php index 9884450ec..b4990c0e3 100644 --- a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -23,17 +23,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface { - protected Security $security; - - protected TranslatorInterface $translator; - - public function __construct( - Security $security, - TranslatorInterface $translator - ) { - $this->security = $security; - $this->translator = $translator; - } + public function __construct(protected Security $security, protected TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php index 4b2d348d7..0afe11cfc 100644 --- a/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php @@ -18,14 +18,9 @@ use Symfony\Component\Security\Core\Security; /** * @implements LocalMenuBuilderInterface */ -final class AdminMenuBuilder implements LocalMenuBuilderInterface +final readonly class AdminMenuBuilder implements LocalMenuBuilderInterface { - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; - } + public function __construct(private Security $security) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php index a3cebec38..e76aaf5ee 100644 --- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php @@ -21,25 +21,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; /** * @implements LocalMenuBuilderInterface */ -final class PersonMenuBuilder implements LocalMenuBuilderInterface +final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface { - /** - * @var AuthorizationCheckerInterface - */ - private $authorizationChecker; - - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct( - AuthorizationCheckerInterface $authorizationChecker, - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->authorizationChecker = $authorizationChecker; - } + public function __construct(private AuthorizationCheckerInterface $authorizationChecker, private TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationHandler.php b/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationHandler.php index ab26da81d..8eb219fd2 100644 --- a/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationHandler.php +++ b/src/Bundle/ChillActivityBundle/Notification/ActivityNotificationHandler.php @@ -16,14 +16,9 @@ use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Notification\NotificationHandlerInterface; -final class ActivityNotificationHandler implements NotificationHandlerInterface +final readonly class ActivityNotificationHandler implements NotificationHandlerInterface { - private ActivityRepository $activityRepository; - - public function __construct(ActivityRepository $activityRepository) - { - $this->activityRepository = $activityRepository; - } + public function __construct(private ActivityRepository $activityRepository) {} public function getTemplate(Notification $notification, array $options = []): string { @@ -40,6 +35,6 @@ final class ActivityNotificationHandler implements NotificationHandlerInterface public function supports(Notification $notification, array $options = []): bool { - return $notification->getRelatedEntityClass() === Activity::class; + return Activity::class === $notification->getRelatedEntityClass(); } } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php index f9db5c158..231ad5432 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php @@ -35,9 +35,6 @@ use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Security; -use function count; -use function in_array; - final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface { public function __construct( @@ -75,7 +72,6 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos return $qb->getQuery()->getSingleScalarResult(); } - public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array { $qb = $this->buildBaseQuery($filters); @@ -83,7 +79,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb->andWhere('a.accompanyingPeriod = :period')->setParameter('period', $period); foreach ($orderBy as $field => $order) { - $qb->addOrderBy('a.' . $field, $order); + $qb->addOrderBy('a.'.$field, $order); } if (null !== $start) { @@ -122,9 +118,30 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos ->leftJoin('a.user', 'activity_u') ->andWhere( $qb->expr()->orX( - 'creator.userJob IN (:jobs)', - 'activity_u.userJob IN (:jobs)', - 'EXISTS (SELECT 1 FROM ' . User::class . ' activity_user WHERE activity_user MEMBER OF a.users AND activity_user.userJob IN (:jobs))' + $qb->expr()->exists( + sprintf( + 'SELECT 1 FROM %s ujh_creator WHERE ujh_creator.user = a.createdBy ' + .'AND ujh_creator.job IN (:jobs) AND a.createdAt > ujh_creator.startDate ' + .'AND (ujh_creator.endDate IS NULL or ujh_creator.endDate > a.date)', + User\UserJobHistory::class + ) + ), + $qb->expr()->exists( + sprintf( + 'SELECT 1 FROM %s ujh_u WHERE ujh_u.user = a.user ' + .'AND ujh_u.job IN (:jobs) AND a.createdAt > ujh_u.startDate ' + .'AND (ujh_u.endDate IS NULL or ujh_u.endDate > a.date)', + User\UserJobHistory::class + ) + ), + $qb->expr()->exists( + sprintf( + 'SELECT 1 FROM %s ujh_users WHERE ujh_users.user MEMBER OF a.users ' + .'AND ujh_users.job IN (:jobs) AND a.createdAt > ujh_users.startDate ' + .'AND (ujh_users.endDate IS NULL or ujh_users.endDate > a.date)', + User\UserJobHistory::class + ) + ), ) ) ->setParameter('jobs', $jobs); @@ -142,7 +159,6 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos } /** - * @param AccompanyingPeriod|Person $associated * @return array */ public function findActivityTypeByAssociated(AccompanyingPeriod|Person $associated): array @@ -172,16 +188,17 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos return $qb->getQuery()->getResult(); } - public function findUserJobByAssociated(Person|AccompanyingPeriod $associated): array + public function findUserJobByAssociated(AccompanyingPeriod|Person $associated): array { $in = $this->em->createQueryBuilder(); - $in->select('IDENTITY(u.userJob)') - ->from(User::class, 'u') + $in->select('IDENTITY(u.job)') + ->distinct() + ->from(User\UserJobHistory::class, 'u') ->join( Activity::class, 'a', Join::WITH, - 'a.createdBy = u OR a.user = u OR u MEMBER OF a.users' + 'a.createdBy = u.user OR a.user = u.user OR u.user MEMBER OF a.users AND a.date >= u.startDate ANd (u.endDate IS NULL or u.endDate > a.date)' ); if ($associated instanceof Person) { @@ -203,7 +220,6 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos return $qb->getQuery()->getResult(); } - public function findByAccompanyingPeriodSimplified(AccompanyingPeriod $period, ?int $limit = 1000): array { $rsm = new ResultSetMappingBuilder($this->em); @@ -291,7 +307,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb = $this->filterBaseQueryByPerson($qb, $person, $role); foreach ($orderBy as $field => $direction) { - $qb->addOrderBy('a.' . $field, $direction); + $qb->addOrderBy('a.'.$field, $direction); } if (null !== $start) { @@ -318,7 +334,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $orX->add(sprintf('a.person = :person AND a.scope IN (:scopes_%d)', $counter)); $qb->setParameter(sprintf('scopes_%d', $counter), $scopes); $qb->setParameter('person', $person); - $counter++; + ++$counter; } foreach ($person->getAccompanyingPeriodParticipations() as $participation) { @@ -341,7 +357,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos ->setParameter(sprintf('participation_end_%d', $counter), $participation->getEndDate()); } $orX->add($and); - $counter++; + ++$counter; } if (0 === $orX->count()) { @@ -362,10 +378,10 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos return [ 'id' => $metadataActivity->getTableName() - . '.' . $metadataActivity->getColumnName('id'), + .'.'.$metadataActivity->getColumnName('id'), 'type' => 'activity', 'date' => $metadataActivity->getTableName() - . '.' . $metadataActivity->getColumnName('date'), + .'.'.$metadataActivity->getColumnName('date'), 'FROM' => $from, 'WHERE' => $where, 'parameters' => $parameters, @@ -378,12 +394,12 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $metadataPerson = $this->em->getClassMetadata(Person::class); $associationMapping = $metadataActivity->getAssociationMapping('person'); - return $metadataActivity->getTableName() . ' JOIN ' - . $metadataPerson->getTableName() . ' ON ' - . $metadataPerson->getTableName() . '.' . + return $metadataActivity->getTableName().' JOIN ' + .$metadataPerson->getTableName().' ON ' + .$metadataPerson->getTableName().'.'. $associationMapping['joinColumns'][0]['referencedColumnName'] - . ' = ' - . $associationMapping['joinColumns'][0]['name']; + .' = ' + .$associationMapping['joinColumns'][0]['name']; } private function getWhereClause(string $context, array $args): array @@ -402,7 +418,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos ActivityVoter::SEE ); - if (count($reachableCenters) === 0) { + if (0 === \count($reachableCenters)) { // insert a dummy condition return 'FALSE = TRUE'; } @@ -419,7 +435,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos foreach ($reachableCenters as $center) { // we pass if not in centers - if (!in_array($center, $args['centers'], true)) { + if (!\in_array($center, $args['centers'], true)) { continue; } // we get all the reachable scopes for this center @@ -441,7 +457,7 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos // begin loop for scopes $where .= ' AND ('; - $scopesI = 0; //like scope#i + $scopesI = 0; // like scope#i foreach ($reachablesScopesId as $scopeId) { if (0 < $scopesI) { diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php index 474d8ad16..7c51afd63 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php @@ -22,8 +22,8 @@ interface ActivityACLAwareRepositoryInterface /** * Return all the activities associated to an accompanying period and that the user is allowed to apply the given role. * - * * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + * * @return array */ public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; @@ -49,20 +49,20 @@ interface ActivityACLAwareRepositoryInterface /** * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + * * @return array */ public function findByPerson(Person $person, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; - /** - * Return a list of the type for the activities associated to person or accompanying period + * Return a list of the type for the activities associated to person or accompanying period. * * @return array */ public function findActivityTypeByAssociated(AccompanyingPeriod|Person $associated): array; /** - * Return a list of the user job for the activities associated to person or accompanying period + * Return a list of the user job for the activities associated to person or accompanying period. * * Associated mean the job: * - of the creator; diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php index 9cc57f93f..99e75f2da 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepository.php @@ -15,25 +15,15 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Service\GenericDoc\Providers\AccompanyingPeriodActivityGenericDocProvider; use Chill\ActivityBundle\Service\GenericDoc\Providers\PersonActivityGenericDocProvider; -use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; -use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider; -use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface; -use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; -use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\MappingException; -use Doctrine\ORM\QueryBuilder; -use Symfony\Component\HttpKernel\HttpCache\Store; use Symfony\Component\Security\Core\Security; final readonly class ActivityDocumentACLAwareRepository implements ActivityDocumentACLAwareRepositoryInterface @@ -45,14 +35,14 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum private Security $security ) {} - public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface + public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQueryInterface { $query = $this->buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext($person, $startDate, $endDate, $content); return $this->addFetchQueryByPersonACL($query, $person); } - public function buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + public function buildBaseFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); @@ -81,7 +71,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum return $this->addWhereClauses($query, $startDate, $endDate, $content); } - public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); @@ -116,8 +106,8 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum $storedObjectMetadata->getColumnName('createdAt') ); $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), - DateTimeImmutable::createFromInterface($participation->getStartDate()), - null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + \DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : \DateTimeImmutable::createFromInterface($participation->getEndDate())]; $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; } @@ -132,7 +122,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum return $this->addWhereClauses($query, $startDate, $endDate, $content); } - private function addWhereClauses(FetchQuery $query, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + private function addWhereClauses(FetchQuery $query, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -155,7 +145,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum if (null !== $content and '' !== $content) { $query->addWhereClause( 'stored_obj.title ilike ?', - ['%' . $content . '%'], + ['%'.$content.'%'], [Types::STRING] ); } @@ -172,7 +162,7 @@ final readonly class ActivityDocumentACLAwareRepository implements ActivityDocum foreach ($this->centerResolverManager->resolveCenters($person) as $center) { $reachableScopes = [ ...$reachableScopes, - ...$this->authorizationHelperForCurrentUser->getReachableScopes(ActivityVoter::SEE, $center) + ...$this->authorizationHelperForCurrentUser->getReachableScopes(ActivityVoter::SEE, $center), ]; } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php index 9f4a9c0f8..dcd45c016 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityDocumentACLAwareRepositoryInterface.php @@ -14,24 +14,23 @@ namespace Chill\ActivityBundle\Repository; use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; /** - * Gives queries usable for fetching documents, with ACL aware + * Gives queries usable for fetching documents, with ACL aware. */ interface ActivityDocumentACLAwareRepositoryInterface { /** - * Return a fetch query for querying document's activities for a person + * Return a fetch query for querying document's activities for a person. * * This method must check the rights to see a document: the user must be allowed to see the given activities */ - public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQueryInterface; + public function buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQueryInterface; /** - * Return a fetch query for querying document's activities for an activity in accompanying periods, but for a given person + * Return a fetch query for querying document's activities for an activity in accompanying periods, but for a given person. * * This method must check the rights to see a document: the user must be allowed to see the given accompanying periods */ - public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery; + public function buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery; } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepository.php index 2cf9f9470..ae3296e7f 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepository.php @@ -17,7 +17,7 @@ use Doctrine\ORM\EntityRepository; class ActivityPresenceRepository implements ActivityPresenceRepositoryInterface { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -34,7 +34,7 @@ class ActivityPresenceRepository implements ActivityPresenceRepositoryInterface return $this->repository->findAll(); } - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepositoryInterface.php index 228d70856..d2daa1d5d 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityPresenceRepositoryInterface.php @@ -25,7 +25,7 @@ interface ActivityPresenceRepositoryInterface /** * @return array|ActivityPresence[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array; + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array; public function findOneBy(array $criteria): ?ActivityPresence; diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php index c6b69319e..47a7b35e8 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityReasonRepository.php @@ -23,15 +23,11 @@ use Symfony\Component\HttpFoundation\RequestStack; */ class ActivityReasonRepository extends ServiceEntityRepository { - private RequestStack $requestStack; - public function __construct( ManagerRegistry $registry, - RequestStack $requestStack + private readonly RequestStack $requestStack ) { parent::__construct($registry, ActivityReason::class); - - $this->requestStack = $requestStack; } /** diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php index 5a6e16cd5..a7025d4a9 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityRepository.php @@ -62,7 +62,7 @@ class ActivityRepository extends ServiceEntityRepository ->setParameter('period', $period); foreach ($orderBy as $k => $dir) { - $qb->addOrderBy('a.' . $k, $dir); + $qb->addOrderBy('a.'.$k, $dir); } $qb->setMaxResults($limit)->setFirstResult($offset); @@ -90,7 +90,7 @@ class ActivityRepository extends ServiceEntityRepository ->setParameter('person', $person); foreach ($orderBy as $k => $dir) { - $qb->addOrderBy('a.' . $k, $dir); + $qb->addOrderBy('a.'.$k, $dir); } $qb->setMaxResults($limit)->setFirstResult($offset); diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php index 10bd1e651..6f7453a74 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php @@ -11,17 +11,13 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; -use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; -use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Chill\PersonBundle\Entity\Person; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; -use Doctrine\ORM\Query\Expr\Join; final class ActivityTypeRepository implements ActivityTypeRepositoryInterface { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $em) { @@ -52,7 +48,7 @@ final class ActivityTypeRepository implements ActivityTypeRepositoryInterface /** * @return array|ActivityType[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php index 574faea22..899535ad6 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepositoryInterface.php @@ -12,8 +12,6 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Repository; use Chill\ActivityBundle\Entity\ActivityType; -use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Chill\PersonBundle\Entity\Person; use Doctrine\Persistence\ObjectRepository; interface ActivityTypeRepositoryInterface extends ObjectRepository 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 8d1aba2b3..b3382c3de 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/_list_item.html.twig @@ -75,7 +75,7 @@ {% endif %} - {% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with { + {% include '@ChillActivity/Activity/concernedGroups.html.twig' with { 'context': context, 'render': 'wrap-list', 'entity': activity, diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/editAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/editAccompanyingCourse.html.twig index d0359e223..3cf476bbb 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/editAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/editAccompanyingCourse.html.twig @@ -8,7 +8,7 @@
{# <=== vue component #} - {% include 'ChillActivityBundle:Activity:edit.html.twig' %} + {% include '@ChillActivity/Activity/edit.html.twig' %}
{% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/editPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/editPerson.html.twig index 91b3867c1..73eec5f62 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/editPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/editPerson.html.twig @@ -24,7 +24,7 @@
{# <=== vue component #} - {% include 'ChillActivityBundle:Activity:edit.html.twig' %} + {% include '@ChillActivity/Activity/edit.html.twig' %}
{% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig index dd78c9396..fde256af0 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig @@ -91,7 +91,7 @@
{% for activity in activities %} - {% include 'ChillActivityBundle:Activity:_list_item.html.twig' with { + {% include '@ChillActivity/Activity/_list_item.html.twig' with { 'context': context, 'recordAction': _self.recordAction(activity, context, person_id, accompanying_course_id) } %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig index bdf55d86f..e2710ea43 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listAccompanyingCourse.html.twig @@ -31,7 +31,7 @@

{{ 'Activity list' |trans }}

- {% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillActivity/Activity/list.html.twig' with {'context': 'accompanyingCourse'} %} {% if is_granted('CHILL_ACTIVITY_CREATE', accompanyingCourse) %}
    diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig index 0c1afdac9..5870f124f 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/listPerson.html.twig @@ -46,7 +46,7 @@

    {{ 'Activity list' |trans }}

    - {% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %} + {% include '@ChillActivity/Activity/list.html.twig' with {'context': 'person'} %} {% if is_granted('CHILL_ACTIVITY_CREATE', person) %}
      diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig index 47a61bd86..0b098dffe 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newAccompanyingCourse.html.twig @@ -8,7 +8,7 @@
      {# <=== vue component #} - {% include 'ChillActivityBundle:Activity:new.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillActivity/Activity/new.html.twig' with {'context': 'accompanyingCourse'} %}
      {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newPerson.html.twig index d57fc3412..dd0b91ccb 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/newPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/newPerson.html.twig @@ -8,7 +8,7 @@
      {# <=== vue component #} - {% include 'ChillActivityBundle:Activity:new.html.twig' with {'context': 'person'} %} + {% include '@ChillActivity/Activity/new.html.twig' with {'context': 'person'} %}
      {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypeAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypeAccompanyingCourse.html.twig index 5e73db597..4bc26baea 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypeAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypeAccompanyingCourse.html.twig @@ -5,5 +5,5 @@ {% block title 'Activity creation'|trans %} {% block content %} - {% include 'ChillActivityBundle:Activity:selectType.html.twig' %} + {% include '@ChillActivity/Activity/selectType.html.twig' %} {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypePerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypePerson.html.twig index f616012e4..c3815f79d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypePerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/selectTypePerson.html.twig @@ -5,5 +5,5 @@ {% block title 'Activity creation'|trans %} {% block content %} - {% include 'ChillActivityBundle:Activity:selectType.html.twig' %} + {% include '@ChillActivity/Activity/selectType.html.twig' %} {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig index fca6a7658..d4beb606a 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig @@ -88,7 +88,7 @@

      {{ 'Concerned groups'|trans }}

      -{% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with { +{% include '@ChillActivity/Activity/concernedGroups.html.twig' with { 'context': context, 'render': 'bloc', 'badge_person': true diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig index 3486f47bc..de471a9ab 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showAccompanyingCourse.html.twig @@ -18,11 +18,11 @@ {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} -{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %} +{% import '@ChillActivity/ActivityReason/macro.html.twig' as m %} {% block content -%}
      - {% include 'ChillActivityBundle:Activity:show.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillActivity/Activity/show.html.twig' with {'context': 'accompanyingCourse'} %}
      {% endblock content %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showInNotification.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showInNotification.html.twig index 721538271..36ba70c7b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showInNotification.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showInNotification.html.twig @@ -8,7 +8,7 @@ {% if activity is not null %}
      {% if is_granted('CHILL_ACTIVITY_SEE', activity) %} - {% include 'ChillActivityBundle:Activity:_list_item.html.twig' with { + {% include '@ChillActivity/Activity/_list_item.html.twig' with { 'recordAction': _self.recordAction(activity), 'context': 'accompanyingCourse', 'itemBlocClass': 'bg-chill-llight-gray' diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig index 43a8eb86b..39daee516 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/showPerson.html.twig @@ -16,11 +16,11 @@ {{ encore_entry_link_tags('mod_document_action_buttons_group') }} {% endblock %} -{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %} +{% import '@ChillActivity/ActivityReason/macro.html.twig' as m %} {% block content -%}
      - {% include 'ChillActivityBundle:Activity:show.html.twig' with {'context': 'person'} %} + {% include '@ChillActivity/Activity/show.html.twig' with {'context': 'person'} %}
      {% endblock %} diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Timeline/activity_person_context.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Timeline/activity_person_context.html.twig index 435be1958..3979be2f3 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Timeline/activity_person_context.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Timeline/activity_person_context.html.twig @@ -1,4 +1,4 @@ -{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %} +{% import '@ChillActivity/ActivityReason/macro.html.twig' as m %}

      {{ activity.date|format_date('long') }} / {{ 'Activity'|trans }}{% if 'person' != context %} / {{ activity.person|chill_entity_render_box({'addLink': true}) }}{% endif %}

      diff --git a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php index 2e55f862c..27f4b07a6 100644 --- a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php +++ b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityStatsVoter.php @@ -20,9 +20,9 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const LISTS = 'CHILL_ACTIVITY_LIST'; + final public const LISTS = 'CHILL_ACTIVITY_LIST'; - public const STATS = 'CHILL_ACTIVITY_STATS'; + final public const STATS = 'CHILL_ACTIVITY_STATS'; protected VoterHelperInterface $helper; diff --git a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php index 15d2441d5..bf2ed78a0 100644 --- a/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php +++ b/src/Bundle/ChillActivityBundle/Security/Authorization/ActivityVoter.php @@ -21,12 +21,9 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter; -use RuntimeException; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security; -use function in_array; - class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { /** @@ -35,7 +32,7 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn * * It is safe for usage in template and controller */ - public const CREATE = 'CHILL_ACTIVITY_CREATE'; + final public const CREATE = 'CHILL_ACTIVITY_CREATE'; /** * role to allow to create an activity associated win an accompanying course. @@ -44,7 +41,7 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn * * @internal */ - public const CREATE_ACCOMPANYING_COURSE = 'CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE'; + final public const CREATE_ACCOMPANYING_COURSE = 'CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE'; /** * role to allow to create an activity associated with a person. @@ -53,17 +50,17 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn * * @internal */ - public const CREATE_PERSON = 'CHILL_ACTIVITY_CREATE_PERSON'; + final public const CREATE_PERSON = 'CHILL_ACTIVITY_CREATE_PERSON'; - public const DELETE = 'CHILL_ACTIVITY_DELETE'; + final public const DELETE = 'CHILL_ACTIVITY_DELETE'; - public const FULL = 'CHILL_ACTIVITY_FULL'; + final public const FULL = 'CHILL_ACTIVITY_FULL'; - public const SEE = 'CHILL_ACTIVITY_SEE'; + final public const SEE = 'CHILL_ACTIVITY_SEE'; - public const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS'; + final public const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS'; - public const UPDATE = 'CHILL_ACTIVITY_UPDATE'; + final public const UPDATE = 'CHILL_ACTIVITY_UPDATE'; private const ALL = [ self::CREATE, @@ -74,15 +71,12 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn self::FULL, ]; - protected Security $security; - protected VoterHelperInterface $voterHelper; public function __construct( - Security $security, + protected Security $security, VoterHelperFactoryInterface $voterHelperFactory ) { - $this->security = $security; $this->voterHelper = $voterHelperFactory->generate(self::class) ->addCheckFor(Person::class, [self::SEE, self::CREATE]) ->addCheckFor(AccompanyingPeriod::class, [self::SEE, self::CREATE]) @@ -148,11 +142,11 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn return $this->voterHelper->voteOnAttribute(self::CREATE_ACCOMPANYING_COURSE, $subject->getAccompanyingPeriod(), $token); } } else { - throw new RuntimeException('Could not determine context of activity.'); + throw new \RuntimeException('Could not determine context of activity.'); } } elseif ($subject instanceof AccompanyingPeriod) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { - if (in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) { + if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) { return false; } } diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php index a20ca365b..46e466ae1 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ActivityContext.php @@ -18,7 +18,6 @@ use Chill\DocGeneratorBundle\Context\Exception\UnexpectedTypeException; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\DocGeneratorBundle\Service\Context\BaseContextData; use Chill\DocStoreBundle\Entity\StoredObject; -use Chill\DocStoreBundle\Repository\DocumentCategoryRepository; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; @@ -42,49 +41,17 @@ class ActivityContext implements DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface { - private BaseContextData $baseContextData; - - private DocumentCategoryRepository $documentCategoryRepository; - - private EntityManagerInterface $em; - - private NormalizerInterface $normalizer; - - private PersonRenderInterface $personRender; - - private PersonRepository $personRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private TranslatorInterface $translator; - - private ThirdPartyRender $thirdPartyRender; - - private ThirdPartyRepository $thirdPartyRepository; - public function __construct( - DocumentCategoryRepository $documentCategoryRepository, - NormalizerInterface $normalizer, - TranslatableStringHelperInterface $translatableStringHelper, - EntityManagerInterface $em, - PersonRenderInterface $personRender, - PersonRepository $personRepository, - TranslatorInterface $translator, - BaseContextData $baseContextData, - ThirdPartyRender $thirdPartyRender, - ThirdPartyRepository $thirdPartyRepository - ) { - $this->documentCategoryRepository = $documentCategoryRepository; - $this->normalizer = $normalizer; - $this->translatableStringHelper = $translatableStringHelper; - $this->em = $em; - $this->personRender = $personRender; - $this->personRepository = $personRepository; - $this->translator = $translator; - $this->baseContextData = $baseContextData; - $this->thirdPartyRender = $thirdPartyRender; - $this->thirdPartyRepository = $thirdPartyRepository; - } + private readonly NormalizerInterface $normalizer, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly EntityManagerInterface $em, + private readonly PersonRenderInterface $personRender, + private readonly PersonRepository $personRepository, + private readonly TranslatorInterface $translator, + private readonly BaseContextData $baseContextData, + private readonly ThirdPartyRender $thirdPartyRender, + private readonly ThirdPartyRepository $thirdPartyRepository + ) {} public function adminFormReverseTransform(array $data): array { @@ -159,7 +126,7 @@ class ActivityContext implements 'multiple' => false, 'required' => false, 'expanded' => true, - 'label' => $options[$key . 'Label'], + 'label' => $options[$key.'Label'], 'placeholder' => $this->translator->trans('Any person selected'), ]); } @@ -242,7 +209,7 @@ class ActivityContext implements if ($options['thirdParty']) { $data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [ 'docgen:expects' => ThirdParty::class, - 'groups' => 'docgen:read' + 'groups' => 'docgen:read', ]); } @@ -285,7 +252,7 @@ class ActivityContext implements { $options = $template->getOptions(); - return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options ['thirdParty']; + return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options['thirdParty']; } public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void diff --git a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php index 045d09beb..221d1f4b2 100644 --- a/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php +++ b/src/Bundle/ChillActivityBundle/Service/DocGenerator/ListActivitiesByAccompanyingPeriodContext.php @@ -32,13 +32,11 @@ use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext; 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 @@ -48,45 +46,17 @@ class ListActivitiesByAccompanyingPeriodContext implements DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface { - private AccompanyingPeriodContext $accompanyingPeriodContext; - - private ActivityACLAwareRepositoryInterface $activityACLAwareRepository; - - private NormalizerInterface $normalizer; - - private PersonRepository $personRepository; - - private SocialActionRepository $socialActionRepository; - - private SocialIssueRepository $socialIssueRepository; - - private ThirdPartyRepository $thirdPartyRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private UserRepository $userRepository; - public function __construct( - AccompanyingPeriodContext $accompanyingPeriodContext, - ActivityACLAwareRepositoryInterface $activityACLAwareRepository, - NormalizerInterface $normalizer, - PersonRepository $personRepository, - SocialActionRepository $socialActionRepository, - SocialIssueRepository $socialIssueRepository, - ThirdPartyRepository $thirdPartyRepository, - TranslatableStringHelperInterface $translatableStringHelper, - UserRepository $userRepository, - ) { - $this->accompanyingPeriodContext = $accompanyingPeriodContext; - $this->activityACLAwareRepository = $activityACLAwareRepository; - $this->normalizer = $normalizer; - $this->personRepository = $personRepository; - $this->socialActionRepository = $socialActionRepository; - $this->socialIssueRepository = $socialIssueRepository; - $this->thirdPartyRepository = $thirdPartyRepository; - $this->translatableStringHelper = $translatableStringHelper; - $this->userRepository = $userRepository; - } + private readonly AccompanyingPeriodContext $accompanyingPeriodContext, + private readonly ActivityACLAwareRepositoryInterface $activityACLAwareRepository, + private readonly NormalizerInterface $normalizer, + private readonly PersonRepository $personRepository, + private readonly SocialActionRepository $socialActionRepository, + private readonly SocialIssueRepository $socialIssueRepository, + private readonly ThirdPartyRepository $thirdPartyRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly UserRepository $userRepository + ) {} public function adminFormReverseTransform(array $data): array { @@ -150,7 +120,8 @@ class ListActivitiesByAccompanyingPeriodContext implements $activities, function ($activity) use ($user) { $activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []); - return in_array($user->getUsername(), $activityUsernames, true); + + return \in_array($user->getUsername(), $activityUsernames, true); } ) ); @@ -167,7 +138,7 @@ class ListActivitiesByAccompanyingPeriodContext implements function ($work) use ($user) { $workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []); - return in_array($user->getUsername(), $workUsernames, true); + return \in_array($user->getUsername(), $workUsernames, true); } ) ); @@ -191,6 +162,7 @@ class ListActivitiesByAccompanyingPeriodContext implements if ($myWorksOnly && isset($contextGenerationData['creator'])) { $data['course']['works'] = $this->filterWorksByUser($data['course']['works'], $contextGenerationData['creator']); } + return $data; } @@ -244,7 +216,7 @@ class ListActivitiesByAccompanyingPeriodContext implements $activity = $row[0]; $activity['date'] = $this->normalizer->normalize($activity['date'], 'docgen', [ - AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => DateTime::class, + AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => \DateTime::class, ]); if (null === $activity['location']) { @@ -257,8 +229,8 @@ class ListActivitiesByAccompanyingPeriodContext implements $activity['location']['type'] = 'location'; foreach (['1', '2'] as $key) { - $activity['location']['phonenumber' . $key] = $this->normalizer->normalize( - $activity['location']['phonenumber' . $key], + $activity['location']['phonenumber'.$key] = $this->normalizer->normalize( + $activity['location']['phonenumber'.$key], 'docgen', [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => PhoneNumber::class] ); diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php index 05be52e25..2c6c9a691 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/AccompanyingPeriodActivityGenericDocProvider.php @@ -22,13 +22,11 @@ use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\MappingException; use Symfony\Component\Security\Core\Security; -final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface +final readonly class AccompanyingPeriodActivityGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface { public const KEY = 'accompanying_period_activity_document'; @@ -38,7 +36,7 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo private ActivityDocumentACLAwareRepositoryInterface $activityDocumentACLAwareRepository, ) {} - public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); $activityMetadata = $this->em->getClassMetadata(Activity::class); @@ -83,7 +81,7 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo if (null !== $content) { $query->addWhereClause( 'doc_obj.title ilike ?', - ['%' . $content . '%'], + ['%'.$content.'%'], [Types::STRING] ); } @@ -91,10 +89,6 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo return $query; } - /** - * @param AccompanyingPeriod $accompanyingPeriod - * @return bool - */ public function isAllowedForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool { return $this->security->isGranted(ActivityVoter::SEE, $accompanyingPeriod); @@ -105,7 +99,7 @@ final class AccompanyingPeriodActivityGenericDocProvider implements GenericDocFo return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); } - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForPerson(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { return $this->activityDocumentACLAwareRepository ->buildFetchQueryActivityDocumentLinkedToAccompanyingPeriodFromPersonContext($person, $startDate, $endDate, $content); diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php index f4a7c4afa..b84345375 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Providers/PersonActivityGenericDocProvider.php @@ -11,15 +11,11 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Service\GenericDoc\Providers; -use Chill\ActivityBundle\Repository\ActivityDocumentACLAwareRepository; use Chill\ActivityBundle\Repository\ActivityDocumentACLAwareRepositoryInterface; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; -use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; -use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Security; final readonly class PersonActivityGenericDocProvider implements GenericDocForPersonProviderInterface @@ -27,11 +23,11 @@ final readonly class PersonActivityGenericDocProvider implements GenericDocForPe public const KEY = 'person_activity_document'; public function __construct( - private Security $security, + private Security $security, private ActivityDocumentACLAwareRepositoryInterface $personActivityDocumentACLAwareRepository, ) {} - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForPerson(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { return $this->personActivityDocumentACLAwareRepository->buildFetchQueryActivityDocumentLinkedToPersonFromPersonContext( $person, @@ -41,10 +37,6 @@ final readonly class PersonActivityGenericDocProvider implements GenericDocForPe ); } - /** - * @param Person $person - * @return bool - */ public function isAllowedForPerson(Person $person): bool { return $this->security->isGranted(ActivityVoter::SEE, $person); diff --git a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php index c465dbca1..93649cea8 100644 --- a/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php +++ b/src/Bundle/ChillActivityBundle/Service/GenericDoc/Renderers/AccompanyingPeriodActivityGenericDocRenderer.php @@ -17,23 +17,14 @@ use Chill\ActivityBundle\Service\GenericDoc\Providers\PersonActivityGenericDocPr use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; use Chill\DocStoreBundle\Repository\StoredObjectRepository; -use Chill\PersonBundle\Entity\AccompanyingPeriod; -final class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRendererInterface +final readonly class AccompanyingPeriodActivityGenericDocRenderer implements GenericDocRendererInterface { - private StoredObjectRepository $objectRepository; - - private ActivityRepository $activityRepository; - - public function __construct(StoredObjectRepository $storedObjectRepository, ActivityRepository $activityRepository) - { - $this->objectRepository = $storedObjectRepository; - $this->activityRepository = $activityRepository; - } + public function __construct(private StoredObjectRepository $objectRepository, private ActivityRepository $activityRepository) {} public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingPeriodActivityGenericDocProvider::KEY || $genericDocDTO->key === PersonActivityGenericDocProvider::KEY; + return AccompanyingPeriodActivityGenericDocProvider::KEY === $genericDocDTO->key || PersonActivityGenericDocProvider::KEY === $genericDocDTO->key; } public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string diff --git a/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php b/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php index c60a8d286..aa7783d2d 100644 --- a/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php +++ b/src/Bundle/ChillActivityBundle/Templating/Entity/ActivityReasonRender.php @@ -12,7 +12,6 @@ declare(strict_types=1); 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; @@ -38,21 +37,21 @@ class ActivityReasonRender implements ChillEntityRenderInterface public function renderBox($entity, array $options): string { return - $this->getDefaultOpeningBox('activity-reason') . - '' . - ' ' . - '' . + $this->getDefaultOpeningBox('activity-reason'). + ''. + ' '. + ''. $this->translatableStringHelper->localize( $entity->getCategory()->getName() - ) . - '' . - ' > ' . - '' . + ). + ''. + ' > '. + ''. $this->translatableStringHelper->localize( $entity->getName() - ) . - '' . - '' . + ). + ''. + ''. $this->getDefaultClosingBox(); } @@ -63,10 +62,10 @@ class ActivityReasonRender implements ChillEntityRenderInterface if (null !== $entity->getCategory()) { $category = $this->translatableStringHelper->localize( $entity->getCategory()->getName() - ) . ' > '; + ).' > '; } - return $category . + return $category. $this->translatableStringHelper->localize( $entity->getName() ); diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php index 04301afae..38aa49cdf 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php @@ -12,14 +12,12 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Controller; use Chill\ActivityBundle\Entity\ActivityType; -use RuntimeException; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Security\Core\Role\Role; -use function count; -use function in_array; /** * @internal + * * @coversNothing */ final class ActivityControllerTest extends WebTestCase @@ -76,10 +74,8 @@ final class ActivityControllerTest extends WebTestCase /** * @dataProvider getSecuredPagesUnauthenticated - * - * @param mixed $url */ - public function testAccessIsDeniedForUnauthenticated($url) + public function testAccessIsDeniedForUnauthenticated(mixed $url) { $client = $this->createClient(); @@ -194,7 +190,7 @@ final class ActivityControllerTest extends WebTestCase $crawler = $client->followRedirect(); - $this->assertNotContains('January 25, 2015', $crawler->text()); + $this->assertStringNotContainsString('January 25, 2015', $crawler->text()); } /** @@ -208,19 +204,19 @@ final class ActivityControllerTest extends WebTestCase $container = self::$kernel->getContainer(); $em = $container->get('doctrine.orm.entity_manager'); - //get the social PermissionGroup, and remove CHILL_ACTIVITY_* + // get the social PermissionGroup, and remove CHILL_ACTIVITY_* $socialPermissionGroup = $em ->getRepository(\Chill\MainBundle\Entity\PermissionsGroup::class) ->findOneByName('social'); $withoutActivityPermissionGroup = (new \Chill\MainBundle\Entity\PermissionsGroup()) ->setName('social without activity'); - //copy role scopes where ACTIVITY is not present + // copy role scopes where ACTIVITY is not present foreach ($socialPermissionGroup->getRoleScopes() as $roleScope) { - if (!strpos($roleScope->getRole(), 'ACTIVITY')) { + if (!strpos((string) $roleScope->getRole(), 'ACTIVITY')) { $withoutActivityPermissionGroup->addRoleScope($roleScope); } } - //create groupCenter + // create groupCenter $groupCenter = new \Chill\MainBundle\Entity\GroupCenter(); $groupCenter->setCenter($em->getRepository(\Chill\MainBundle\Entity\Center::class) ->findOneBy(['name' => 'Center A'])) @@ -228,7 +224,7 @@ final class ActivityControllerTest extends WebTestCase $em->persist($withoutActivityPermissionGroup); $em->persist($groupCenter); - //create user + // create user $faker = \Faker\Factory::create(); $username = $faker->name; $user = new \Chill\MainBundle\Entity\User(); @@ -253,20 +249,17 @@ final class ActivityControllerTest extends WebTestCase $activities = $em->getRepository(\Chill\ActivityBundle\Entity\Activity::class) ->findBy(['person' => $person]); - if (count($activities) === 0) { - throw new RuntimeException('We need activities associated with this ' - . 'person. Did you forget to add fixtures ?'); + if (0 === \count($activities)) { + throw new \RuntimeException('We need activities associated with this person. Did you forget to add fixtures ?'); } return $activities; } /** - * @param mixed $username - * - * @return \Symfony\Component\BrowserKit\Client + * @return \Symfony\Component\BrowserKit\AbstractBrowser */ - private function getAuthenticatedClient($username = 'center a_social') + private function getAuthenticatedClient(mixed $username = 'center a_social') { return self::createClient([], [ 'PHP_AUTH_USER' => $username, @@ -289,8 +282,7 @@ final class ActivityControllerTest extends WebTestCase ]); if (null === $person) { - throw new RuntimeException('We need a person with firstname Gérard and' - . ' lastname Depardieu. Did you add fixtures ?'); + throw new \RuntimeException('We need a person with firstname Gérard and lastname Depardieu. Did you add fixtures ?'); } return $person; @@ -310,7 +302,7 @@ final class ActivityControllerTest extends WebTestCase $reason = $reasons[array_rand($reasons)]; - if (in_array($reason->getId(), $excludeIds, true)) { + if (\in_array($reason->getId(), $excludeIds, true)) { return $this->getRandomActivityReason($excludeIds); } @@ -344,8 +336,7 @@ final class ActivityControllerTest extends WebTestCase ->findOneByUsername($username); if (null === $user) { - throw new RuntimeException("The user with username {$username} " - . 'does not exists in database. Did you add fixtures ?'); + throw new \RuntimeException("The user with username {$username} ".'does not exists in database. Did you add fixtures ?'); } $center = self::$kernel->getContainer() @@ -358,14 +349,14 @@ final class ActivityControllerTest extends WebTestCase ->get('chill.main.security.authorization.helper') ->getReachableScopes( $user, - new Role('CHILL_ACTIVITY_UPDATE'), + 'CHILL_ACTIVITY_UPDATE', $center ); $reachableScopesDelete = self::$kernel->getContainer() ->get('chill.main.security.authorization.helper') ->getReachableScopes( $user, - new Role('CHILL_ACTIVITY_DELETE'), + 'CHILL_ACTIVITY_DELETE', $center ); $reachableScopesId = array_intersect( @@ -373,13 +364,12 @@ final class ActivityControllerTest extends WebTestCase array_map(static fn ($s) => $s->getId(), $reachableScopesUpdate) ); - if (count($reachableScopesId) === 0) { - throw new RuntimeException('there are not scope reachable for ' - . 'both CHILL_ACTIVITY_UPDATE and CHILL_ACTIVITY_DELETE'); + if (0 === \count($reachableScopesId)) { + throw new \RuntimeException('there are not scope reachable for both CHILL_ACTIVITY_UPDATE and CHILL_ACTIVITY_DELETE'); } foreach ($reachableScopesUpdate as $scope) { - if (in_array($scope->getId(), $reachableScopesId, true)) { + if (\in_array($scope->getId(), $reachableScopesId, true)) { $reachableScopes[] = $scope; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonCategoryControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonCategoryControllerTest.php index 14f75e863..81378b5ef 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonCategoryControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonCategoryControllerTest.php @@ -15,11 +15,15 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * @internal + * * @coversNothing */ final class ActivityReasonCategoryControllerTest extends WebTestCase { - public function testToWrite() + /** + * @doesNotPerformAssertions + */ + public function testToWrite(): never { $this->markTestSkipped(); } diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonControllerTest.php index 47de677a3..ce37d3fb7 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityReasonControllerTest.php @@ -15,11 +15,15 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * @internal + * * @coversNothing */ final class ActivityReasonControllerTest extends WebTestCase { - public function testToWrite() + /** + * @doesNotPerformAssertions + */ + public function testToWrite(): never { $this->markTestSkipped(); } diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityTypeControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityTypeControllerTest.php index b2276f427..23de2d17c 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityTypeControllerTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityTypeControllerTest.php @@ -15,11 +15,15 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * @internal + * * @coversNothing */ final class ActivityTypeControllerTest extends WebTestCase { - public function testToWrite() + /** + * @doesNotPerformAssertions + */ + public function testToWrite(): never { $this->markTestSkipped(); } diff --git a/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php index 3d91c3da9..6610b64ff 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php @@ -22,6 +22,7 @@ use Prophecy\PhpUnit\ProphecyTrait; /** * @internal + * * @coversNothing */ final class ActivityTest extends TestCase diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php index 6f5af8982..6cb0eb299 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialActionAggregatorTest.php @@ -12,12 +12,13 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators; use Chill\ActivityBundle\Entity\Activity; -use Chill\ActivityBundle\Export\Aggregator\BySocialActionAggregator; +use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialActionAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class BySocialActionAggregatorTest extends AbstractAggregatorTest @@ -45,9 +46,7 @@ final class BySocialActionAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -55,8 +54,8 @@ final class BySocialActionAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.socialActions', 'actsocialaction'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.socialActions', 'actsocialaction'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php index 19d29141b..583e950a6 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ACPAggregators/BySocialIssueAggregatorTest.php @@ -12,12 +12,13 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator\ACPAggregators; use Chill\ActivityBundle\Entity\Activity; -use Chill\ActivityBundle\Export\Aggregator\BySocialIssueAggregator; +use Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialIssueAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class BySocialIssueAggregatorTest extends AbstractAggregatorTest @@ -45,18 +46,16 @@ final class BySocialIssueAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() - ->select('count(activity.id)') + ->select('count(activity)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.socialIssues', 'actsocialissue'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.socialIssues', 'actsocialissue'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php index 31633b9a3..bb0906be6 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityTypeAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Doctrine\ORM\EntityManagerInterface; @@ -20,6 +21,7 @@ use Prophecy\PhpUnit\ProphecyTrait; * Add tests for ActivityTypeAggregator. * * @internal + * * @coversNothing */ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest @@ -32,7 +34,7 @@ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest { self::bootKernel(); - $this->aggregator = self::$container->get('chill.activity.export.type_aggregator'); + $this->aggregator = self::$container->get(ActivityTypeAggregator::class); $request = $this->prophesize() ->willExtend(\Symfony\Component\HttpFoundation\Request::class); @@ -57,19 +59,17 @@ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders() { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity'), + ->from(Activity::class, 'activity'), $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity') + ->from(Activity::class, 'activity') ->join('activity.activityType', 'acttype'), ]; } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php index 06542aa41..0cd7fe14d 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ActivityUserAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Doctrine\ORM\EntityManagerInterface; @@ -20,6 +21,7 @@ use Prophecy\PhpUnit\ProphecyTrait; * Add tests for ActivityUsernAggregator. * * @internal + * * @coversNothing */ final class ActivityUserAggregatorTest extends AbstractAggregatorTest @@ -57,16 +59,14 @@ final class ActivityUserAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity'), + ->from(Activity::class, 'activity'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByThirdpartyAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByThirdpartyAggregatorTest.php index 44d0ec497..0558c3f2b 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByThirdpartyAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByThirdpartyAggregatorTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ByThirdpartyAggregatorTest extends AbstractAggregatorTest @@ -45,9 +46,7 @@ final class ByThirdpartyAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -55,8 +54,8 @@ final class ByThirdpartyAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.thirdParties', 'acttparty'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.thirdParties', 'acttparty'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByUserAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByUserAggregatorTest.php index f256bde53..3e8359ab8 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByUserAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/ByUserAggregatorTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ByUserAggregatorTest extends AbstractAggregatorTest @@ -28,7 +29,7 @@ final class ByUserAggregatorTest extends AbstractAggregatorTest { self::bootKernel(); - $this->aggregator = self::$container->get('chill.activity.export.byuser_aggregator'); + $this->aggregator = self::$container->get(ByCreatorAggregator::class); } public function getAggregator() @@ -45,9 +46,7 @@ final class ByUserAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -55,8 +54,8 @@ final class ByUserAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.users', 'actusers'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.users', 'actusers'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/CreatorScopeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/CreatorScopeAggregatorTest.php index da3d1c871..49c1d746f 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/CreatorScopeAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/CreatorScopeAggregatorTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class CreatorScopeAggregatorTest extends AbstractAggregatorTest @@ -28,7 +29,7 @@ final class CreatorScopeAggregatorTest extends AbstractAggregatorTest { self::bootKernel(); - $this->aggregator = self::$container->get('chill.activity.export.userscope_aggregator'); + $this->aggregator = self::$container->get(CreatorScopeAggregator::class); } public function getAggregator() @@ -45,9 +46,7 @@ final class CreatorScopeAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -55,8 +54,8 @@ final class CreatorScopeAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.user', 'actuser'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.user', 'actuser'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/DateAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/DateAggregatorTest.php index 44ff0529b..db3a3ff76 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/DateAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/DateAggregatorTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class DateAggregatorTest extends AbstractAggregatorTest @@ -53,9 +54,7 @@ final class DateAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -63,7 +62,7 @@ final class DateAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp'), + ->leftJoin('activity.accompanyingPeriod', 'acp'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/JobScopeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/JobScopeAggregatorTest.php new file mode 100644 index 000000000..69d511ace --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/JobScopeAggregatorTest.php @@ -0,0 +1,61 @@ +aggregator = self::$container->get(JobScopeAggregator::class); + } + + public function getAggregator() + { + return $this->aggregator; + } + + public function getFormData(): array + { + return [ + [], + ]; + } + + public function getQueryBuilders(): array + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.user', 'actuser'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php index c4641bd4c..663901edd 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class LocationTypeAggregatorTest extends AbstractAggregatorTest @@ -45,9 +46,7 @@ final class LocationTypeAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); @@ -55,8 +54,8 @@ final class LocationTypeAggregatorTest extends AbstractAggregatorTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.accompanyingPeriod', 'acp') - ->join('activity.location', 'actloc'), + ->leftJoin('activity.accompanyingPeriod', 'acp') + ->leftJoin('activity.location', 'actloc'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php index 0a61e983f..004de0b99 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Aggregator/PersonAggregators/ActivityReasonAggregatorTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Aggregator\PersonAggregators; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator; use Chill\MainBundle\Test\Export\AbstractAggregatorTest; use Doctrine\ORM\EntityManagerInterface; @@ -18,6 +19,7 @@ use Prophecy\PhpUnit\ProphecyTrait; /** * @internal + * * @coversNothing */ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest @@ -30,7 +32,7 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest { self::bootKernel(); - $this->aggregator = self::$container->get('chill.activity.export.reason_aggregator'); + $this->aggregator = self::$container->get(ActivityReasonAggregator::class); $request = $this->prophesize() ->willExtend(\Symfony\Component\HttpFoundation\Request::class); @@ -56,23 +58,21 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity'), + ->from(Activity::class, 'activity'), $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity') + ->from(Activity::class, 'activity') ->join('activity.reasons', 'actreasons'), $em->createQueryBuilder() ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity') + ->from(Activity::class, 'activity') ->join('activity.reasons', 'actreasons') ->join('actreasons.category', 'actreasoncat'), ]; diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityDurationTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityDurationTest.php index 2eb2176b0..5f9b635ee 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityDurationTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityDurationTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class AvgActivityDurationTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityVisitDurationTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityVisitDurationTest.php index 59b4384cf..b15462912 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityVisitDurationTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/AvgActivityVisitDurationTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class AvgActivityVisitDurationTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountActivityTest.php index f03bbb956..46279ebd8 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountActivityTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/CountActivityTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class CountActivityTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityDurationTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityDurationTest.php index 24a5133b6..c4f91f52e 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityDurationTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityDurationTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class SumActivityDurationTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityVisitDurationTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityVisitDurationTest.php index 1940140ac..6bd7e9d19 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityVisitDurationTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToACP/SumActivityVisitDurationTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class SumActivityVisitDurationTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/CountActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/CountActivityTest.php index 864ff55ba..61ae15604 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/CountActivityTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/CountActivityTest.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; /** * @internal + * * @coversNothing */ final class CountActivityTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/ListActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/ListActivityTest.php index afa3da111..f474b1fe6 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/ListActivityTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/ListActivityTest.php @@ -17,6 +17,7 @@ use Prophecy\PhpUnit\ProphecyTrait; /** * @internal + * * @coversNothing */ final class ListActivityTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/StatActivityDurationTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/StatActivityDurationTest.php index 44d327ffd..11fb84a9a 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/StatActivityDurationTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Export/LinkedToPerson/StatActivityDurationTest.php @@ -18,6 +18,7 @@ use Chill\MainBundle\Test\Export\AbstractExportTest; * Test the "sum" part of StatActivityDuration. * * @internal + * * @coversNothing */ final class StatActivityDurationTest extends AbstractExportTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php index 3ed453f69..347d7466f 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ActivityTypeFilterTest.php @@ -13,7 +13,6 @@ namespace Chill\ActivityBundle\Tests\Export\Filter\ACPFilters; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; -use Chill\ActivityBundle\Export\Filter\ActivityTypeFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\Common\Collections\ArrayCollection; @@ -22,6 +21,7 @@ use Doctrine\ORM\Query\Expr; /** * @internal + * * @coversNothing */ final class ActivityTypeFilterTest extends AbstractFilterTest @@ -42,6 +42,7 @@ final class ActivityTypeFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() @@ -64,9 +65,7 @@ final class ActivityTypeFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByCreatorFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByCreatorFilterTest.php new file mode 100644 index 000000000..0b0c1f029 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/ByCreatorFilterTest.php @@ -0,0 +1,77 @@ +filter = self::$container->get(ByCreatorFilter::class); + } + + public function getFilter() + { + return $this->filter; + } + + public function getFormData(): array + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $array = $em->createQueryBuilder() + ->from(User::class, 'u') + ->select('u') + ->getQuery() + ->setMaxResults(2) + ->getResult(); + + $data = []; + + foreach ($array as $a) { + $data[] = [ + 'accepted_users' => $a, + ]; + } + + return $data; + } + + public function getQueryBuilders(): array + { + self::bootKernel(); + + $em = self::$container->get(EntityManagerInterface::class); + + return [ + $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity') + ->join('activity.users', 'actusers'), + ]; + } +} diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php index 1fa121d94..e6ec47666 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialActionFilterTest.php @@ -19,6 +19,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class BySocialActionFilterTest extends AbstractFilterTest @@ -47,7 +48,6 @@ final class BySocialActionFilterTest extends AbstractFilterTest ->from(SocialAction::class, 'sa') ->select('sa') ->getQuery() - ->setMaxResults(1) ->getResult(); $data = []; diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php index ee2360a4e..47f45ceb5 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ACPFilters/BySocialIssueFilterTest.php @@ -20,6 +20,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class BySocialIssueFilterTest extends AbstractFilterTest diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php index 64d455125..4cefb136a 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityDateFilterTest.php @@ -13,12 +13,13 @@ namespace Chill\ActivityBundle\Tests\Export\Filter; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Export\Filter\ActivityDateFilter; +use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use DateTime; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ActivityDateFilterTest extends AbstractFilterTest @@ -41,24 +42,22 @@ final class ActivityDateFilterTest extends AbstractFilterTest { return [ [ - 'date_from' => DateTime::createFromFormat('Y-m-d', '2020-01-01'), - 'date_to' => DateTime::createFromFormat('Y-m-d', '2021-01-01'), + 'date_from' => new RollingDate(RollingDate::T_FIXED_DATE, \DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01')), + 'date_to' => new RollingDate(RollingDate::T_FIXED_DATE, \DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01')), ], ]; } - public function getQueryBuilders(): array + public function getQueryBuilders(): iterable { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); - return [ - $em->createQueryBuilder() - ->select('count(activity.id)') - ->from(Activity::class, 'activity'), - ]; + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'); + + self::ensureKernelShutdown(); } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php index 26d5248ae..3d1f1fa2d 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityReasonFilterTest.php @@ -14,10 +14,13 @@ namespace Chill\ActivityBundle\Tests\Export\Filter; use Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\EntityManagerInterface; use Prophecy\PhpUnit\ProphecyTrait; +use Symfony\Component\HttpFoundation\RequestStack; /** * @internal + * * @coversNothing */ final class ActivityReasonFilterTest extends AbstractFilterTest @@ -37,7 +40,7 @@ final class ActivityReasonFilterTest extends AbstractFilterTest $request->getLocale()->willReturn('fr'); - self::$container->get('request_stack') + self::$container->get(RequestStack::class) ->push($request->reveal()); } @@ -48,47 +51,42 @@ final class ActivityReasonFilterTest extends AbstractFilterTest public function getFormData() { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); - $em = self::$kernel->getContainer() - ->get('doctrine.orm.entity_manager'); + $em = self::$container + ->get(EntityManagerInterface::class); $reasons = $em->createQuery('SELECT reason ' - . 'FROM ChillActivityBundle:ActivityReason reason') + .'FROM ChillActivityBundle:ActivityReason reason') ->getResult(); // generate an array of 5 different combination of results for ($i = 0; 5 > $i; ++$i) { - $r[] = ['reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1))]; + yield ['reasons' => new ArrayCollection(array_splice($reasons, ($i + 1) * -1))]; } - return $r; + self::ensureKernelShutdown(); } - public function getQueryBuilders() + public function getQueryBuilders(): iterable { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); - $em = self::$kernel->getContainer() - ->get('doctrine.orm.entity_manager'); + $em = self::$container->get(EntityManagerInterface::class); - return [ - $em->createQueryBuilder() - ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity'), - $em->createQueryBuilder() - ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity') - ->join('activity.reasons', 'reasons'), - $em->createQueryBuilder() - ->select('count(activity.id)') - ->from('ChillActivityBundle:Activity', 'activity') - ->join('activity.reasons', 'reasons') - ->join('reasons.category', 'category'), - ]; + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity'); + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.reasons', 'reasons'); + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.reasons', 'reasons') + ->join('reasons.category', 'category'); + + self::ensureKernelShutdown(); } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php index 9fd1250ca..5f94b4579 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ActivityTypeFilterTest.php @@ -15,10 +15,12 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityType; use Chill\ActivityBundle\Export\Filter\ActivityTypeFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ActivityTypeFilterTest extends AbstractFilterTest @@ -37,8 +39,10 @@ final class ActivityTypeFilterTest extends AbstractFilterTest return $this->filter; } - public function getFormData(): array + public function getFormData(): iterable { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() @@ -51,25 +55,23 @@ final class ActivityTypeFilterTest extends AbstractFilterTest foreach ($array as $a) { $data[] = [ - 'types' => $a, + 'types' => new ArrayCollection([$a]), ]; } return $data; } - public function getQueryBuilders(): array + public function getQueryBuilders(): iterable { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); - return [ - $em->createQueryBuilder() - ->select('count(activity.id)') - ->from(Activity::class, 'activity'), - ]; + yield $em->createQueryBuilder() + ->select('count(activity.id)') + ->from(Activity::class, 'activity'); + + self::ensureKernelShutdown(); } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ByCreatorFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ByCreatorFilterTest.php index e41a0e43e..d5073b625 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ByCreatorFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/ByCreatorFilterTest.php @@ -19,9 +19,10 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ -final class ByUserFilterTest extends AbstractFilterTest +final class ByCreatorFilterTest extends AbstractFilterTest { private ByCreatorFilter $filter; diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/EmergencyFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/EmergencyFilterTest.php index 072588ced..5ef1879a7 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/EmergencyFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/EmergencyFilterTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class EmergencyFilterTest extends AbstractFilterTest @@ -46,9 +47,7 @@ final class EmergencyFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/LocationTypeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/LocationTypeFilterTest.php index 2d779bf32..bf52ceee1 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/LocationTypeFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/LocationTypeFilterTest.php @@ -19,6 +19,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class LocationTypeFilterTest extends AbstractFilterTest @@ -39,12 +40,14 @@ final class LocationTypeFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(LocationType::class, 'lt') ->select('lt') ->getQuery() + ->setMaxResults(1) ->getResult(); $data = []; @@ -60,9 +63,7 @@ final class LocationTypeFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php index b4e962ba9..6ad78579e 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/ActivityReasonFilterTest.php @@ -15,10 +15,12 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ActivityReasonFilterTest extends AbstractFilterTest @@ -39,19 +41,21 @@ final class ActivityReasonFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(ActivityReason::class, 'ar') ->select('ar') ->getQuery() + ->setMaxResults(1) ->getResult(); $data = []; foreach ($array as $a) { $data[] = [ - 'reasons' => $a, + 'reasons' => new ArrayCollection([$a]), ]; } @@ -60,9 +64,7 @@ final class ActivityReasonFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php index 2fb68ed81..34a9c8303 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonFilters/PersonHavingActivityBetweenDateFilterTest.php @@ -15,11 +15,11 @@ use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use DateTime; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest @@ -40,20 +40,22 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(ActivityReason::class, 'ar') ->select('ar') ->getQuery() + ->setMaxResults(1) ->getResult(); $data = []; foreach ($array as $a) { $data[] = [ - 'date_from' => DateTime::createFromFormat('Y-m-d', '2021-07-01'), - 'date_to' => DateTime::createFromFormat('Y-m-d', '2022-07-01'), + 'date_from' => \DateTime::createFromFormat('Y-m-d', '2021-07-01'), + 'date_to' => \DateTime::createFromFormat('Y-m-d', '2022-07-01'), 'reasons' => [$a], ]; } @@ -73,8 +75,7 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest $em->createQueryBuilder() ->select('count(activity.id)') ->from(Activity::class, 'activity') - ->join('activity.person', 'person') - , + ->join('activity.person', 'person'), ]; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php index 762de529e..a2ea7c158 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/PersonHavingActivityBetweenDateFilterTest.php @@ -12,12 +12,16 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Tests\Export\Filter; use Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter; +use Chill\ActivityBundle\Repository\ActivityReasonRepository; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use DateTime; -use function array_slice; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Persistence\ManagerRegistry; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; /** * @internal + * * @coversNothing */ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest @@ -35,7 +39,7 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest $request->getLocale()->willReturn('fr'); - self::$container->get('request_stack') + self::$container->get(RequestStack::class) ->push($request->reveal()); } @@ -46,8 +50,8 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest public function getFormData() { - $date_from = DateTime::createFromFormat('Y-m-d', '2015-01-15'); - $date_to = new DateTime(); // today + $date_from = \DateTime::createFromFormat('Y-m-d', '2015-01-15'); + $date_to = new \DateTime(); // today $reasons = $this->getActivityReasons(); $data = []; @@ -56,7 +60,7 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest $data[] = [ 'date_from' => $date_from, 'date_to' => $date_to, - 'reasons' => array_slice($reasons, 0, 1 + $i), + 'reasons' => \array_slice($reasons, 0, 1 + $i), ]; } @@ -65,26 +69,24 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest public function getQueryBuilders() { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); - $em = self::$kernel->getContainer() - ->get('doctrine.orm.entity_manager'); + $em = self::$container + ->get(EntityManagerInterface::class); - return [ - $em->createQueryBuilder() - ->select('count(person.id)') - ->from('ChillPersonBundle:Person', 'person') - // add a fake where clause - ->where('person.id > 0'), - $em->createQueryBuilder() - ->select('count(person.id)') - ->from('ChillActivityBundle:Activity', 'activity') - ->join('activity.person', 'person') - // add a fake where clause - ->where('person.id > 0'), - ]; + yield $em->createQueryBuilder() + ->select('count(person.id)') + ->from('ChillPersonBundle:Person', 'person') + // add a fake where clause + ->where('person.id > 0'); + yield $em->createQueryBuilder() + ->select('count(person.id)') + ->from('ChillActivityBundle:Activity', 'activity') + ->join('activity.person', 'person') + // add a fake where clause + ->where('person.id > 0'); + + self::ensureKernelShutdown(); } /** @@ -94,12 +96,14 @@ final class PersonHavingActivityBetweenDateFilterTest extends AbstractFilterTest */ private function getActivityReasons() { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); - return self::$kernel->getContainer() - ->get('chill_activity.repository.reason') - ->findAll(); + $managerRegistry = self::$container->get(ManagerRegistry::class); + $requestStack = new RequestStack(); + $requestStack->push(new Request()); + + $repository = new ActivityReasonRepository($managerRegistry, $requestStack); + + return $repository->findAll(); } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/SentReceivedFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/SentReceivedFilterTest.php index 5ea655f79..f368e69fa 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/SentReceivedFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/SentReceivedFilterTest.php @@ -18,6 +18,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class SentReceivedFilterTest extends AbstractFilterTest @@ -46,9 +47,7 @@ final class SentReceivedFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserFilterTest.php index b80a160d7..ef8f4c6b2 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserFilterTest.php @@ -19,6 +19,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class UserFilterTest extends AbstractFilterTest @@ -39,12 +40,14 @@ final class UserFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(User::class, 'u') ->select('u') ->getQuery() + ->setMaxResults(1) ->getResult(); $data = []; @@ -60,9 +63,7 @@ final class UserFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserScopeFilterTest.php b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserScopeFilterTest.php index 46ff8fda3..858931327 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserScopeFilterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Export/Filter/UserScopeFilterTest.php @@ -19,6 +19,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class UserScopeFilterTest extends AbstractFilterTest @@ -39,19 +40,21 @@ final class UserScopeFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(Scope::class, 's') ->select('s') ->getQuery() + ->setMaxResults(1) ->getResult(); $data = []; foreach ($array as $a) { $data[] = [ - 'accepted_userscope' => $a, + 'scopes' => $a, ]; } @@ -60,9 +63,7 @@ final class UserScopeFilterTest extends AbstractFilterTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php index 3ed6b4409..3d1b31f08 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php @@ -13,14 +13,13 @@ namespace Chill\ActivityBundle\Tests\Form; use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Form\ActivityType; -use DateTime; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; -use Symfony\Component\Security\Core\Role\Role; /** * @internal + * * @coversNothing */ final class ActivityTypeTest extends KernelTestCase @@ -30,11 +29,6 @@ final class ActivityTypeTest extends KernelTestCase */ protected $center; - /** - * @var \Symfony\Component\DependencyInjection\ContainerInterface - */ - protected $container; - /** * @var \Symfony\Component\Form\FormBuilderInterface */ @@ -85,7 +79,7 @@ final class ActivityTypeTest extends KernelTestCase $form = $this->formBuilder ->add('activity', ActivityType::class, [ 'center' => $this->center, - 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'role' => 'CHILL_ACTIVITY_CREATE', ]) ->getForm(); @@ -101,7 +95,7 @@ final class ActivityTypeTest extends KernelTestCase $form = $this->formBuilder ->add('activity', ActivityType::class, [ 'center' => $this->center, - 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'role' => 'CHILL_ACTIVITY_CREATE', ]) ->getForm(); @@ -145,7 +139,7 @@ final class ActivityTypeTest extends KernelTestCase public function testFormWithActivityHavingDifferentTime() { $activity = new Activity(); - $activity->setDurationTime(DateTime::createFromFormat('U', 60)); + $activity->setDurationTime(\DateTime::createFromFormat('U', 60)); $builder = $this->container ->get('form.factory') @@ -157,7 +151,7 @@ final class ActivityTypeTest extends KernelTestCase $form = $builder ->add('activity', ActivityType::class, [ 'center' => $this->center, - 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'role' => 'CHILL_ACTIVITY_CREATE', ]) ->getForm(); diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php index a8d85daa6..014c3ae9f 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityReasonTest.php @@ -20,6 +20,7 @@ use Symfony\Component\Form\Test\TypeTestCase; * Test translatableActivityReason. * * @internal + * * @coversNothing */ final class TranslatableActivityReasonTest extends TypeTestCase @@ -34,7 +35,10 @@ final class TranslatableActivityReasonTest extends TypeTestCase parent::setUp(); } - public function testSimple() + /** + * @doesNotPerformAssertions + */ + public function testSimple(): never { $translatableActivityReasonType = new PickActivityReasonType( $this->getTranslatableStringHelper() diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php index 770b88cf4..80779d909 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Form/Type/TranslatableActivityTypeTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; /** * @internal + * * @coversNothing */ final class TranslatableActivityTypeTest extends KernelTestCase @@ -27,18 +28,11 @@ final class TranslatableActivityTypeTest extends KernelTestCase */ protected $builder; - /** - * @var \Symfony\Component\DependencyInjection\ContainerInterface - */ - protected $container; - protected function setUp(): void { self::bootKernel(); - $this->container = self::$kernel->getContainer(); - - $this->builder = $this->container + $this->builder = self::$container ->get('form.factory') ->createBuilder(FormType::class, null, [ 'csrf_protection' => false, @@ -89,11 +83,9 @@ final class TranslatableActivityTypeTest extends KernelTestCase } /** - * @param mixed $active - * * @return \Chill\ActivityBundle\Entity\ActivityType */ - protected function getRandomType($active = true) + protected function getRandomType(mixed $active = true) { $types = $this->container->get('doctrine.orm.entity_manager') ->getRepository(ActivityType::class) diff --git a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php index e7b2117d4..88eb3e7f8 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityACLAwareRepositoryTest.php @@ -33,6 +33,7 @@ use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ class ActivityACLAwareRepositoryTest extends KernelTestCase @@ -182,7 +183,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase if (null === $person = $this->entityManager->createQueryBuilder() ->select('p')->from(Person::class, 'p')->setMaxResults(1) ->getQuery()->getSingleResult()) { - throw new \RuntimeException("person not found"); + throw new \RuntimeException('person not found'); } /** @var AccompanyingPeriod $period1 */ @@ -193,7 +194,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->setMaxResults(1) ->getQuery() ->getSingleResult()) { - throw new \RuntimeException("no period found"); + throw new \RuntimeException('no period found'); } /** @var AccompanyingPeriod $period2 */ @@ -206,7 +207,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->setMaxResults(1) ->getQuery() ->getSingleResult()) { - throw new \RuntimeException("no second period found"); + throw new \RuntimeException('no second period found'); } // add a period $period1->addPerson($person); @@ -222,7 +223,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->setMaxResults(2) ->getQuery() ->getResult()) { - throw new \RuntimeException("no types"); + throw new \RuntimeException('no types'); } if ([] === $jobs = $this->entityManager @@ -233,7 +234,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->getQuery() ->getResult() ) { - throw new \RuntimeException("no jobs found"); + throw new \RuntimeException('no jobs found'); } if (null === $user = $this->entityManager @@ -244,19 +245,19 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->getQuery() ->getSingleResult() ) { - throw new \RuntimeException("no user found"); + throw new \RuntimeException('no user found'); } if ([] === $centers = $this->entityManager->createQueryBuilder() ->select('c')->from(Center::class, 'c')->setMaxResults(2)->getQuery() ->getResult()) { - throw new \RuntimeException("no centers found"); + throw new \RuntimeException('no centers found'); } if ([] === $scopes = $this->entityManager->createQueryBuilder() ->select('s')->from(Scope::class, 's')->setMaxResults(2)->getQuery() ->getResult()) { - throw new \RuntimeException("no scopes found"); + throw new \RuntimeException('no scopes found'); } yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], []]; @@ -279,7 +280,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->setMaxResults(1) ->getQuery() ->getSingleResult()) { - throw new \RuntimeException("no period found"); + throw new \RuntimeException('no period found'); } if ([] === $types = $this->entityManager @@ -289,7 +290,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->setMaxResults(2) ->getQuery() ->getResult()) { - throw new \RuntimeException("no types"); + throw new \RuntimeException('no types'); } if ([] === $jobs = $this->entityManager @@ -300,7 +301,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->getQuery() ->getResult() ) { - throw new \RuntimeException("no jobs found"); + throw new \RuntimeException('no jobs found'); } if (null === $user = $this->entityManager @@ -311,7 +312,7 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase ->getQuery() ->getSingleResult() ) { - throw new \RuntimeException("no user found"); + throw new \RuntimeException('no user found'); } yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []]; diff --git a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php index 74f1d2bd0..c32714641 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Repository/ActivityDocumentACLAwareRepositoryTest.php @@ -20,7 +20,6 @@ use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Doctrine\ORM\EntityManagerInterface; -use phpseclib3\Math\BinaryField; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -28,6 +27,7 @@ use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ class ActivityDocumentACLAwareRepositoryTest extends KernelTestCase @@ -104,22 +104,22 @@ class ActivityDocumentACLAwareRepositoryTest extends KernelTestCase { $this->setUp(); - if (null === $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p WHERE SIZE(p.accompanyingPeriodParticipations) > 0 ") + if (null === $person = $this->entityManager->createQuery('SELECT p FROM '.Person::class.' p WHERE SIZE(p.accompanyingPeriodParticipations) > 0 ') ->setMaxResults(1) ->getSingleResult()) { - throw new \RuntimeException("no person in dtabase"); + throw new \RuntimeException('no person in dtabase'); } - if ([] === $scopes = $this->entityManager->createQuery("SELECT s FROM " . Scope::class . " s ")->setMaxResults(5)->getResult()) { - throw new \RuntimeException("no scopes in database"); + if ([] === $scopes = $this->entityManager->createQuery('SELECT s FROM '.Scope::class.' s ')->setMaxResults(5)->getResult()) { + throw new \RuntimeException('no scopes in database'); } yield [$person, [], true, null, null, null]; yield [$person, $scopes, true, null, null, null]; - yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), null, null]; - yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), null]; - yield [$person, $scopes, true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), "content"]; - yield [$person, $scopes, true, null, new \DateTimeImmutable("1 week ago"), "content"]; - yield [$person, [], true, new \DateTimeImmutable("1 month ago"), new \DateTimeImmutable("1 week ago"), "content"]; + yield [$person, $scopes, true, new \DateTimeImmutable('1 month ago'), null, null]; + yield [$person, $scopes, true, new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('1 week ago'), null]; + yield [$person, $scopes, true, new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('1 week ago'), 'content']; + yield [$person, $scopes, true, null, new \DateTimeImmutable('1 week ago'), 'content']; + yield [$person, [], true, new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('1 week ago'), 'content']; } } diff --git a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php index 1fb90a4ae..b907363a3 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Security/Authorization/ActivityVoterTest.php @@ -24,6 +24,7 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; /** * @internal + * * @coversNothing */ final class ActivityVoterTest extends KernelTestCase @@ -127,7 +128,7 @@ final class ActivityVoterTest extends KernelTestCase /** * @dataProvider dataProvider_testVoteAction * - * @param type $expectedResult + * @param type $expectedResult * @param string $attribute * @param string $message */ @@ -156,11 +157,11 @@ final class ActivityVoterTest extends KernelTestCase * * @return \Symfony\Component\Security\Core\Authentication\Token\TokenInterface */ - protected function prepareToken(?User $user = null) + protected function prepareToken(User $user = null) { $token = $this->prophet->prophesize(); $token - ->willImplement('\\' . \Symfony\Component\Security\Core\Authentication\Token\TokenInterface::class); + ->willImplement('\\'.\Symfony\Component\Security\Core\Authentication\Token\TokenInterface::class); if (null === $user) { $token->getUser()->willReturn(null); diff --git a/src/Bundle/ChillActivityBundle/Tests/Timeline/TimelineProviderTest.php b/src/Bundle/ChillActivityBundle/Tests/Timeline/TimelineProviderTest.php index 664196ad4..b7796c9ba 100644 --- a/src/Bundle/ChillActivityBundle/Tests/Timeline/TimelineProviderTest.php +++ b/src/Bundle/ChillActivityBundle/Tests/Timeline/TimelineProviderTest.php @@ -15,11 +15,15 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * @internal + * * @coversNothing */ final class TimelineProviderTest extends WebTestCase { - public function testAnActivityIsShownOnTimeline() + /** + * @doesNotPerformAssertions + */ + public function testAnActivityIsShownOnTimeline(): never { $this->markTestSkipped('we have to write fixtures before writing this tests'); } diff --git a/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php b/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php index 2c9272b08..23a75e9fe 100644 --- a/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php +++ b/src/Bundle/ChillActivityBundle/Timeline/TimelineActivityProvider.php @@ -19,40 +19,23 @@ use Chill\MainBundle\Timeline\TimelineProviderInterface; use Chill\MainBundle\Timeline\TimelineSingleQuery; use Chill\PersonBundle\Entity\Person; use Doctrine\ORM\EntityManagerInterface; -use LogicException; -use RuntimeException; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\User\UserInterface; -use function implode; -use function in_array; -use function strtr; - class TimelineActivityProvider implements TimelineProviderInterface { private const SUPPORTED_CONTEXTS = ['center', 'person']; - protected ActivityACLAwareRepository $aclAwareRepository; - - protected EntityManagerInterface $em; - - protected AuthorizationHelperInterface $helper; - protected UserInterface $user; public function __construct( - EntityManagerInterface $em, - AuthorizationHelperInterface $helper, + protected EntityManagerInterface $em, + protected AuthorizationHelperInterface $helper, TokenStorageInterface $storage, - ActivityACLAwareRepository $aclAwareRepository + protected ActivityACLAwareRepository $aclAwareRepository ) { - $this->em = $em; - $this->helper = $helper; - $this->aclAwareRepository = $aclAwareRepository; - if (!$storage->getToken()->getUser() instanceof User) { - throw new RuntimeException('A user should be authenticated !'); + throw new \RuntimeException('A user should be authenticated !'); } $this->user = $storage->getToken()->getUser(); @@ -71,10 +54,10 @@ class TimelineActivityProvider implements TimelineProviderInterface return TimelineSingleQuery::fromArray([ 'id' => $metadataActivity->getTableName() - . '.' . $metadataActivity->getColumnName('id'), + .'.'.$metadataActivity->getColumnName('id'), 'type' => 'activity', 'date' => $metadataActivity->getTableName() - . '.' . $metadataActivity->getColumnName('date'), + .'.'.$metadataActivity->getColumnName('date'), 'FROM' => $this->getFromClausePerson(), 'WHERE' => $where, 'parameters' => $parameters, @@ -100,7 +83,7 @@ class TimelineActivityProvider implements TimelineProviderInterface $this->checkContext($context); return [ - 'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig', + 'template' => '@ChillActivity/Timeline/activity_person_context.html.twig', 'template_data' => [ 'activity' => $entity, 'context' => $context, @@ -116,17 +99,12 @@ class TimelineActivityProvider implements TimelineProviderInterface /** * Check if the context is supported. * - * @throws LogicException if the context is not supported + * @throws \LogicException if the context is not supported */ private function checkContext(string $context) { - if (false === in_array($context, self::SUPPORTED_CONTEXTS, true)) { - throw new LogicException( - sprintf( - "The context '%s' is not supported. Currently only 'person' is supported", - $context - ) - ); + if (false === \in_array($context, self::SUPPORTED_CONTEXTS, true)) { + throw new \LogicException(sprintf("The context '%s' is not supported. Currently only 'person' is supported", $context)); } } @@ -151,8 +129,8 @@ class TimelineActivityProvider implements TimelineProviderInterface $parameters = []; $metadataActivity = $this->em->getClassMetadata(Activity::class); $associationMapping = $metadataActivity->getAssociationMapping('person'); - $role = new Role('CHILL_ACTIVITY_SEE'); - $reachableScopes = $this->helper->getReachableScopes($this->user, $role->getRole(), $person->getCenter()); + $role = 'CHILL_ACTIVITY_SEE'; + $reachableScopes = $this->helper->getReachableScopes($this->user, $role, $person->getCenter()); $whereClause = ' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) '; $scopes_ids = []; @@ -161,8 +139,8 @@ class TimelineActivityProvider implements TimelineProviderInterface // loop on reachable scopes foreach ($reachableScopes as $scope) { - /** @phpstan-ignore-next-line */ - if (in_array($scope->getId(), $scopes_ids, true)) { + /* @phpstan-ignore-next-line */ + if (\in_array($scope->getId(), $scopes_ids, true)) { continue; } $scopes_ids[] = '?'; @@ -170,13 +148,13 @@ class TimelineActivityProvider implements TimelineProviderInterface } return [ - strtr( + \strtr( $whereClause, [ '{activity.person_id}' => $associationMapping['joinColumns'][0]['name'], - '{activity.scope_id}' => $metadataActivity->getTableName() . '.' . + '{activity.scope_id}' => $metadataActivity->getTableName().'.'. $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'], - '{scopes_ids}' => implode(', ', $scopes_ids), + '{scopes_ids}' => \implode(', ', $scopes_ids), ] ), $parameters, diff --git a/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php index 393b33322..aafe5f9b5 100644 --- a/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php +++ b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php @@ -18,9 +18,9 @@ use Symfony\Component\Validator\Constraint; */ class ActivityValidity extends Constraint { - public const IS_REQUIRED_MESSAGE = ' is required'; + final public const IS_REQUIRED_MESSAGE = ' is required'; - public const ROOT_MESSAGE = 'For this type of activity, '; + final public const ROOT_MESSAGE = 'For this type of activity, '; public $noPersonsMessage = 'For this type of activity, you must add at least one person'; @@ -39,6 +39,6 @@ class ActivityValidity extends Constraint public function makeIsRequiredMessage(string $property) { - return self::ROOT_MESSAGE . $property . self::IS_REQUIRED_MESSAGE; + return self::ROOT_MESSAGE.$property.self::IS_REQUIRED_MESSAGE; } } diff --git a/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php index 11b4b61e0..21ee6185e 100644 --- a/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php +++ b/src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidityValidator.php @@ -18,9 +18,6 @@ use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\UnexpectedValueException; -use function array_merge; -use function count; - class ActivityValidityValidator extends ConstraintValidator { public function validate($activity, Constraint $constraint) @@ -33,106 +30,106 @@ class ActivityValidityValidator extends ConstraintValidator throw new UnexpectedValueException($activity, Activity::class); } - if ($activity->getActivityType()->getPersonsVisible() === 2 && count($activity->getPersons()) === 0) { + if (2 === $activity->getActivityType()->getPersonsVisible() && 0 === \count($activity->getPersons())) { $this->context ->buildViolation($constraint->noPersonsMessage) ->addViolation(); } - if ($activity->getActivityType()->getUsersVisible() === 2 && count($activity->getUsers()) === 0) { + if (2 === $activity->getActivityType()->getUsersVisible() && 0 === \count($activity->getUsers())) { $this->context ->buildViolation($constraint->noUsersMessage) ->addViolation(); } - if ($activity->getActivityType()->getThirdPartiesVisible() === 2 && count($activity->getThirdParties()) === 0) { + if (2 === $activity->getActivityType()->getThirdPartiesVisible() && 0 === \count($activity->getThirdParties())) { $this->context ->buildViolation($constraint->noThirdPartiesMessage) ->addViolation(); } - if ($activity->getActivityType()->getUserVisible() === 2 && null === $activity->getUser()) { + if (2 === $activity->getActivityType()->getUserVisible() && null === $activity->getUser()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('user')) ->addViolation(); } - if ($activity->getActivityType()->getDateVisible() === 2 && null === $activity->getDate()) { + if (2 === $activity->getActivityType()->getDateVisible() && null === $activity->getDate()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('date')) ->addViolation(); } - if ($activity->getActivityType()->getLocationVisible() === 2 && null === $activity->getLocation()) { + if (2 === $activity->getActivityType()->getLocationVisible() && null === $activity->getLocation()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('location')) ->addViolation(); } - if ($activity->getActivityType()->getDurationTimeVisible() === 2 && null === $activity->getDurationTime()) { + if (2 === $activity->getActivityType()->getDurationTimeVisible() && null === $activity->getDurationTime()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('duration time')) ->addViolation(); } - if ($activity->getActivityType()->getTravelTimeVisible() === 2 && null === $activity->getTravelTime()) { + if (2 === $activity->getActivityType()->getTravelTimeVisible() && null === $activity->getTravelTime()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('travel time')) ->addViolation(); } - if ($activity->getActivityType()->getAttendeeVisible() === 2 && null === $activity->getAttendee()) { + if (2 === $activity->getActivityType()->getAttendeeVisible() && null === $activity->getAttendee()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('attendee')) ->addViolation(); } - if ($activity->getActivityType()->getReasonsVisible() === 2 && null === $activity->getReasons()) { + if (2 === $activity->getActivityType()->getReasonsVisible() && null === $activity->getReasons()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('reasons')) ->addViolation(); } - if ($activity->getActivityType()->getCommentVisible() === 2 && null === $activity->getComment()) { + if (2 === $activity->getActivityType()->getCommentVisible() && null === $activity->getComment()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('comment')) ->addViolation(); } - if ($activity->getActivityType()->getSentReceivedVisible() === 2 && null === $activity->getSentReceived()) { + if (2 === $activity->getActivityType()->getSentReceivedVisible() && null === $activity->getSentReceived()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('sent/received')) ->addViolation(); } - if ($activity->getActivityType()->getDocumentsVisible() === 2 && null === $activity->getDocuments()) { + if (2 === $activity->getActivityType()->getDocumentsVisible() && null === $activity->getDocuments()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('document')) ->addViolation(); } - if ($activity->getActivityType()->getEmergencyVisible() === 2 && null === $activity->getEmergency()) { + if (2 === $activity->getActivityType()->getEmergencyVisible() && null === $activity->getEmergency()) { $this->context ->buildViolation($constraint->makeIsRequiredMessage('emergency')) ->addViolation(); } - if ($activity->getActivityType()->getSocialIssuesVisible() === 2 && $activity->getSocialIssues()->count() === 0) { + if (2 === $activity->getActivityType()->getSocialIssuesVisible() && 0 === $activity->getSocialIssues()->count()) { $this->context ->buildViolation($constraint->socialIssuesMessage) ->addViolation(); } - if ($activity->getActivityType()->getSocialActionsVisible() === 2 && $activity->getSocialActions()->count() === 0) { + if (2 === $activity->getActivityType()->getSocialActionsVisible() && 0 === $activity->getSocialActions()->count()) { // check if a social action may be added $actions = []; foreach ($activity->getSocialIssues() as $socialIssue) { /** @var SocialIssue $socialIssue */ - $actions = array_merge($actions, $socialIssue->getRecursiveSocialActions()->toArray()); + $actions = \array_merge($actions, $socialIssue->getRecursiveSocialActions()->toArray()); } - if (0 < count($actions)) { + if (0 < \count($actions)) { $this->context ->buildViolation($constraint->socialActionsMessage) ->addViolation(); diff --git a/src/Bundle/ChillActivityBundle/config/routes.yaml b/src/Bundle/ChillActivityBundle/config/routes.yaml index d20f47013..e5539c753 100644 --- a/src/Bundle/ChillActivityBundle/config/routes.yaml +++ b/src/Bundle/ChillActivityBundle/config/routes.yaml @@ -1,22 +1,6 @@ -chill_activity_activity: - resource: "@ChillActivityBundle/config/routes/activity.yaml" - prefix: / - -chill_activity_activityreason: - resource: "@ChillActivityBundle/config/routes/activityreason.yaml" - prefix: / - -chill_activity_activityreasoncategory: - resource: "@ChillActivityBundle/config/routes/activityreasoncategory.yaml" - prefix: / - -chill_activity_admin_index: - path: /{_locale}/admin/activity - controller: Chill\ActivityBundle\Controller\AdminController::indexActivityAction - -chill_admin_activity_redirect_to_admin_index: - path: /{_locale}/admin/activity_redirect_to_main - controller: Chill\ActivityBundle\Controller\AdminController::redirectToAdminIndexAction +chill_activity_routes: + resource: '@ChillActivityBundle/Controller' + type: annotation chill_activity_type_admin: path: /{_locale}/admin/activity/type diff --git a/src/Bundle/ChillActivityBundle/config/routes/activity.yaml b/src/Bundle/ChillActivityBundle/config/routes/activity.yaml deleted file mode 100644 index 179de905b..000000000 --- a/src/Bundle/ChillActivityBundle/config/routes/activity.yaml +++ /dev/null @@ -1,26 +0,0 @@ -chill_activity_activity_list: - path: /{_locale}/activity/ - controller: Chill\ActivityBundle\Controller\ActivityController::listAction - -chill_activity_activity_show: - path: /{_locale}/activity/{id}/show - controller: Chill\ActivityBundle\Controller\ActivityController::showAction - -chill_activity_activity_select_type: - path: /{_locale}/activity/select-type - controller: Chill\ActivityBundle\Controller\ActivityController::selectTypeAction - -chill_activity_activity_new: - path: /{_locale}/activity/new - controller: Chill\ActivityBundle\Controller\ActivityController::newAction - methods: [POST, GET] - -chill_activity_activity_edit: - path: /{_locale}/activity/{id}/edit - controller: Chill\ActivityBundle\Controller\ActivityController::editAction - methods: [GET, POST, PUT] - -chill_activity_activity_delete: - path: /{_locale}/activity/{id}/delete - controller: Chill\ActivityBundle\Controller\ActivityController::deleteAction - methods: [GET, POST, DELETE] diff --git a/src/Bundle/ChillActivityBundle/config/routes/activityreason.yaml b/src/Bundle/ChillActivityBundle/config/routes/activityreason.yaml deleted file mode 100644 index 59473d9f0..000000000 --- a/src/Bundle/ChillActivityBundle/config/routes/activityreason.yaml +++ /dev/null @@ -1,30 +0,0 @@ -chill_activity_activityreason: - path: /{_locale}/admin/activityreason/ - controller: Chill\ActivityBundle\Controller\ActivityReasonController::indexAction - -chill_activity_activityreason_show: - path: /{_locale}/admin/activityreason/{id}/show - controller: Chill\ActivityBundle\Controller\ActivityReasonController::showAction - -chill_activity_activityreason_new: - path: /{_locale}/admin/activityreason/new - controller: Chill\ActivityBundle\Controller\ActivityReasonController::newAction - -chill_activity_activityreason_create: - path: /{_locale}/admin/activityreason/create - controller: Chill\ActivityBundle\Controller\ActivityReasonController::createAction - methods: POST - -chill_activity_activityreason_edit: - path: /{_locale}/admin/activityreason/{id}/edit - controller: Chill\ActivityBundle\Controller\ActivityReasonController::editAction - -chill_activity_activityreason_update: - path: /{_locale}/admin/activityreason/{id}/update - controller: Chill\ActivityBundle\Controller\ActivityReasonController::updateAction - methods: [POST, PUT] - -chill_activity_activityreason_delete: - path: /{_locale}/admin/activityreason/{id}/delete - controller: Chill\ActivityBundle\Controller\ActivityReasonController::deleteAction - methods: [POST, DELETE] diff --git a/src/Bundle/ChillActivityBundle/config/routes/activityreasoncategory.yaml b/src/Bundle/ChillActivityBundle/config/routes/activityreasoncategory.yaml deleted file mode 100644 index 1487a1e24..000000000 --- a/src/Bundle/ChillActivityBundle/config/routes/activityreasoncategory.yaml +++ /dev/null @@ -1,30 +0,0 @@ -chill_activity_activityreasoncategory: - path: /{_locale}/admin/activityreasoncategory/ - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::indexAction - -chill_activity_activityreasoncategory_show: - path: /{_locale}/admin/activityreasoncategory/{id}/show - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::showAction - -chill_activity_activityreasoncategory_new: - path: /{_locale}/admin/activityreasoncategory/new - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::newAction - -chill_activity_activityreasoncategory_create: - path: /{_locale}/admin/activityreasoncategory/create - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::createAction - methods: POST - -chill_activity_activityreasoncategory_edit: - path: /{_locale}/admin/activityreasoncategory/{id}/edit - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::editAction - -chill_activity_activityreasoncategory_update: - path: /{_locale}/admin/activityreasoncategory/{id}/update - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::updateAction - methods: [POST, PUT] - -chill_activity_activityreasoncategory_delete: - path: /{_locale}/admin/activityreasoncategory/{id}/delete - controller: Chill\ActivityBundle\Controller\ActivityReasonCategoryController::deleteAction - methods: [POST, DELETE] diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 563ea7bf5..09a5227eb 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -177,6 +177,10 @@ services: tags: - { name: chill.export_aggregator, alias: activity_creator_scope_aggregator } + Chill\ActivityBundle\Export\Aggregator\JobScopeAggregator: + tags: + - { name: chill.export_aggregator, alias: activity_creator_job_aggregator } + Chill\ActivityBundle\Export\Aggregator\ActivityUsersAggregator: tags: - { name: chill.export_aggregator, alias: activity_users_aggregator } diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20150701091248.php b/src/Bundle/ChillActivityBundle/migrations/Version20150701091248.php index f96762748..5a050035a 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20150701091248.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20150701091248.php @@ -22,7 +22,7 @@ class Version20150701091248 extends AbstractMigration public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE Activity DROP CONSTRAINT FK_55026B0C59BB1592'); $this->addSql('ALTER TABLE ActivityReason DROP CONSTRAINT FK_654A2FCD12469DE2'); @@ -40,7 +40,7 @@ class Version20150701091248 extends AbstractMigration public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('CREATE SEQUENCE Activity_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); $this->addSql('CREATE SEQUENCE ActivityReason_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20150702093317.php b/src/Bundle/ChillActivityBundle/migrations/Version20150702093317.php index f8dc40e95..053e4ecc8 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20150702093317.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20150702093317.php @@ -22,7 +22,7 @@ class Version20150702093317 extends AbstractMigration public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE ActivityReasonCategory DROP COLUMN name;'); $this->addSql('ALTER TABLE ActivityReasonCategory ADD COLUMN label VARCHAR(255) NOT NULL;'); @@ -35,7 +35,7 @@ class Version20150702093317 extends AbstractMigration public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE ActivityReasonCategory DROP COLUMN label;'); $this->addSql('ALTER TABLE ActivityReasonCategory ADD COLUMN name JSON;'); diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20150704091347.php b/src/Bundle/ChillActivityBundle/migrations/Version20150704091347.php index 6509701cc..78204fa67 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20150704091347.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20150704091347.php @@ -22,7 +22,7 @@ class Version20150704091347 extends AbstractMigration public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE Activity ALTER COLUMN remark SET NOT NULL;'); $this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;'); @@ -31,7 +31,7 @@ class Version20150704091347 extends AbstractMigration public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE Activity ALTER COLUMN remark DROP NOT NULL;'); $this->addSql('ALTER TABLE Activity ALTER COLUMN attendee DROP NOT NULL;'); diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20160222103457.php b/src/Bundle/ChillActivityBundle/migrations/Version20160222103457.php index 1531230c1..ceb0e59e6 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20160222103457.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20160222103457.php @@ -25,14 +25,14 @@ class Version20160222103457 extends AbstractMigration public function down(Schema $schema): void { $this->abortIf( - $this->connection->getDatabasePlatform()->getName() !== 'postgresql', + 'postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.' ); $this->addSql('ALTER TABLE Activity ADD reason_id INT DEFAULT NULL'); $this->addSql('ALTER TABLE Activity ADD CONSTRAINT ' - . 'fk_55026b0c59bb1592 FOREIGN KEY (reason_id) ' - . 'REFERENCES activityreason (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + .'fk_55026b0c59bb1592 FOREIGN KEY (reason_id) ' + .'REFERENCES activityreason (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('CREATE INDEX idx_55026b0c59bb1592 ON Activity (reason_id)'); // try to keep at least on activity reason... @@ -52,29 +52,29 @@ class Version20160222103457 extends AbstractMigration public function up(Schema $schema): void { $this->abortIf( - $this->connection->getDatabasePlatform()->getName() !== 'postgresql', + 'postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.' ); // create the new table activity reason $this->addSql( 'CREATE TABLE activity_activityreason (' - . 'activity_id INT NOT NULL, ' - . 'activityreason_id INT NOT NULL, ' - . 'PRIMARY KEY(activity_id, activityreason_id))' + .'activity_id INT NOT NULL, ' + .'activityreason_id INT NOT NULL, ' + .'PRIMARY KEY(activity_id, activityreason_id))' ); $this->addSql('CREATE INDEX IDX_338A864381C06096 ON activity_activityreason (activity_id)'); $this->addSql('CREATE INDEX IDX_338A8643D771E0FC ON activity_activityreason (activityreason_id)'); $this->addSql('ALTER TABLE activity_activityreason ' - . 'ADD CONSTRAINT FK_338A864381C06096 FOREIGN KEY (activity_id) ' - . 'REFERENCES Activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + .'ADD CONSTRAINT FK_338A864381C06096 FOREIGN KEY (activity_id) ' + .'REFERENCES Activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE activity_activityreason ' - . 'ADD CONSTRAINT FK_338A8643D771E0FC FOREIGN KEY (activityreason_id) ' - . 'REFERENCES ActivityReason (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + .'ADD CONSTRAINT FK_338A8643D771E0FC FOREIGN KEY (activityreason_id) ' + .'REFERENCES ActivityReason (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); // migrate old data to new table $this->addSql('INSERT INTO activity_activityreason (activity_id, activityreason_id) ' - . 'SELECT id, reason_id FROM activity WHERE reason_id IS NOT NULL'); + .'SELECT id, reason_id FROM activity WHERE reason_id IS NOT NULL'); // remove old column $this->addSql('ALTER TABLE activity DROP CONSTRAINT fk_55026b0c59bb1592'); diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20210422073711.php b/src/Bundle/ChillActivityBundle/migrations/Version20210422073711.php index ec321faa7..9be59b2b9 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20210422073711.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20210422073711.php @@ -14,8 +14,6 @@ namespace Chill\Migrations\Activity; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; -use function count; - /** * Auto-generated Migration: Please modify to your needs! */ @@ -49,8 +47,8 @@ final class Version20210422073711 extends AbstractMigration 'Domicile erronéee', ]; - for ($i = 1; count($list) >= $i; ++$i) { - $this->addSql('INSERT INTO activitytpresence VALUES(' . $i . ", json_build_object('fr', '" . $list[$i - 1] . "'), true)"); + for ($i = 1; \count($list) >= $i; ++$i) { + $this->addSql('INSERT INTO activitytpresence VALUES('.$i.", json_build_object('fr', '".$list[$i - 1]."'), true)"); } $this->addSql('ALTER TABLE activity ADD emergency BOOLEAN NOT NULL DEFAULT false'); diff --git a/src/Bundle/ChillActivityBundle/migrations/Version20210422123846.php b/src/Bundle/ChillActivityBundle/migrations/Version20210422123846.php index 18711bad0..110ca24b2 100644 --- a/src/Bundle/ChillActivityBundle/migrations/Version20210422123846.php +++ b/src/Bundle/ChillActivityBundle/migrations/Version20210422123846.php @@ -58,7 +58,7 @@ final class Version20210422123846 extends AbstractMigration $this->addSql('ALTER TABLE activity_thirdparty ADD CONSTRAINT FK_C6F0DE0381C06096 FOREIGN KEY (activity_id) REFERENCES activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE activity_thirdparty ADD CONSTRAINT FK_C6F0DE03C7D3A8E6 FOREIGN KEY (thirdparty_id) REFERENCES chill_3party.third_party (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE activity_document ADD CONSTRAINT FK_78633A7881C06096 FOREIGN KEY (activity_id) REFERENCES activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - //$this->addSql('ALTER TABLE activity_document ADD CONSTRAINT FK_78633A78C33F7837 FOREIGN KEY (document_id) REFERENCES Document (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + // $this->addSql('ALTER TABLE activity_document ADD CONSTRAINT FK_78633A78C33F7837 FOREIGN KEY (document_id) REFERENCES Document (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE activity_user ADD CONSTRAINT FK_8E570DDB81C06096 FOREIGN KEY (activity_id) REFERENCES activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE activity_user ADD CONSTRAINT FK_8E570DDBA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml index b2ec70623..123a0d075 100644 --- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml @@ -282,8 +282,6 @@ Filter activity by creator: Filtrer les échanges par créateur de l'échange '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 é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’échange @@ -301,10 +299,6 @@ 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 échanges par type de localisation Group activity by date: Grouper les échanges par date @@ -315,7 +309,6 @@ for week: Semaine by year: Par année in year: En 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 échanges par action liée @@ -362,10 +355,10 @@ export: filter: activity: - by_usersjob: + by_users_job: 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: + by_users_scope: 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%' course_having_activity_between_date: @@ -381,6 +374,9 @@ export: if no reasons: Si aucun sujet n'est coché, tous les sujets seront pris en compte title: Filtrer les personnes ayant été associés à un échange au cours de la période date mismatch: La date de fin de la période doit être supérieure à la date du début + by_creator_scope: + Filter activity by user scope: Filtrer les échanges par service du créateur de l'échange + 'Filtered activity by user scope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%" aggregator: activity: @@ -392,6 +388,18 @@ export: by_location: Activity Location: Localisation de l'échange Title: Grouper les échanges par localisation de l'échange + by_user_job: + Users 's job: Métier des utilisateurs participants à l'échange + Aggregate by users job: Grouper les échanges par métier des utilisateurs participants + by_user_scope: + Users 's scope: Service principal des utilisateurs participants à l'échange + Aggregate by users scope: Grouper les échanges par service principal de l'utilisateur + by_creator_scope: + Group activity by creator scope: Grouper les échanges par service du créateur de l'échange + Calc date: Date de calcul du service du créateur de l'échange + by_creator_job: + Group activity by creator job: Grouper les échanges par service du créateur de l'échange + Calc date: Date de calcul du service du créateur de l'échange generic_doc: filter: diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php index 9144bb129..cbf0ba9ec 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php @@ -24,6 +24,6 @@ class AdminController extends AbstractController */ public function indexAdminAction() { - return $this->render('ChillAsideActivityBundle:Admin:index.html.twig'); + return $this->render('@ChillAsideActivity/Admin/index.html.twig'); } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php index 009a9f2c8..602ef1204 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php @@ -23,7 +23,7 @@ class AsideActivityCategoryController extends CRUDController { protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var QueryBuilder $query */ + /* @var QueryBuilder $query */ $query->addOrderBy('e.ordering', 'ASC'); return $query; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php index 25cb2a557..c29a5a6dc 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php @@ -16,17 +16,11 @@ use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; -use DateTime; use Symfony\Component\HttpFoundation\Request; final class AsideActivityController extends CRUDController { - private AsideActivityCategoryRepository $categoryRepository; - - public function __construct(AsideActivityCategoryRepository $categoryRepository) - { - $this->categoryRepository = $categoryRepository; - } + public function __construct(private readonly AsideActivityCategoryRepository $categoryRepository) {} public function createEntity(string $action, Request $request): object { @@ -36,7 +30,7 @@ final class AsideActivityController extends CRUDController $asideActivity->setLocation($this->getUser()->getCurrentLocation()); $duration = $request->query->get('duration', '300'); - $duration = DateTime::createFromFormat('U', $duration); + $duration = \DateTime::createFromFormat('U', $duration); $asideActivity->setDuration($duration); $categoryId = $request->query->get('type', 7); @@ -53,7 +47,7 @@ final class AsideActivityController extends CRUDController return $asideActivity; } - protected function buildQueryEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null) + protected function buildQueryEntities(string $action, Request $request, FilterOrderHelper $filterOrder = null) { $qb = parent::buildQueryEntities($action, $request); diff --git a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php index 6f6a11390..12c82be00 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivity.php @@ -14,22 +14,13 @@ namespace Chill\AsideActivityBundle\DataFixtures\ORM; use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\MainBundle\DataFixtures\ORM\LoadUsers; use Chill\MainBundle\Repository\UserRepository; -use DateInterval; -use DateTimeImmutable; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; -use function random_int; - class LoadAsideActivity extends Fixture implements DependentFixtureInterface { - private UserRepository $userRepository; - - public function __construct(UserRepository $userRepository) - { - $this->userRepository = $userRepository; - } + public function __construct(private readonly UserRepository $userRepository) {} public function getDependencies(): array { @@ -47,15 +38,15 @@ class LoadAsideActivity extends Fixture implements DependentFixtureInterface $activity = new AsideActivity(); $activity ->setAgent($user) - ->setCreatedAt(new DateTimeImmutable('now')) + ->setCreatedAt(new \DateTimeImmutable('now')) ->setCreatedBy($user) - ->setUpdatedAt(new DateTimeImmutable('now')) + ->setUpdatedAt(new \DateTimeImmutable('now')) ->setUpdatedBy($user) ->setType( $this->getReference('aside_activity_category_0') ) - ->setDate((new DateTimeImmutable('today')) - ->sub(new DateInterval('P' . random_int(1, 100) . 'D'))); + ->setDate((new \DateTimeImmutable('today')) + ->sub(new \DateInterval('P'.\random_int(1, 100).'D'))); $manager->persist($activity); } diff --git a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivityCategory.php b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivityCategory.php index 1d15adbc1..3e6b4247a 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivityCategory.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DataFixtures/ORM/LoadAsideActivityCategory.php @@ -27,7 +27,7 @@ class LoadAsideActivityCategory extends \Doctrine\Bundle\FixturesBundle\Fixture $category = new AsideActivityCategory(); $category->setTitle(['fr' => $label]); $manager->persist($category); - $this->setReference('aside_activity_category_' . $key, $category); + $this->setReference('aside_activity_category_'.$key, $category); } $manager->flush(); diff --git a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/ChillAsideActivityExtension.php b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/ChillAsideActivityExtension.php index 927de1845..056f29ba1 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/ChillAsideActivityExtension.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/ChillAsideActivityExtension.php @@ -26,7 +26,7 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte $container->setParameter('chill_aside_activity.form.time_duration', $config['form']['time_duration']); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/form.yaml'); $loader->load('services/menu.yaml'); @@ -100,7 +100,7 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte protected function prependRoute(ContainerBuilder $container) { - //declare routes for task bundle + // declare routes for task bundle $container->prependExtensionConfig('chill_main', [ 'routing' => [ 'resources' => [ diff --git a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php index 2e2398c3e..241a545a8 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/DependencyInjection/Configuration.php @@ -14,8 +14,6 @@ namespace Chill\AsideActivityBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; -use function is_int; - class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() @@ -132,7 +130,7 @@ class Configuration implements ConfigurationInterface ->info('The number of seconds of this duration. Must be an integer.') ->cannotBeEmpty() ->validate() - ->ifTrue(static fn ($data) => !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 412bb873e..2bb8a985d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivity.php @@ -15,19 +15,21 @@ use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\Location; -use DateTimeInterface; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Entity + * * @ORM\Table(schema="chill_asideactivity") */ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface { /** * @ORM\ManyToOne(targetEntity=User::class) + * * @ORM\JoinColumn(nullable=false) + * * @Assert\NotBlank */ private \Chill\MainBundle\Entity\User $agent; @@ -35,10 +37,11 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="datetime") */ - private $createdAt; + private ?\DateTimeInterface $createdAt = null; /** * @ORM\ManyToOne(targetEntity=User::class) + * * @ORM\JoinColumn(nullable=false) */ private \Chill\MainBundle\Entity\User $createdBy; @@ -46,22 +49,25 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="datetime") */ - private $date; + private ?\DateTimeInterface $date = null; /** * @ORM\Column(type="time", nullable=true) */ - private ?DateTimeInterface $duration = null; + private ?\DateTimeInterface $duration = null; /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ private ?int $id = null; /** * @ORM\ManyToOne(targetEntity=Location::class) + * * @ORM\JoinColumn(nullable=true) */ private ?Location $location = null; @@ -69,18 +75,19 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="text", nullable=true) */ - private $note; + private ?string $note = null; /** * @ORM\ManyToOne(targetEntity=AsideActivityCategory::class, inversedBy="asideActivities") + * * @ORM\JoinColumn(nullable=false) */ - private $type; + private ?\Chill\AsideActivityBundle\Entity\AsideActivityCategory $type = null; /** * @ORM\Column(type="datetime", nullable=true) */ - private $updatedAt; + private ?\DateTimeInterface $updatedAt = null; /** * @ORM\ManyToOne(targetEntity=User::class) @@ -92,7 +99,7 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this->agent; } - public function getCreatedAt(): ?DateTimeInterface + public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; } @@ -102,12 +109,12 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this->createdBy; } - public function getDate(): ?DateTimeInterface + public function getDate(): ?\DateTimeInterface { return $this->date; } - public function getDuration(): ?DateTimeInterface + public function getDuration(): ?\DateTimeInterface { return $this->duration; } @@ -132,7 +139,7 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this->type; } - public function getUpdatedAt(): ?DateTimeInterface + public function getUpdatedAt(): ?\DateTimeInterface { return $this->updatedAt; } @@ -149,7 +156,7 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setCreatedAt(DateTimeInterface $createdAt): self + public function setCreatedAt(\DateTimeInterface $createdAt): self { $this->createdAt = $createdAt; @@ -163,14 +170,14 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setDate(DateTimeInterface $date): self + public function setDate(\DateTimeInterface $date): self { $this->date = $date; return $this; } - public function setDuration(?DateTimeInterface $duration): self + public function setDuration(?\DateTimeInterface $duration): self { $this->duration = $duration; @@ -198,7 +205,7 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setUpdatedAt(DateTimeInterface $updatedAt): self + public function setUpdatedAt(\DateTimeInterface $updatedAt): self { $this->updatedAt = $updatedAt; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php index 6c12e5828..be71d73f9 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php @@ -19,24 +19,28 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * @ORM\Entity + * * @ORM\Table(schema="chill_asideactivity") */ class AsideActivityCategory { /** * @ORM\OneToMany(targetEntity=AsideActivityCategory::class, mappedBy="parent") + * + * @var Collection */ - private $children; + private Collection $children; /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ private int $id; /** - * @ORM\OneToMany(targetEntity=AsideActivityCategory::class, mappedBy="parent") * @ORM\Column(type="boolean") */ private bool $isActive = true; @@ -50,6 +54,7 @@ class AsideActivityCategory /** * @ORM\ManyToOne(targetEntity=AsideActivityCategory::class, inversedBy="children") + * * @ORM\JoinColumn(nullable=true) */ private ?AsideActivityCategory $parent = null; @@ -114,10 +119,8 @@ class AsideActivityCategory /** * @Assert\Callback - * - * @param mixed $payload */ - public function preventRecursiveParent(ExecutionContextInterface $context, $payload) + public function preventRecursiveParent(ExecutionContextInterface $context, mixed $payload) { if (!$this->hasParent()) { return; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php index 8ae43534d..4271ae118 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php @@ -20,15 +20,10 @@ use Symfony\Component\Form\FormBuilderInterface; class ByActivityTypeAggregator implements AggregatorInterface { - private AsideActivityCategoryRepository $asideActivityCategoryRepository; - - private TranslatableStringHelper $translatableStringHelper; - - public function __construct(AsideActivityCategoryRepository $asideActivityCategoryRepository, TranslatableStringHelper $translatableStringHelper) - { - $this->asideActivityCategoryRepository = $asideActivityCategoryRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly AsideActivityCategoryRepository $asideActivityCategoryRepository, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -50,6 +45,7 @@ class ByActivityTypeAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByLocationAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByLocationAggregator.php index 360e30efb..b5ca1022b 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByLocationAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByLocationAggregator.php @@ -14,33 +14,23 @@ namespace Chill\AsideActivityBundle\Export\Aggregator; use Chill\AsideActivityBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\LocationRepository; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; class ByLocationAggregator implements AggregatorInterface { - public function __construct(private LocationRepository $locationRepository) {} + public function __construct(private readonly LocationRepository $locationRepository) {} - /** - * @inheritDoc - */ public function buildForm(FormBuilderInterface $builder): void { // no form } - /** - * @inheritDoc - */ public function getFormDefaultData(): array { return []; } - /** - * @inheritDoc - */ public function getLabels($key, array $values, $data) { return function ($value): string { @@ -55,42 +45,27 @@ class ByLocationAggregator implements AggregatorInterface }; } - /** - * @inheritDoc - */ public function getQueryKeys($data): array { return ['by_aside_activity_location_aggregator']; } - /** - * @inheritDoc - */ public function getTitle(): string { return 'export.aggregator.Group by aside activity location'; } - /** - * @inheritDoc - */ public function addRole(): ?string { return null; } - /** - * @inheritDoc - */ public function alterQuery(QueryBuilder $qb, $data): void { $qb->addSelect('IDENTITY(aside.location) AS by_aside_activity_location_aggregator') ->addGroupBy('by_aside_activity_location_aggregator'); } - /** - * @inheritDoc - */ public function applyOn(): string { return Declarations::ASIDE_ACTIVITY_TYPE; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php index f09a704e2..c3883b18a 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php @@ -12,25 +12,22 @@ declare(strict_types=1); namespace Chill\AsideActivityBundle\Export\Aggregator; use Chill\AsideActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\UserJobRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; - class ByUserJobAggregator implements AggregatorInterface { - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'aside_act_agg_user_job'; - private UserJobRepositoryInterface $userJobRepository; - - public function __construct(UserJobRepositoryInterface $userJobRepository, TranslatableStringHelperInterface $translatableStringHelper) - { - $this->userJobRepository = $userJobRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly UserJobRepositoryInterface $userJobRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -39,24 +36,37 @@ class ByUserJobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('aside_user', $qb->getAllAliases(), true)) { - $qb->leftJoin('aside.agent', 'aside_user'); - } + $p = self::PREFIX; $qb - ->addSelect('IDENTITY(aside_user.userJob) AS aside_activity_user_job_aggregator') - ->addGroupBy('aside_activity_user_job_aggregator'); + ->leftJoin('aside.agent', "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // job_at based on aside.date + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'aside.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'aside.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.job) AS {$p}_select") + ->addGroupBy("{$p}_select"); } - public function applyOn() + public function applyOn(): string { return Declarations::ASIDE_ACTIVITY_TYPE; } - public function buildForm(FormBuilderInterface $builder) - { - // nothing to add in the form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -83,11 +93,11 @@ class ByUserJobAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['aside_activity_user_job_aggregator']; + return [self::PREFIX.'_select']; } - public function getTitle() + public function getTitle(): string { - return 'export.aggregator.Aggregate by user job'; + return 'export.aggregator.by_user_job.Aggregate by user job'; } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php index 3dd465db2..a99d2b75f 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php @@ -12,25 +12,22 @@ declare(strict_types=1); namespace Chill\AsideActivityBundle\Export\Aggregator; use Chill\AsideActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; - class ByUserScopeAggregator implements AggregatorInterface { - private ScopeRepositoryInterface $scopeRepository; + private const PREFIX = 'aside_act_agg_user_scope'; - private TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct(ScopeRepositoryInterface $scopeRepository, TranslatableStringHelperInterface $translatableStringHelper) - { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly ScopeRepositoryInterface $scopeRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -39,24 +36,36 @@ class ByUserScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('aside_user', $qb->getAllAliases(), true)) { - $qb->leftJoin('aside.agent', 'aside_user'); - } + $p = self::PREFIX; $qb - ->addSelect('IDENTITY(aside_user.mainScope) AS aside_activity_user_scope_aggregator') - ->addGroupBy('aside_activity_user_scope_aggregator'); + ->leftJoin('aside.agent', "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'aside.date'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'aside.date') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select") + ->addGroupBy("{$p}_select"); } - public function applyOn() + public function applyOn(): string { return Declarations::ASIDE_ACTIVITY_TYPE; } - public function buildForm(FormBuilderInterface $builder) - { - // nothing to add in the form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -83,11 +92,11 @@ class ByUserScopeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['aside_activity_user_scope_aggregator']; + return [self::PREFIX.'_select']; } - public function getTitle() + public function getTitle(): string { - return 'export.aggregator.Aggregate by user scope'; + return 'export.aggregator.by_user_scope.Aggregate by user scope'; } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Declarations.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Declarations.php index 8c808ea37..f86f78866 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Declarations.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Declarations.php @@ -16,5 +16,5 @@ namespace Chill\AsideActivityBundle\Export; */ abstract class Declarations { - public const ASIDE_ACTIVITY_TYPE = 'aside_activity'; + final public const ASIDE_ACTIVITY_TYPE = 'aside_activity'; } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php index 351cbb4ea..70922b6ae 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/AvgAsideActivityDuration.php @@ -18,20 +18,14 @@ use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterface { - private AsideActivityRepository $repository; - - public function __construct( - AsideActivityRepository $repository - ) { - $this->repository = $repository; - } + public function __construct(private readonly AsideActivityRepository $repository) {} public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -55,7 +49,7 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac 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"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Average duration aside activities' : $value; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php index a8bfcc3a2..6d1eed5fe 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/CountAsideActivity.php @@ -18,20 +18,14 @@ use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class CountAsideActivity implements ExportInterface, GroupedExportInterface { - private AsideActivityRepository $repository; - - public function __construct( - AsideActivityRepository $repository - ) { - $this->repository = $repository; - } + public function __construct(private readonly AsideActivityRepository $repository) {} public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -55,7 +49,7 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_result' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } $labels = array_combine($values, $values); diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php index b43ee6e01..33155c62f 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php @@ -26,51 +26,23 @@ use Chill\MainBundle\Repository\CenterRepositoryInterface; use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; -use DateTimeInterface; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; -final class ListAsideActivity implements ListInterface, GroupedExportInterface +final readonly class ListAsideActivity implements ListInterface, GroupedExportInterface { - private AsideActivityCategoryRepository $asideActivityCategoryRepository; - - private CategoryRender $categoryRender; - - private CenterRepositoryInterface $centerRepository; - - private DateTimeHelper $dateTimeHelper; - - private EntityManagerInterface $em; - - private ScopeRepositoryInterface $scopeRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private UserHelper $userHelper; - public function __construct( - EntityManagerInterface $em, - DateTimeHelper $dateTimeHelper, - UserHelper $userHelper, - ScopeRepositoryInterface $scopeRepository, - CenterRepositoryInterface $centerRepository, - AsideActivityCategoryRepository $asideActivityCategoryRepository, - CategoryRender $categoryRender, + private EntityManagerInterface $em, + private DateTimeHelper $dateTimeHelper, + private UserHelper $userHelper, + private ScopeRepositoryInterface $scopeRepository, + private CenterRepositoryInterface $centerRepository, + private AsideActivityCategoryRepository $asideActivityCategoryRepository, + private CategoryRender $categoryRender, private LocationRepository $locationRepository, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->em = $em; - $this->dateTimeHelper = $dateTimeHelper; - $this->userHelper = $userHelper; - $this->scopeRepository = $scopeRepository; - $this->centerRepository = $centerRepository; - $this->asideActivityCategoryRepository = $asideActivityCategoryRepository; - $this->categoryRender = $categoryRender; - $this->translatableStringHelper = $translatableStringHelper; - } + private TranslatableStringHelperInterface $translatableStringHelper + ) {} public function buildForm(FormBuilderInterface $builder) {} @@ -96,99 +68,78 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface 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 match ($key) { + 'id', 'note' => static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.aside_activity.'.$key; + } - return $value ?? ''; - }; + return $value ?? ''; + }, + 'duration' => static function ($value) use ($key) { + if ('_header' === $value) { + return 'export.aside_activity.'.$key; + } - case 'duration': - return static function ($value) use ($key) { - if ('_header' === $value) { - return 'export.aside_activity.' . $key; - } + if (null === $value) { + return ''; + } - if (null === $value) { - return ''; - } + if ($value instanceof \DateTimeInterface) { + return $value->format('H:i:s'); + } - if ($value instanceof DateTimeInterface) { - return $value->format('H:i:s'); - } + return $value; + }, + 'createdAt', 'updatedAt', 'date' => $this->dateTimeHelper->getLabel('export.aside_activity.'.$key), + 'agent_id', 'creator_id' => $this->userHelper->getLabel($key, $values, 'export.aside_activity.'.$key), + 'aside_activity_type' => function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.aside_activity_type'; + } - return $value; - }; + if (null === $value || '' === $value || null === $c = $this->asideActivityCategoryRepository->find($value)) { + return ''; + } - case 'createdAt': - case 'updatedAt': - case 'date': - return $this->dateTimeHelper->getLabel('export.aside_activity.' . $key); + return $this->categoryRender->renderString($c, []); + }, + 'location' => function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.location'; + } - case 'agent_id': - case 'creator_id': - return $this->userHelper->getLabel($key, $values, 'export.aside_activity.' . $key); + if (null === $value || '' === $value || null === $l = $this->locationRepository->find($value)) { + return ''; + } - case 'aside_activity_type': - return function ($value) { - if ('_header' === $value) { - return 'export.aside_activity.aside_activity_type'; - } + return $l->getName(); + }, + 'main_scope' => function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.main_scope'; + } - if (null === $value || '' === $value || null === $c = $this->asideActivityCategoryRepository->find($value)) { - return ''; - } + if (null === $value || '' === $value || null === $c = $this->scopeRepository->find($value)) { + return ''; + } - return $this->categoryRender->renderString($c, []); - }; + return $this->translatableStringHelper->localize($c->getName()); + }, + 'main_center' => function ($value) { + if ('_header' === $value) { + return 'export.aside_activity.main_center'; + } - case 'location': - return function ($value) { - if ('_header' === $value) { - return 'export.aside_activity.location'; - } + if (null === $value || '' === $value || null === $c = $this->centerRepository->find($value)) { + /* @var Center $c */ + return ''; + } - if (null === $value || '' === $value || null === $l = $this->locationRepository->find($value)) { - return ''; - } - - return $l->getName(); - }; - - 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); - } + return $c->getName(); + }, + default => throw new \LogicException('this key is not supported : '.$key), + }; } public function getQueryKeys($data) @@ -228,7 +179,10 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface { $qb = $this->em->createQueryBuilder() ->from(AsideActivity::class, 'aside') - ->leftJoin('aside.agent', 'agent'); + ->leftJoin('aside.agent', 'agent') + ->leftJoin('agent.scopeHistories', 'scopeHistories') + ->andWhere('scopeHistories.startDate <= aside.date AND (scopeHistories.endDate IS NULL or scopeHistories.endDate > aside.date)') + ; $qb ->addSelect('aside.id AS id') @@ -236,7 +190,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface ->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(scopeHistories.scope) AS main_scope') ->addSelect('IDENTITY(agent.mainCenter) AS main_center') ->addSelect('IDENTITY(aside.type) AS aside_activity_type') ->addSelect('aside.date') diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php index 87f4a3dc3..0fd318902 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/SumAsideActivityDuration.php @@ -18,20 +18,14 @@ use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Doctrine\ORM\Query; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class SumAsideActivityDuration implements ExportInterface, GroupedExportInterface { - private AsideActivityRepository $repository; - - public function __construct( - AsideActivityRepository $repository - ) { - $this->repository = $repository; - } + public function __construct(private readonly AsideActivityRepository $repository) {} public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; @@ -55,7 +49,7 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac 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"); + throw new \LogicException("the key {$key} is not used by this export"); } return static fn ($value) => '_header' === $value ? 'Sum duration aside activities' : $value; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php index 3d389f5b3..b78640d49 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php @@ -23,21 +23,11 @@ use Symfony\Component\Form\FormBuilderInterface; class ByActivityTypeFilter implements FilterInterface { - private AsideActivityCategoryRepository $asideActivityTypeRepository; - - private CategoryRender $categoryRender; - - private TranslatableStringHelperInterface $translatableStringHelper; - public function __construct( - CategoryRender $categoryRender, - TranslatableStringHelperInterface $translatableStringHelper, - AsideActivityCategoryRepository $asideActivityTypeRepository - ) { - $this->categoryRender = $categoryRender; - $this->asideActivityTypeRepository = $asideActivityTypeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly CategoryRender $categoryRender, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly AsideActivityCategoryRepository $asideActivityTypeRepository + ) {} public function addRole(): ?string { @@ -76,6 +66,7 @@ class ByActivityTypeFilter implements FilterInterface }, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php index 98a254bc4..8f3c9c305 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php @@ -26,17 +26,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ByDateFilter implements FilterInterface { - protected TranslatorInterface $translator; - - private RollingDateConverterInterface $rollingDateConverter; - - public function __construct( - RollingDateConverterInterface $rollingDateConverter, - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->rollingDateConverter = $rollingDateConverter; - } + public function __construct(private readonly RollingDateConverterInterface $rollingDateConverter, protected TranslatorInterface $translator) {} public function addRole(): ?string { @@ -92,14 +82,14 @@ class ByDateFilter implements FilterInterface if (null === $date_from) { $form->get('date_from')->addError(new FormError( $this->translator->trans('This field ' - . 'should not be empty') + .'should not be empty') )); } if (null === $date_to) { $form->get('date_to')->addError(new FormError( $this->translator->trans('This field ' - . 'should not be empty') + .'should not be empty') )); } @@ -110,13 +100,14 @@ class ByDateFilter implements FilterInterface ) { $form->get('date_to')->addError(new FormError( $this->translator->trans('export.filter.This date should be after ' - . 'the date given in "Implied in an aside activity after ' - . 'this date" field') + .'the date given in "Implied in an aside activity after ' + .'this date" field') )); } } }); } + public function getFormDefaultData(): array { return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByLocationFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByLocationFilter.php index a1f51273c..0be041dc9 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByLocationFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByLocationFilter.php @@ -16,9 +16,7 @@ use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\PickUserLocationType; -use Chill\MainBundle\Repository\LocationRepository; use Doctrine\ORM\QueryBuilder; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Security\Core\Security; @@ -28,26 +26,17 @@ final readonly class ByLocationFilter implements FilterInterface private Security $security ) {} - /** - * @inheritDoc - */ public function getTitle(): string { return 'export.filter.Filter by aside activity location'; } - /** - * @inheritDoc - */ public function buildForm(FormBuilderInterface $builder): void { $builder ->add('locations', PickUserLocationType::class); } - /** - * @inheritDoc - */ public function getFormDefaultData(): array { $user = $this->security->getUser(); @@ -63,9 +52,6 @@ final readonly class ByLocationFilter implements FilterInterface ]; } - /** - * @inheritDoc - */ public function describeAction($data, $format = 'string'): array { $locations = $data['locations']->map(fn (Location $l): string => $l->getName()); @@ -75,17 +61,11 @@ final readonly class ByLocationFilter implements FilterInterface ]]; } - /** - * @inheritDoc - */ public function addRole(): ?string { return null; } - /** - * @inheritDoc - */ public function alterQuery(QueryBuilder $qb, $data): void { $clause = $qb->expr()->in('aside.location', ':locations'); @@ -94,9 +74,6 @@ final readonly class ByLocationFilter implements FilterInterface $qb->setParameter('locations', $data['locations']); } - /** - * @inheritDoc - */ public function applyOn(): string { return Declarations::ASIDE_ACTIVITY_TYPE; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php index 2858d3417..8dd1a8eac 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php @@ -20,12 +20,7 @@ use Symfony\Component\Form\FormBuilderInterface; class ByUserFilter implements FilterInterface { - private UserRender $userRender; - - public function __construct(UserRender $userRender) - { - $this->userRender = $userRender; - } + public function __construct(private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -53,6 +48,7 @@ class ByUserFilter implements FilterInterface 'label' => 'Creators', ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php index 55f477768..3d5bb6530 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php @@ -13,6 +13,7 @@ namespace Chill\AsideActivityBundle\Export\Filter; use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\AsideActivityBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; @@ -22,12 +23,11 @@ use Symfony\Component\Form\FormBuilderInterface; class ByUserJobFilter implements FilterInterface { - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'aside_act_filter_user_job'; - public function __construct(TranslatableStringHelperInterface $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -36,38 +36,46 @@ class ByUserJobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { + $p = self::PREFIX; + $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' + 'SELECT 1 FROM '.AsideActivity::class." {$p}_act " + ."JOIN {$p}_act.agent {$p}_user " + .'JOIN '.UserJobHistory::class." {$p}_history WITH {$p}_history.user = {$p}_user " + ."WHERE {$p}_act = aside " + // job_at based on aside.date + ."AND {$p}_history.startDate <= aside.date " + ."AND ({$p}_history.endDate IS NULL OR {$p}_history.endDate > aside.date) " + ."AND {$p}_history.job IN ( :{$p}_jobs )" ) ) - ->setParameter('aside_activity_user_job_filter_jobs', $data['jobs']); + ->setParameter( + "{$p}_jobs", + $data['jobs'], + ); } - public function applyOn() + public function applyOn(): string { 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 getFormDefaultData(): array - { - return []; + $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') + public function describeAction($data, $format = 'string'): array { - return ['export.filter.Filtered aside activities by user jobs: only %jobs%', [ + return ['export.filter.by_user_job.Filtered aside activities by user jobs: only %jobs%', [ '%jobs%' => implode( ', ', array_map( @@ -78,8 +86,15 @@ class ByUserJobFilter implements FilterInterface ]]; } - public function getTitle() + public function getFormDefaultData(): array { - return 'export.filter.Filter by user jobs'; + return [ + 'jobs' => [], + ]; + } + + public function getTitle(): string + { + return 'export.filter.by_user_job.Filter by user jobs'; } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php index 8fa51866d..846814785 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php @@ -14,6 +14,7 @@ namespace Chill\AsideActivityBundle\Export\Filter; use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\AsideActivityBundle\Export\Declarations; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; @@ -23,17 +24,12 @@ use Symfony\Component\Form\FormBuilderInterface; class ByUserScopeFilter implements FilterInterface { - private ScopeRepositoryInterface $scopeRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; + private const PREFIX = 'aside_act_filter_user_scope'; public function __construct( - ScopeRepositoryInterface $scopeRepository, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly ScopeRepositoryInterface $scopeRepository, + private readonly TranslatableStringHelperInterface $translatableStringHelper + ) {} public function addRole(): ?string { @@ -42,39 +38,47 @@ class ByUserScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { + $p = self::PREFIX; + $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 ' + 'SELECT 1 FROM '.AsideActivity::class." {$p}_act " + ."JOIN {$p}_act.agent {$p}_user " + .'JOIN '.UserScopeHistory::class." {$p}_history WITH {$p}_history.user = {$p}_user " + ."WHERE {$p}_act = aside " + // scope_at based on aside.date + ."AND {$p}_history.startDate <= aside.date " + ."AND ({$p}_history.endDate IS NULL OR {$p}_history.endDate > aside.date) " + ."AND {$p}_history.scope IN ( :{$p}_scopes )" ) ) - ->setParameter('aside_activity_user_scope_filter_scopes', $data['scopes']); + ->setParameter( + "{$p}_scopes", + $data['scopes'], + ); } - public function applyOn() + public function applyOn(): string { 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 getFormDefaultData(): array - { - return []; + $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%', [ + return ['export.filter.by_user_scope.Filtered aside activities by user scope: only %scopes%', [ '%scopes%' => implode( ', ', array_map( @@ -85,8 +89,15 @@ class ByUserScopeFilter implements FilterInterface ]]; } - public function getTitle() + public function getFormDefaultData(): array { - return 'export.filter.Filter by user scope'; + return [ + 'scopes' => [], + ]; + } + + public function getTitle(): string + { + return 'export.filter.by_user_scope.Filter by user scope'; } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php index c183fcea6..3a69be137 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php @@ -22,13 +22,7 @@ use Symfony\Component\Form\FormBuilderInterface; final class AsideActivityCategoryType extends AbstractType { - private CategoryRender $categoryRender; - - public function __construct( - CategoryRender $categoryRender - ) { - $this->categoryRender = $categoryRender; - } + public function __construct(private readonly CategoryRender $categoryRender) {} public function buildForm(FormBuilderInterface $builder, array $options) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php index 2a6068424..d6fcb821c 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php @@ -13,16 +13,10 @@ namespace Chill\AsideActivityBundle\Form; use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\AsideActivityBundle\Form\Type\PickAsideActivityCategoryType; -use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillTextareaType; use Chill\MainBundle\Form\Type\PickUserDynamicType; use Chill\MainBundle\Form\Type\PickUserLocationType; -use DateInterval; -use DateTime; -use DateTimeImmutable; -use DateTimeZone; -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; @@ -32,11 +26,9 @@ use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; -use function in_array; - final class AsideActivityFormType extends AbstractType { - private array $timeChoices; + private readonly array $timeChoices; public function __construct( ParameterBagInterface $parameterBag, @@ -68,7 +60,7 @@ final class AsideActivityFormType extends AbstractType ChillDateType::class, [ 'label' => 'date', - 'data' => new DateTime(), + 'data' => new \DateTime(), 'required' => true, ] ) @@ -98,25 +90,19 @@ final class AsideActivityFormType extends AbstractType ) { // set the timezone to GMT, and fix the difference between current and GMT // the datetimetransformer will then handle timezone as GMT - $timezoneUTC = new DateTimeZone('GMT'); - /** @var DateTimeImmutable $data */ - $data = $formEvent->getData() ?? DateTime::createFromFormat('U', '300'); + $timezoneUTC = new \DateTimeZone('GMT'); + /** @var \DateTimeImmutable $data */ + $data = $formEvent->getData() ?? \DateTime::createFromFormat('U', '300'); $seconds = $data->getTimezone()->getOffset($data); $data->setTimeZone($timezoneUTC); - $data->add(new DateInterval('PT' . $seconds . 'S')); + $data->add(new \DateInterval('PT'.$seconds.'S')); // test if the timestamp is in the choices. // If not, recreate the field with the new timestamp - if (!in_array($data->getTimestamp(), $timeChoices, true)) { + if (!\in_array($data->getTimestamp(), $timeChoices, true)) { // the data are not in the possible values. add them $timeChoices[$data->format('H:i')] = $data->getTimestamp(); - $form = $builder->create($fieldName, ChoiceType::class, array_merge( - $durationTimeOptions, - [ - 'choices' => $timeChoices, - 'auto_initialize' => false, - ] - )); + $form = $builder->create($fieldName, ChoiceType::class, [...$durationTimeOptions, 'choices' => $timeChoices, 'auto_initialize' => false]); $form->addModelTransformer($durationTimeTransformer); $formEvent->getForm()->getParent()->add($form->getForm()); } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php index 3ee392517..23923fb6c 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/Type/PickAsideActivityCategoryType.php @@ -20,13 +20,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class PickAsideActivityCategoryType extends AbstractType { - private CategoryRender $categoryRender; - - public function __construct( - CategoryRender $categoryRender - ) { - $this->categoryRender = $categoryRender; - } + public function __construct(private readonly CategoryRender $categoryRender) {} public function configureOptions(OptionsResolver $resolver) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php b/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php index 8cc076a6e..43a37e068 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php @@ -14,14 +14,9 @@ namespace Chill\AsideActivityBundle\Menu; use Knp\Menu\MenuItem; use Symfony\Component\Security\Core\Security; -final class AdminMenuBuilder implements \Chill\MainBundle\Routing\LocalMenuBuilderInterface +final readonly class AdminMenuBuilder implements \Chill\MainBundle\Routing\LocalMenuBuilderInterface { - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; - } + public function __construct(private Security $security) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php index f23fcdc8a..a32d52303 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php @@ -21,19 +21,8 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class SectionMenuBuilder implements LocalMenuBuilderInterface { - public AuthorizationCheckerInterface $authorizationChecker; + public function __construct(protected TranslatorInterface $translator, public AuthorizationCheckerInterface $authorizationChecker) {} - protected TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator, AuthorizationCheckerInterface $authorizationChecker) - { - $this->translator = $translator; - $this->authorizationChecker = $authorizationChecker; - } - - /** - * @param $menuId - */ public function buildMenu($menuId, MenuItem $menu, array $parameters) { if ($this->authorizationChecker->isGranted('ROLE_USER')) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Repository/AsideActivityCategoryRepository.php b/src/Bundle/ChillAsideActivityBundle/src/Repository/AsideActivityCategoryRepository.php index 918cec586..533e567b4 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Repository/AsideActivityCategoryRepository.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Repository/AsideActivityCategoryRepository.php @@ -18,7 +18,7 @@ use Doctrine\Persistence\ObjectRepository; class AsideActivityCategoryRepository implements ObjectRepository { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -49,7 +49,7 @@ class AsideActivityCategoryRepository implements ObjectRepository * * @return AsideActivityCategory[] */ - public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array + public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Security/AsideActivityVoter.php b/src/Bundle/ChillAsideActivityBundle/src/Security/AsideActivityVoter.php index 6b308b5f2..e15abd439 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Security/AsideActivityVoter.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Security/AsideActivityVoter.php @@ -21,9 +21,9 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class AsideActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const STATS = 'CHILL_ASIDE_ACTIVITY_STATS'; + final public const STATS = 'CHILL_ASIDE_ACTIVITY_STATS'; - private VoterHelperInterface $voterHelper; + private readonly VoterHelperInterface $voterHelper; public function __construct( VoterHelperFactoryInterface $voterHelperFactory diff --git a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php index 066a0ca52..2598c4e01 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php @@ -14,12 +14,11 @@ namespace Chill\AsideActivityBundle\Templating\Entity; use Chill\AsideActivityBundle\Entity\AsideActivityCategory; use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Symfony\Component\Templating\EngineInterface; /** * @implements ChillEntityRenderInterface */ -final class CategoryRender implements ChillEntityRenderInterface +final readonly class CategoryRender implements ChillEntityRenderInterface { public const DEFAULT_ARGS = [ self::SEPERATOR_KEY => ' > ', @@ -27,15 +26,7 @@ final class CategoryRender implements ChillEntityRenderInterface public const SEPERATOR_KEY = 'default.separator'; - private EngineInterface $engine; - - private TranslatableStringHelper $translatableStringHelper; - - public function __construct(TranslatableStringHelper $translatableStringHelper, EngineInterface $engine) - { - $this->translatableStringHelper = $translatableStringHelper; - $this->engine = $engine; - } + public function __construct(private TranslatableStringHelper $translatableStringHelper, private \Twig\Environment $engine) {} public function buildParents(AsideActivityCategory $asideActivityCategory) { diff --git a/src/Bundle/ChillAsideActivityBundle/src/Tests/Controller/AsideActivityControllerTest.php b/src/Bundle/ChillAsideActivityBundle/src/Tests/Controller/AsideActivityControllerTest.php index 196dd5bc3..4a772775f 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Tests/Controller/AsideActivityControllerTest.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Tests/Controller/AsideActivityControllerTest.php @@ -15,25 +15,22 @@ use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\MainBundle\Test\PrepareClientTrait; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; -use function array_pop; -use function shuffle; /** * @internal + * * @coversNothing */ final class AsideActivityControllerTest extends WebTestCase { use PrepareClientTrait; - protected function setUp(): void + protected function tearDown(): void { - parent::setUp(); - self::bootKernel(); - $this->client = $this->getClientAuthenticated(); + self::ensureKernelShutdown(); } - public function generateAsideActivityId() + public function generateAsideActivityId(): iterable { self::bootKernel(); @@ -50,13 +47,15 @@ final class AsideActivityControllerTest extends WebTestCase ->getQuery() ->getResult(); - shuffle($asideActivityIds); + \shuffle($asideActivityIds); - yield [array_pop($asideActivityIds)['id']]; + yield [\array_pop($asideActivityIds)['id']]; - yield [array_pop($asideActivityIds)['id']]; + yield [\array_pop($asideActivityIds)['id']]; - yield [array_pop($asideActivityIds)['id']]; + yield [\array_pop($asideActivityIds)['id']]; + + self::ensureKernelShutdown(); } /** @@ -64,22 +63,28 @@ final class AsideActivityControllerTest extends WebTestCase */ public function testEditWithoutUsers(int $asideActivityId) { - $this->client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit"); + self::ensureKernelShutdown(); + $client = $this->getClientAuthenticated(); + $client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit"); - $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); } public function testIndexWithoutUsers() { - $this->client->request('GET', '/fr/asideactivity'); + self::ensureKernelShutdown(); + $client = $this->getClientAuthenticated(); + $client->request('GET', '/fr/asideactivity'); - $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); } public function testNewWithoutUsers() { - $this->client->request('GET', '/fr/asideactivity/new'); + self::ensureKernelShutdown(); + $client = $this->getClientAuthenticated(); + $client->request('GET', '/fr/asideactivity/new'); - $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Tests/Export/Export/ListAsideActivityTest.php b/src/Bundle/ChillAsideActivityBundle/src/Tests/Export/Export/ListAsideActivityTest.php new file mode 100644 index 000000000..29ea8d1f6 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Tests/Export/Export/ListAsideActivityTest.php @@ -0,0 +1,43 @@ +listAsideActivity = self::$container->get(ListAsideActivity::class); + } + + public function testExecuteQuery(): void + { + $qb = $this->listAsideActivity->initiateQuery([], [], []) + ->setMaxResults(1); + + $results = $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY); + + self::assertIsArray($results, 'smoke test: test that the result is an array'); + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/config/routes.yaml b/src/Bundle/ChillAsideActivityBundle/src/config/routes.yaml index ddb635084..0a193b990 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/config/routes.yaml +++ b/src/Bundle/ChillAsideActivityBundle/src/config/routes.yaml @@ -1,12 +1,3 @@ chill_asideactivities_controllers: resource: "@ChillAsideActivityBundle/Controller" type: annotation - -chill_admin_aside_activity_redirect_to_admin_index: - path: /{_locale}/admin/activity_redirect_to_main - controller: Chill\ActivityBundle\Controller\AdminController::redirectToAdminIndexAction - options: - menus: - admin_aside_activity: - order: 0 - label: Main admin menu diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml index 6028193db..0a324d2cd 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml @@ -200,17 +200,21 @@ export: 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 + by_user_job: + '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 + by_user_scope: + 'Filtered aside activities by user scope: only %scopes%': "Filtré par service des utilisateurs: uniquement %scopes%" + Filter by user scope: Filtrer les activités annexes par service d'utilisateur Filter by aside activity location: Filtrer les activités annexes par localisation 'Filtered by aside activity location: only %location%': "Filtré par localisation: uniquement %location%" 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 + by_user_job: + Aggregate by user job: Grouper les activités annexes par métier des utilisateurs + by_user_scope: + Aggregate by user scope: Grouper les activités annexes par service des utilisateurs Aside activity location: Localisation des activités annexe Group by aside activity location: Grouper les activités annexes par localisation Aside activity localisation: Localisation diff --git a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php index 2662b896a..3b5a687a6 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorInterface.php @@ -17,7 +17,7 @@ use Chill\BudgetBundle\Entity\Resource; interface CalculatorInterface { /** - * @param array $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 7987bdfdf..477f23189 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorManager.php @@ -11,14 +11,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; -use function array_keys; -use function implode; class CalculatorManager { @@ -42,7 +36,7 @@ class CalculatorManager } /** - * @param array $elements + * @param array $elements * * @return CalculatorResult[] */ @@ -63,9 +57,8 @@ class CalculatorManager public function getCalculator(string $alias): CalculatorInterface { - if (false === array_key_exists($alias, $this->calculators)) { - throw new OutOfBoundsException("The calculator with alias '{$alias}' does " - . 'not exists. Possible values are ' . implode(', ', array_keys($this->calculators))); + if (false === \array_key_exists($alias, $this->calculators)) { + throw new \OutOfBoundsException("The calculator with alias '{$alias}' does ".'not exists. Possible values are '.\implode(', ', \array_keys($this->calculators))); } return $this->calculators[$alias]; diff --git a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php index 2a67486f0..ce31dcaaf 100644 --- a/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php +++ b/src/Bundle/ChillBudgetBundle/Calculator/CalculatorResult.php @@ -13,11 +13,11 @@ namespace Chill\BudgetBundle\Calculator; class CalculatorResult { - public const TYPE_CURRENCY = 'currency'; + final public const TYPE_CURRENCY = 'currency'; - public const TYPE_PERCENTAGE = 'percentage'; + final public const TYPE_PERCENTAGE = 'percentage'; - public const TYPE_RATE = 'rate'; + final public const TYPE_RATE = 'rate'; public $label; diff --git a/src/Bundle/ChillBudgetBundle/ChillBudgetBundle.php b/src/Bundle/ChillBudgetBundle/ChillBudgetBundle.php index 30bf1e68a..71f6a7076 100644 --- a/src/Bundle/ChillBudgetBundle/ChillBudgetBundle.php +++ b/src/Bundle/ChillBudgetBundle/ChillBudgetBundle.php @@ -20,6 +20,6 @@ class ChillBudgetBundle extends Bundle { parent::build($container); - $container->addCompilerPass(new CalculatorCompilerPass()); + $container->addCompilerPass(new CalculatorCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); } } diff --git a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php index 125c72ce4..38d4d82f5 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php @@ -23,39 +23,20 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Contracts\Translation\TranslatorInterface; -use function get_class; - abstract class AbstractElementController extends AbstractController { - protected LoggerInterface $chillMainLogger; - - protected EntityManagerInterface $em; - - protected TranslatorInterface $translator; - - public function __construct( - EntityManagerInterface $em, - TranslatorInterface $translator, - LoggerInterface $chillMainLogger - ) { - $this->em = $em; - $this->translator = $translator; - $this->chillMainLogger = $chillMainLogger; - } + public function __construct(protected EntityManagerInterface $em, protected TranslatorInterface $translator, protected LoggerInterface $chillMainLogger) {} /** * Route( * "{_locale}/family-members/family-members/{id}/delete", * name="chill_family_members_family_members_delete" * ). - * - * @param mixed $template - * @param mixed $flashMessage */ - protected function _delete(AbstractElement $element, Request $request, $template, $flashMessage): Response + protected function _delete(AbstractElement $element, Request $request, mixed $template, mixed $flashMessage): Response { $this->denyAccessUnlessGranted(BudgetElementVoter::DELETE, $element, 'You are not ' - . 'allowed to delete this item'); + .'allowed to delete this item'); $form = $this->createDeleteForm(); @@ -67,12 +48,12 @@ abstract class AbstractElementController extends AbstractController $indexPage = 'chill_budget_elements_household_index'; } - if ($request->getMethod() === Request::METHOD_DELETE) { + if (Request::METHOD_DELETE === $request->getMethod()) { $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $this->chillMainLogger->notice('A budget element has been removed', [ - 'family_element' => get_class($element), + 'family_element' => $element::class, 'by_user' => $this->getUser()->getUsername(), 'family_member_id' => $element->getId(), 'amount' => $element->getAmount(), @@ -141,12 +122,7 @@ abstract class AbstractElementController extends AbstractController ]); } - /** - * @param mixed $template - * @param mixed $flashMessageOnSuccess - * @param mixed $entity - */ - protected function _new($entity, Request $request, $template, $flashMessageOnSuccess) + protected function _new(mixed $entity, Request $request, mixed $template, mixed $flashMessageOnSuccess) { /** @var AbstractElement $element */ $element = $this->createNewElement(); @@ -196,10 +172,8 @@ abstract class AbstractElementController extends AbstractController * "{_locale}/family-members/family-members/{id}/view", * name="chill_family_members_family_members_view" * ). - * - * @param mixed $template */ - protected function _view(AbstractElement $element, $template) + protected function _view(AbstractElement $element, mixed $template) { $this->denyAccessUnlessGranted(BudgetElementVoter::SEE, $element); diff --git a/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php b/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php index e1989176d..642b7cc61 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/Admin/ChargeKindController.php @@ -20,7 +20,7 @@ class ChargeKindController extends CRUDController { protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var QueryBuilder $query */ + /* @var QueryBuilder $query */ $query->addOrderBy('e.ordering', 'ASC'); return $query; diff --git a/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php b/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php index 90b8e750a..0762f8252 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/Admin/ResourceKindController.php @@ -20,7 +20,7 @@ class ResourceKindController extends CRUDController { protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) { - /** @var QueryBuilder $query */ + /* @var QueryBuilder $query */ $query->addOrderBy('e.ordering', 'ASC'); return $query; diff --git a/src/Bundle/ChillBudgetBundle/Controller/ChargeController.php b/src/Bundle/ChillBudgetBundle/Controller/ChargeController.php index 5d4a8b3a4..39e96d4a8 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/ChargeController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/ChargeController.php @@ -15,18 +15,14 @@ use Chill\BudgetBundle\Entity\Charge; use Chill\BudgetBundle\Form\ChargeType; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Component\HttpFoundation\Request; class ChargeController extends AbstractElementController { /** - * @Route( - * "{_locale}/budget/charge/{id}/delete", - * name="chill_budget_charge_delete" - * ) - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/charge/{id}/delete", name="chill_budget_charge_delete") */ public function deleteAction(Request $request, Charge $charge) { @@ -39,12 +35,9 @@ class ChargeController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/charge/{id}/edit", - * name="chill_budget_charge_edit" - * ) - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/charge/{id}/edit", name="chill_budget_charge_edit") */ public function editAction(Request $request, Charge $charge) { @@ -57,12 +50,9 @@ class ChargeController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/charge/by-person/{id}/new", - * name="chill_budget_charge_new" - * ) - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/charge/by-person/{id}/new", name="chill_budget_charge_new") */ public function newAction(Request $request, Person $person) { @@ -75,12 +65,9 @@ class ChargeController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/charge/by-household/{id}/new", - * name="chill_budget_charge_household_new" - * ) - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/charge/by-household/{id}/new", name="chill_budget_charge_household_new") */ public function newHouseholdAction(Request $request, Household $household) { @@ -93,12 +80,9 @@ class ChargeController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/charge/{id}/view", - * name="chill_budget_charge_view" - * ) - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/charge/{id}/view", name="chill_budget_charge_view") */ public function viewAction(Charge $charge) { diff --git a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php index b5db3cd30..26acbf8a5 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php @@ -12,46 +12,19 @@ declare(strict_types=1); 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; -use DateTime; -use Doctrine\ORM\EntityManagerInterface; -use Psr\Log\LoggerInterface; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Contracts\Translation\TranslatorInterface; - -use function array_merge; -use function count; class ElementController extends AbstractController { - private CalculatorManager $calculator; - - private ResourceRepository $resourceRepository; - - private ChargeRepository $chargeRepository; - - public function __construct( - CalculatorManager $calculator, - ResourceRepository $resourceRepository, - ChargeRepository $chargeRepository, - ) { - $this->calculator = $calculator; - $this->resourceRepository = $resourceRepository; - $this->chargeRepository = $chargeRepository; - } + public function __construct(private readonly CalculatorManager $calculator, private readonly ResourceRepository $resourceRepository, private readonly ChargeRepository $chargeRepository) {} /** - * @Route( - * "{_locale}/budget/elements/by-person/{id}", - * name="chill_budget_elements_index" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/elements/by-person/{id}", name="chill_budget_elements_index") */ public function indexAction(Person $person) { @@ -60,13 +33,13 @@ class ElementController extends AbstractController $charges = $this->chargeRepository->findAllByEntity($person); $resources = $this->resourceRepository->findAllByEntity($person); - $elements = array_merge($charges, $resources); + $elements = \array_merge($charges, $resources); - if (count($elements) > 0) { + if (\count($elements) > 0) { $results = $this->calculator->calculateDefault($elements); } - return $this->render('ChillBudgetBundle:Person:index.html.twig', [ + return $this->render('@ChillBudget/Person/index.html.twig', [ 'person' => $person, 'charges' => $charges, 'resources' => $resources, @@ -75,10 +48,7 @@ class ElementController extends AbstractController } /** - * @Route( - * "{_locale}/budget/elements/by-household/{id}", - * name="chill_budget_elements_household_index" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/elements/by-household/{id}", name="chill_budget_elements_household_index") */ public function indexHouseholdAction(Household $household) { @@ -87,13 +57,13 @@ class ElementController extends AbstractController $charges = $this->chargeRepository->findAllByEntity($household); $resources = $this->resourceRepository->findAllByEntity($household); - $elements = array_merge($charges, $resources); + $elements = \array_merge($charges, $resources); - if (count($elements) > 0) { + if (\count($elements) > 0) { $results = $this->calculator->calculateDefault($elements); } - return $this->render('ChillBudgetBundle:Household:index.html.twig', [ + return $this->render('@ChillBudget/Household/index.html.twig', [ 'household' => $household, 'charges' => $charges, 'resources' => $resources, diff --git a/src/Bundle/ChillBudgetBundle/Controller/ResourceController.php b/src/Bundle/ChillBudgetBundle/Controller/ResourceController.php index e7f1e9ff3..f67d92a43 100644 --- a/src/Bundle/ChillBudgetBundle/Controller/ResourceController.php +++ b/src/Bundle/ChillBudgetBundle/Controller/ResourceController.php @@ -15,17 +15,13 @@ use Chill\BudgetBundle\Entity\Resource; use Chill\BudgetBundle\Form\ResourceType; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class ResourceController extends AbstractElementController { /** - * @Route( - * "{_locale}/budget/resource/{id}/delete", - * name="chill_budget_resource_delete" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/resource/{id}/delete", name="chill_budget_resource_delete") */ public function deleteAction(Request $request, Resource $resource) { @@ -38,10 +34,7 @@ class ResourceController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/resource/{id}/edit", - * name="chill_budget_resource_edit" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/resource/{id}/edit", name="chill_budget_resource_edit") */ public function editAction(Request $request, Resource $resource): Response { @@ -56,10 +49,7 @@ class ResourceController extends AbstractElementController /** * Create a new budget element for a person. * - * @Route( - * "{_locale}/budget/resource/by-person/{id}/new", - * name="chill_budget_resource_new" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/resource/by-person/{id}/new", name="chill_budget_resource_new") */ public function newAction(Request $request, Person $person): Response { @@ -74,10 +64,7 @@ class ResourceController extends AbstractElementController /** * Create new budget element for a household. * - * @Route( - * "{_locale}/budget/resource/by-household/{id}/new", - * name="chill_budget_resource_household_new" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/resource/by-household/{id}/new", name="chill_budget_resource_household_new") */ public function newHouseholdAction(Request $request, Household $household): Response { @@ -90,10 +77,7 @@ class ResourceController extends AbstractElementController } /** - * @Route( - * "{_locale}/budget/resource/{id}/view", - * name="chill_budget_resource_view" - * ) + * @\Symfony\Component\Routing\Annotation\Route("{_locale}/budget/resource/{id}/view", name="chill_budget_resource_view") */ public function viewAction(Resource $resource): Response { diff --git a/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php b/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php index 57976f846..6a8842b64 100644 --- a/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php +++ b/src/Bundle/ChillBudgetBundle/DependencyInjection/ChillBudgetExtension.php @@ -34,7 +34,7 @@ class ChillBudgetExtension extends Extension implements PrependExtensionInterfac $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services/form.yaml'); $loader->load('services/repository.yaml'); $loader->load('services/security.yaml'); @@ -60,7 +60,7 @@ class ChillBudgetExtension extends Extension implements PrependExtensionInterfac */ public function prependRoutes(ContainerBuilder $container) { - //add routes for custom bundle + // add routes for custom bundle $container->prependExtensionConfig('chill_main', [ 'routing' => [ 'resources' => [ diff --git a/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php b/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php index 619a6cdd7..52a52c99f 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php +++ b/src/Bundle/ChillBudgetBundle/Entity/AbstractElement.php @@ -14,8 +14,6 @@ namespace Chill\BudgetBundle\Entity; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use DateTime; -use DateTimeImmutable; -use DateTimeInterface; use Doctrine\ORM\Mapping as ORM; use Ramsey\Uuid\Type\Decimal; use Symfony\Component\Validator\Constraints as Assert; @@ -29,9 +27,11 @@ abstract class AbstractElement { /** * @ORM\Column(name="amount", type="decimal", precision=10, scale=2) + * * @Assert\GreaterThan( * value=0 * ) + * * @Assert\NotNull( * message="The amount cannot be empty" * ) @@ -45,12 +45,13 @@ abstract class AbstractElement /** * @ORM\Column(name="endDate", type="datetime_immutable", nullable=true) + * * @Assert\GreaterThan( * propertyPath="startDate", * message="The budget element's end date must be after the start date" * ) */ - private ?DateTimeImmutable $endDate = null; + private ?\DateTimeImmutable $endDate = null; /** * @ORM\ManyToOne( @@ -68,16 +69,17 @@ abstract class AbstractElement /** * @ORM\Column(name="startDate", type="datetime_immutable") + * * @Assert\Date */ - private DateTimeImmutable $startDate; + private \DateTimeImmutable $startDate; /** * @ORM\Column(name="type", type="string", length=255) */ private string $type = ''; - /*Getters and Setters */ + /* Getters and Setters */ public function getAmount(): float { @@ -89,7 +91,7 @@ abstract class AbstractElement return $this->comment; } - public function getEndDate(): ?DateTimeImmutable + public function getEndDate(): ?\DateTimeImmutable { return $this->endDate; } @@ -104,7 +106,7 @@ abstract class AbstractElement return $this->person; } - public function getStartDate(): DateTimeImmutable + public function getStartDate(): \DateTimeImmutable { return $this->startDate; } @@ -130,17 +132,17 @@ abstract class AbstractElement return $this; } - public function setComment(?string $comment = null): self + public function setComment(string $comment = null): self { $this->comment = $comment; return $this; } - public function setEndDate(?DateTimeInterface $endDate = null): self + public function setEndDate(\DateTimeInterface $endDate = null): self { - if ($endDate instanceof DateTime) { - $this->endDate = DateTimeImmutable::createFromMutable($endDate); + if ($endDate instanceof \DateTime) { + $this->endDate = \DateTimeImmutable::createFromMutable($endDate); } elseif (null === $endDate) { $this->endDate = null; } else { @@ -164,10 +166,10 @@ abstract class AbstractElement return $this; } - public function setStartDate(DateTimeInterface $startDate): self + public function setStartDate(\DateTimeInterface $startDate): self { - if ($startDate instanceof DateTime) { - $this->startDate = DateTimeImmutable::createFromMutable($startDate); + if ($startDate instanceof \DateTime) { + $this->startDate = \DateTimeImmutable::createFromMutable($startDate); } elseif (null === $startDate) { $this->startDate = null; } else { diff --git a/src/Bundle/ChillBudgetBundle/Entity/Charge.php b/src/Bundle/ChillBudgetBundle/Entity/Charge.php index 056e4abff..68ee65d19 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/Charge.php +++ b/src/Bundle/ChillBudgetBundle/Entity/Charge.php @@ -13,26 +13,26 @@ namespace Chill\BudgetBundle\Entity; use Chill\MainBundle\Entity\HasCentersInterface; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; /** * Charge. * * @ORM\Table(name="chill_budget.charge") + * * @ORM\Entity(repositoryClass="Chill\BudgetBundle\Repository\ChargeRepository") */ class Charge extends AbstractElement implements HasCentersInterface { - public const HELP_ASKED = 'running'; + final public const HELP_ASKED = 'running'; - public const HELP_NO = 'no'; + final public const HELP_NO = 'no'; - public const HELP_NOT_RELEVANT = 'not-relevant'; + final public const HELP_NOT_RELEVANT = 'not-relevant'; - public const HELP_YES = 'yes'; + final public const HELP_YES = 'yes'; - public const HELPS = [ + final public const HELPS = [ self::HELP_ASKED, self::HELP_NO, self::HELP_YES, @@ -41,26 +41,28 @@ class Charge extends AbstractElement implements HasCentersInterface /** * @ORM\ManyToOne(targetEntity=ChargeKind::class, inversedBy="AbstractElement") + * * @ORM\JoinColumn */ private ?ChargeKind $charge = null; /** - * @var string * @ORM\Column(name="help", type="string", nullable=true) */ - private $help = self::HELP_NOT_RELEVANT; + private string $help = self::HELP_NOT_RELEVANT; /** * @ORM\Column(name="id", type="integer") + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ private ?int $id = null; public function __construct() { - $this->setStartDate(new DateTimeImmutable('today')); + $this->setStartDate(new \DateTimeImmutable('today')); } public function getCenters(): array diff --git a/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php b/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php index b6ebcf347..308575677 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php +++ b/src/Bundle/ChillBudgetBundle/Entity/ChargeKind.php @@ -21,14 +21,18 @@ use Symfony\Component\Validator\Constraints as Assert; * @ORM\Table(name="chill_budget.charge_type", * uniqueConstraints={@ORM\UniqueConstraint(name="charge_kind_unique_type_idx", fields={"kind"})} * ) + * * @ORM\Entity + * * @UniqueEntity(fields={"kind"}) */ class ChargeKind { /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ private ?int $id = null; @@ -40,7 +44,9 @@ class ChargeKind /** * @ORM\Column(type="string", length=255, options={"default": ""}, nullable=false) + * * @Assert\Regex(pattern="/^[a-z0-9\-_]{1,}$/", message="budget.admin.form.kind.only_alphanumeric") + * * @Assert\Length(min=3) */ private string $kind = ''; diff --git a/src/Bundle/ChillBudgetBundle/Entity/Resource.php b/src/Bundle/ChillBudgetBundle/Entity/Resource.php index 28b8645e0..c4845ed1b 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/Resource.php +++ b/src/Bundle/ChillBudgetBundle/Entity/Resource.php @@ -13,33 +13,36 @@ namespace Chill\BudgetBundle\Entity; use Chill\MainBundle\Entity\HasCentersInterface; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; /** * Resource. * * @ORM\Table(name="chill_budget.resource") + * * @ORM\Entity(repositoryClass="Chill\BudgetBundle\Repository\ResourceRepository") */ class Resource extends AbstractElement implements HasCentersInterface { /** * @ORM\Column(name="id", type="integer") + * * @ORM\Id + * * @ORM\GeneratedValue(strategy="AUTO") */ 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')); + $this->setStartDate(new \DateTimeImmutable('today')); } public function getCenters(): array diff --git a/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php b/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php index 4b90be5e1..78e0e6a32 100644 --- a/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php +++ b/src/Bundle/ChillBudgetBundle/Entity/ResourceKind.php @@ -19,16 +19,21 @@ use Symfony\Component\Validator\Constraints as Assert; * Type of resource. * * @ORM\Table(name="chill_budget.resource_type", uniqueConstraints={ + * * @ORM\UniqueConstraint(name="resource_kind_unique_type_idx", fields={"kind"}) * }) + * * @ORM\Entity + * * @UniqueEntity(fields={"kind"}) */ class ResourceKind { /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ private ?int $id = null; @@ -40,7 +45,9 @@ class ResourceKind /** * @ORM\Column(type="string", length=255, nullable=false, options={"default": ""}) + * * @Assert\Regex(pattern="/^[a-z0-9\-_]{1,}$/", message="budget.admin.form.kind.only_alphanumeric") + * * @Assert\Length(min=3) */ private string $kind = ''; diff --git a/src/Bundle/ChillBudgetBundle/Form/ChargeType.php b/src/Bundle/ChillBudgetBundle/Form/ChargeType.php index 72863163f..2d219b62a 100644 --- a/src/Bundle/ChillBudgetBundle/Form/ChargeType.php +++ b/src/Bundle/ChillBudgetBundle/Form/ChargeType.php @@ -27,21 +27,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ChargeType extends AbstractType { - protected TranslatableStringHelperInterface $translatableStringHelper; - - private ChargeKindRepository $repository; - - private TranslatorInterface $translator; - - public function __construct( - TranslatableStringHelperInterface $translatableStringHelper, - ChargeKindRepository $repository, - TranslatorInterface $translator - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->repository = $repository; - $this->translator = $translator; - } + public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, private readonly ChargeKindRepository $repository, private readonly TranslatorInterface $translator) {} public function buildForm(FormBuilderInterface $builder, array $options) { diff --git a/src/Bundle/ChillBudgetBundle/Form/ResourceType.php b/src/Bundle/ChillBudgetBundle/Form/ResourceType.php index 09dfd16f3..ba93f1080 100644 --- a/src/Bundle/ChillBudgetBundle/Form/ResourceType.php +++ b/src/Bundle/ChillBudgetBundle/Form/ResourceType.php @@ -26,21 +26,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class ResourceType extends AbstractType { - protected TranslatableStringHelperInterface $translatableStringHelper; - - private ResourceKindRepository $repository; - - private TranslatorInterface $translator; - - public function __construct( - TranslatableStringHelperInterface $translatableStringHelper, - ResourceKindRepository $repository, - TranslatorInterface $translator - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->repository = $repository; - $this->translator = $translator; - } + public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, private readonly ResourceKindRepository $repository, private readonly TranslatorInterface $translator) {} public function buildForm(FormBuilderInterface $builder, array $options) { diff --git a/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php index 894230ad9..b8b4b617c 100644 --- a/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php +++ b/src/Bundle/ChillBudgetBundle/Menu/AdminMenuBuilder.php @@ -15,14 +15,9 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Knp\Menu\MenuItem; use Symfony\Component\Security\Core\Security; -final class AdminMenuBuilder implements LocalMenuBuilderInterface +final readonly class AdminMenuBuilder implements LocalMenuBuilderInterface { - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; - } + public function __construct(private Security $security) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php index 1224c0bfe..94583b439 100644 --- a/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php +++ b/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php @@ -20,17 +20,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class HouseholdMenuBuilder implements LocalMenuBuilderInterface { - protected AuthorizationCheckerInterface $authorizationChecker; - - protected TranslatorInterface $translator; - - public function __construct( - AuthorizationCheckerInterface $authorizationChecker, - TranslatorInterface $translator - ) { - $this->authorizationChecker = $authorizationChecker; - $this->translator = $translator; - } + public function __construct(protected AuthorizationCheckerInterface $authorizationChecker, protected TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php index 7322af849..25bd6a218 100644 --- a/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php @@ -20,17 +20,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class PersonMenuBuilder implements LocalMenuBuilderInterface { - protected AuthorizationCheckerInterface $authorizationChecker; - - protected TranslatorInterface $translator; - - public function __construct( - AuthorizationCheckerInterface $authorizationChecker, - TranslatorInterface $translator - ) { - $this->authorizationChecker = $authorizationChecker; - $this->translator = $translator; - } + public function __construct(protected AuthorizationCheckerInterface $authorizationChecker, protected TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php index 9aaf68ddf..577be07db 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php @@ -17,7 +17,7 @@ use Doctrine\ORM\EntityRepository; final class ChargeKindRepository implements ChargeKindRepositoryInterface { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -66,7 +66,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface * * @return array */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php index f92851eba..7a930bea8 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php @@ -34,12 +34,9 @@ interface ChargeKindRepositoryInterface extends ObjectRepository 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 findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array; public function findOneBy(array $criteria): ?ChargeKind; diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php index 9b89010dc..3154a772d 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeRepository.php @@ -14,7 +14,6 @@ namespace Chill\BudgetBundle\Repository; use Chill\BudgetBundle\Entity\Charge; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; -use DateTime; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -34,7 +33,7 @@ class ChargeRepository extends ServiceEntityRepository /** * @return Charge[] */ - public function findAllByEntity(Person|Household $entity): array + public function findAllByEntity(Household|Person $entity): array { $qb = $this->createQueryBuilder('c'); @@ -46,7 +45,7 @@ class ChargeRepository extends ServiceEntityRepository return $qb->getQuery()->getResult(); } - public function findByEntityAndDate($entity, DateTime $date, $sort = null) + public function findByEntityAndDate($entity, \DateTime $date, $sort = null) { $qb = $this->createQueryBuilder('c'); diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php index 1f9f99753..e10913195 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php @@ -17,7 +17,7 @@ use Doctrine\ORM\EntityRepository; final class ResourceKindRepository implements ResourceKindRepositoryInterface { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -54,7 +54,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface public function findOneByKind(string $kind): ?ResourceKind { - return $this->repository->findOneBy(['kind' => $kind]) ; + return $this->repository->findOneBy(['kind' => $kind]); } /** @@ -71,7 +71,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface * * @return list */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php index dac46ff35..d639d54ee 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php @@ -34,12 +34,9 @@ interface ResourceKindRepositoryInterface extends ObjectRepository 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 findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array; public function findOneBy(array $criteria): ?ResourceKind; diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php index 836f13e4b..2ba95e340 100644 --- a/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php +++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceRepository.php @@ -14,9 +14,7 @@ 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; /** @@ -33,9 +31,9 @@ class ResourceRepository extends ServiceEntityRepository } /** - * @return Resource[] + * @return resource[] */ - public function findAllByEntity(Person|Household $entity): array + public function findAllByEntity(Household|Person $entity): array { $qb = $this->createQueryBuilder('r'); @@ -47,7 +45,7 @@ class ResourceRepository extends ServiceEntityRepository return $qb->getQuery()->getResult(); } - public function findByEntityAndDate(Person|Household $entity, DateTime $date, $sort = null) + public function findByEntityAndDate(Household|Person $entity, \DateTime $date, $sort = null) { $qb = $this->createQueryBuilder('c'); 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 62f4e3e96..dde039194 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_future_budget.html.twig @@ -1,4 +1,4 @@ -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} +{% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %}
      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 ad0a12755..72c85c459 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Budget/_past_budget.html.twig @@ -1,4 +1,4 @@ -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} +{% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %}
      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 7a97731da..abfe9a6d5 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Charge/confirm_delete.html.twig @@ -18,7 +18,7 @@ {% block content %} -{{ include('ChillMainBundle:Util:confirmation_template.html.twig', +{{ include('@ChillMain/Util/confirmation_template.html.twig', { 'title' : 'Remove charge'|trans, 'confirm_question' : confirm_question, diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig index 1df92b297..738c5e825 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Household/index.html.twig @@ -1,6 +1,6 @@ {% extends "@ChillPerson/Household/layout.html.twig" %} -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} +{% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} {% set activeRouteKey = '' %} {% set title = 'Budget for household %household%'|trans({ '%household%' : household.id } ) %} @@ -17,7 +17,7 @@ {% block content %}

      {{ title }}

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

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

      - {% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { + {% include '@ChillBudget/Budget/_budget.html.twig' with { 'resources': member.getBudgetResources, 'charges': member.getBudgetCharges, 'person': member diff --git a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig index aba564206..aaf840f33 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Person/index.html.twig @@ -1,6 +1,6 @@ {% extends "@ChillPerson/Person/layout.html.twig" %} -{% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_results %} +{% from '@ChillBudget/Budget/_macros.html.twig' import table_results %} {% set activeRouteKey = '' %} {% set title = 'Budget for %name%'|trans({ '%name%' : person.firstName ~ " " ~ person.lastName } ) %} 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 5c2e80e10..afcb54c42 100644 --- a/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig +++ b/src/Bundle/ChillBudgetBundle/Resources/views/Resource/confirm_delete.html.twig @@ -18,7 +18,7 @@ {% block content %} -{{ include('ChillMainBundle:Util:confirmation_template.html.twig', +{{ include('@ChillMain/Util/confirmation_template.html.twig', { 'title' : 'Remove resource'|trans, 'confirm_question' : confirm_question, diff --git a/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php b/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php index 5203f9092..f2340b8b9 100644 --- a/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php +++ b/src/Bundle/ChillBudgetBundle/Security/Authorization/BudgetElementVoter.php @@ -20,24 +20,22 @@ use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use UnexpectedValueException; - class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const CREATE = 'CHILL_BUDGET_ELEMENT_CREATE'; + final public const CREATE = 'CHILL_BUDGET_ELEMENT_CREATE'; - public const DELETE = 'CHILL_BUDGET_ELEMENT_DELETE'; + final public const DELETE = 'CHILL_BUDGET_ELEMENT_DELETE'; - public const ROLES = [ + final public const ROLES = [ self::CREATE, self::DELETE, self::SEE, self::UPDATE, ]; - public const SEE = 'CHILL_BUDGET_ELEMENT_SEE'; + final public const SEE = 'CHILL_BUDGET_ELEMENT_SEE'; - public const UPDATE = 'CHILL_BUDGET_ELEMENT_UPDATE'; + final public const UPDATE = 'CHILL_BUDGET_ELEMENT_UPDATE'; protected VoterHelperInterface $voter; @@ -91,6 +89,6 @@ class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierar return false; } - throw new UnexpectedValueException('This subject is not supported, or is an element not associated with person or household'); + 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 1c66d4c1c..a57f7fb29 100644 --- a/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php +++ b/src/Bundle/ChillBudgetBundle/Service/Summary/SummaryBudget.php @@ -20,14 +20,11 @@ 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. */ -final class SummaryBudget implements SummaryBudgetInterface +final readonly class SummaryBudget implements SummaryBudgetInterface { 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'; @@ -37,25 +34,7 @@ final class SummaryBudget implements SummaryBudgetInterface 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 ChargeKindRepositoryInterface $chargeKindRepository; - - private EntityManagerInterface $em; - - private ResourceKindRepositoryInterface $resourceKindRepository; - - private TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct( - EntityManagerInterface $em, - TranslatableStringHelperInterface $translatableStringHelper, - ResourceKindRepositoryInterface $resourceKindRepository, - ChargeKindRepositoryInterface $chargeKindRepository - ) { - $this->em = $em; - $this->translatableStringHelper = $translatableStringHelper; - $this->resourceKindRepository = $resourceKindRepository; - $this->chargeKindRepository = $chargeKindRepository; - } + public function __construct(private EntityManagerInterface $em, private TranslatableStringHelperInterface $translatableStringHelper, private ResourceKindRepositoryInterface $resourceKindRepository, private ChargeKindRepositoryInterface $chargeKindRepository) {} public function getSummaryForHousehold(?Household $household): array { @@ -67,7 +46,7 @@ final class SummaryBudget implements SummaryBudgetInterface } $personIds = $household->getCurrentPersons()->map(static fn (Person $p) => $p->getId()); - $ids = implode(', ', array_fill(0, count($personIds), '?')); + $ids = implode(', ', array_fill(0, \count($personIds), '?')); $parameters = [...$personIds, $household->getId()]; @@ -145,7 +124,7 @@ final class SummaryBudget implements SummaryBudgetInterface $chargeKind = $this->chargeKindRepository->find($row['kind_id']); if (null === $chargeKind) { - throw new RuntimeException('charge kind not found: ' . $row['kind_id']); + throw new \RuntimeException('charge kind not found: '.$row['kind_id']); } $result[$chargeKind->getKind()] = [ 'sum' => (float) $row['sum'], @@ -161,7 +140,7 @@ final class SummaryBudget implements SummaryBudgetInterface $resourceKind = $this->resourceKindRepository->find($row['kind_id']); if (null === $resourceKind) { - throw new RuntimeException('charge kind not found: ' . $row['kind_id']); + throw new \RuntimeException('charge kind not found: '.$row['kind_id']); } $result[$resourceKind->getKind()] = [ @@ -174,7 +153,7 @@ final class SummaryBudget implements SummaryBudgetInterface return $result; default: - throw new LogicException(); + throw new \LogicException(); } } } diff --git a/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php b/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php index 842e6be4e..26871b0f4 100644 --- a/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php +++ b/src/Bundle/ChillBudgetBundle/Templating/BudgetElementTypeRender.php @@ -15,22 +15,13 @@ use Chill\BudgetBundle\Entity\ChargeKind; use Chill\BudgetBundle\Entity\ResourceKind; use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; -use Symfony\Component\Templating\EngineInterface; /** * @implements ChillEntityRenderInterface */ -final class BudgetElementTypeRender implements ChillEntityRenderInterface +final readonly 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 __construct(private TranslatableStringHelperInterface $translatableStringHelper, private \Twig\Environment $engine) {} public function renderBox($entity, array $options): string { diff --git a/src/Bundle/ChillBudgetBundle/Tests/Controller/ElementControllerTest.php b/src/Bundle/ChillBudgetBundle/Tests/Controller/ElementControllerTest.php index 925506a99..52fae812e 100644 --- a/src/Bundle/ChillBudgetBundle/Tests/Controller/ElementControllerTest.php +++ b/src/Bundle/ChillBudgetBundle/Tests/Controller/ElementControllerTest.php @@ -15,10 +15,14 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** * @internal + * * @coversNothing */ final class ElementControllerTest extends WebTestCase { + /** + * @doesNotPerformAssertions + */ public function testIndex() { $client = self::createClient(); @@ -26,6 +30,9 @@ final class ElementControllerTest extends WebTestCase $crawler = $client->request('GET', '/index'); } + /** + * @doesNotPerformAssertions + */ public function testList() { $client = self::createClient(); diff --git a/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php b/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php index 77017abc5..7fb437e05 100644 --- a/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php +++ b/src/Bundle/ChillBudgetBundle/Tests/Service/Summary/SummaryBudgetTest.php @@ -20,15 +20,12 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\HouseholdMember; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use ReflectionClass; -use RuntimeException; /** * @internal @@ -66,15 +63,15 @@ final class SummaryBudgetTest extends TestCase $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')) { + if (str_contains((string) $args[0], 'chill_budget.resource')) { return $queryResources->reveal(); } - if (false !== strpos($args[0], 'chill_budget.charge')) { + if (str_contains((string) $args[0], 'chill_budget.charge')) { return $queryCharges->reveal(); } - throw new RuntimeException('this query does not have a stub counterpart: ' . $args[0]); + throw new \RuntimeException('this query does not have a stub counterpart: '.$args[0]); }); $chargeRepository = $this->prophesize(ChargeKindRepositoryInterface::class); @@ -99,18 +96,18 @@ final class SummaryBudgetTest extends TestCase $translatableStringHelper->localize(Argument::type('array'))->will(static fn ($arg) => $arg[0]['fr']); $person = new Person(); - $personReflection = new ReflectionClass($person); + $personReflection = new \ReflectionClass($person); $personIdReflection = $personReflection->getProperty('id'); $personIdReflection->setAccessible(true); $personIdReflection->setValue($person, 1); $household = new Household(); - $householdReflection = new ReflectionClass($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')); + ->setStartDate(new \DateTimeImmutable('1 month ago')); $household->addMember($householdMember); $summaryBudget = new SummaryBudget( diff --git a/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php b/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php index cfe3a0089..1d2707120 100644 --- a/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php +++ b/src/Bundle/ChillBudgetBundle/migrations/Version20221207105407.php @@ -32,7 +32,7 @@ final class Version20221207105407 extends AbstractMigration implements Container return 'Use new budget admin entities'; } - public function setContainer(?ContainerInterface $container = null) + public function setContainer(ContainerInterface $container = null) { $this->container = $container; } diff --git a/src/Bundle/ChillCalendarBundle/ChillCalendarBundle.php b/src/Bundle/ChillCalendarBundle/ChillCalendarBundle.php index e2042b114..f0f20181a 100644 --- a/src/Bundle/ChillCalendarBundle/ChillCalendarBundle.php +++ b/src/Bundle/ChillCalendarBundle/ChillCalendarBundle.php @@ -21,6 +21,6 @@ class ChillCalendarBundle extends Bundle { parent::build($container); - $container->addCompilerPass(new RemoteCalendarCompilerPass()); + $container->addCompilerPass(new RemoteCalendarCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); } } diff --git a/src/Bundle/ChillCalendarBundle/Command/AzureGrantAdminConsentAndAcquireToken.php b/src/Bundle/ChillCalendarBundle/Command/AzureGrantAdminConsentAndAcquireToken.php index 400619990..c9bf020b1 100644 --- a/src/Bundle/ChillCalendarBundle/Command/AzureGrantAdminConsentAndAcquireToken.php +++ b/src/Bundle/ChillCalendarBundle/Command/AzureGrantAdminConsentAndAcquireToken.php @@ -29,22 +29,12 @@ use TheNetworg\OAuth2\Client\Provider\Azure; class AzureGrantAdminConsentAndAcquireToken extends Command { - private Azure $azure; - - private ClientRegistry $clientRegistry; - - private MachineTokenStorage $machineTokenStorage; - - public function __construct(Azure $azure, ClientRegistry $clientRegistry, MachineTokenStorage $machineTokenStorage) + public function __construct(private readonly Azure $azure, private readonly ClientRegistry $clientRegistry, private readonly MachineTokenStorage $machineTokenStorage) { parent::__construct('chill:calendar:msgraph-grant-admin-consent'); - - $this->azure = $azure; - $this->clientRegistry = $clientRegistry; - $this->machineTokenStorage = $machineTokenStorage; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { /** @var FormatterHelper $formatter */ $formatter = $this->getHelper('formatter'); @@ -76,8 +66,8 @@ class AzureGrantAdminConsentAndAcquireToken extends Command $output->writeln('Token information:'); $output->writeln($token->getToken()); - $output->writeln('Expires at: ' . $token->getExpires()); - $output->writeln('To inspect the token content, go to https://jwt.ms/#access_token=' . urlencode($token->getToken())); + $output->writeln('Expires at: '.$token->getExpires()); + $output->writeln('To inspect the token content, go to https://jwt.ms/#access_token='.urlencode($token->getToken())); return 0; } diff --git a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php index 193b04934..4964f0064 100644 --- a/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php +++ b/src/Bundle/ChillCalendarBundle/Command/MapAndSubscribeUserCalendarCommand.php @@ -21,11 +21,8 @@ namespace Chill\CalendarBundle\Command; use Chill\CalendarBundle\Exception\UserAbsenceSyncException; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\EventsOnUserSubscriptionCreator; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MapCalendarToUser; -use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSGraphUserRepository; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; use Chill\MainBundle\Repository\UserRepositoryInterface; -use DateInterval; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Command\Command; @@ -48,19 +45,19 @@ final class MapAndSubscribeUserCalendarCommand extends Command public function execute(InputInterface $input, OutputInterface $output): int { - $this->logger->info(self::class . ' execute command'); + $this->logger->info(self::class.' execute command'); $limit = 50; $offset = 0; - /** @var DateInterval $interval the interval before the end of the expiration */ - $interval = new DateInterval('P1D'); - $expiration = (new DateTimeImmutable('now'))->add(new DateInterval($input->getOption('subscription-duration'))); + /** @var \DateInterval $interval the interval before the end of the expiration */ + $interval = new \DateInterval('P1D'); + $expiration = (new \DateTimeImmutable('now'))->add(new \DateInterval($input->getOption('subscription-duration'))); $users = $this->userRepository->findAllAsArray('fr'); $created = 0; $renewed = 0; - $this->logger->info(self::class . ' start user to get - renew', [ - 'expiration' => $expiration->format(DateTimeImmutable::ATOM), + $this->logger->info(self::class.' start user to get - renew', [ + 'expiration' => $expiration->format(\DateTimeImmutable::ATOM), ]); foreach ($users as $u) { @@ -73,8 +70,8 @@ final class MapAndSubscribeUserCalendarCommand extends Command $user = $this->userRepository->find($u['id']); if (null === $user) { - $this->logger->error("could not find user by id", ['uid' => $u['id']]); - $output->writeln("could not find user by id : " . $u['id']); + $this->logger->error('could not find user by id', ['uid' => $u['id']]); + $output->writeln('could not find user by id : '.$u['id']); continue; } @@ -83,8 +80,8 @@ final class MapAndSubscribeUserCalendarCommand extends Command // if user still does not have userid, continue if (!$this->mapCalendarToUser->hasUserId($user)) { - $this->logger->warning("user does not have a counterpart on ms api", ['userId' => $user->getId(), 'email' => $user->getEmail()]); - $output->writeln(sprintf("giving up for user with email %s and id %s", $user->getEmail(), $user->getId())); + $this->logger->warning('user does not have a counterpart on ms api', ['userId' => $user->getId(), 'email' => $user->getEmail()]); + $output->writeln(sprintf('giving up for user with email %s and id %s', $user->getEmail(), $user->getId())); continue; } @@ -94,15 +91,15 @@ final class MapAndSubscribeUserCalendarCommand extends Command try { $this->userAbsenceSync->syncUserAbsence($user); } catch (UserAbsenceSyncException $e) { - $this->logger->error("could not sync user absence", ['userId' => $user->getId(), 'email' => $user->getEmail(), 'exception' => $e->getTraceAsString(), "message" => $e->getMessage()]); - $output->writeln(sprintf("Could not sync user absence: id: %s and email: %s", $user->getId(), $user->getEmail())); + $this->logger->error('could not sync user absence', ['userId' => $user->getId(), 'email' => $user->getEmail(), 'exception' => $e->getTraceAsString(), 'message' => $e->getMessage()]); + $output->writeln(sprintf('Could not sync user absence: id: %s and email: %s', $user->getId(), $user->getEmail())); throw $e; } // 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(self::class . ' renew a subscription for', [ + $this->logger->debug(self::class.' renew a subscription for', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -114,7 +111,7 @@ final class MapAndSubscribeUserCalendarCommand extends Command if (0 !== $expirationTs) { ++$renewed; } else { - $this->logger->warning(self::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(), ]); @@ -122,7 +119,7 @@ final class MapAndSubscribeUserCalendarCommand extends Command } if (!$this->mapCalendarToUser->hasActiveSubscription($user)) { - $this->logger->debug(self::class . ' create a subscription for', [ + $this->logger->debug(self::class.' create a subscription for', [ 'userId' => $user->getId(), 'username' => $user->getUsernameCanonical(), ]); @@ -134,14 +131,13 @@ final class MapAndSubscribeUserCalendarCommand extends Command if (0 !== $expirationTs) { ++$created; } else { - $this->logger->warning(self::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(), ]); } } - if (0 === $offset % $limit) { $this->em->flush(); $this->em->clear(); @@ -151,12 +147,12 @@ final class MapAndSubscribeUserCalendarCommand extends Command $this->em->flush(); $this->em->clear(); - $this->logger->warning(self::class . ' process executed', [ + $this->logger->warning(self::class.' process executed', [ 'created' => $created, 'renewed' => $renewed, ]); - $output->writeln("users synchronized"); + $output->writeln('users synchronized'); return 0; } diff --git a/src/Bundle/ChillCalendarBundle/Command/SendShortMessageOnEligibleCalendar.php b/src/Bundle/ChillCalendarBundle/Command/SendShortMessageOnEligibleCalendar.php index 6625a7adb..a027c1bc2 100644 --- a/src/Bundle/ChillCalendarBundle/Command/SendShortMessageOnEligibleCalendar.php +++ b/src/Bundle/ChillCalendarBundle/Command/SendShortMessageOnEligibleCalendar.php @@ -25,13 +25,9 @@ use Symfony\Component\Console\Output\OutputInterface; class SendShortMessageOnEligibleCalendar extends Command { - private BulkCalendarShortMessageSender $messageSender; - - public function __construct(BulkCalendarShortMessageSender $messageSender) + public function __construct(private readonly BulkCalendarShortMessageSender $messageSender) { parent::__construct(); - - $this->messageSender = $messageSender; } public function getName() @@ -39,7 +35,7 @@ class SendShortMessageOnEligibleCalendar extends Command return 'chill:calendar:send-short-messages'; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->messageSender->sendBulkMessageToEligibleCalendars(); diff --git a/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php b/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php index 5891a7be8..bfbdd2abd 100644 --- a/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php +++ b/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php @@ -26,8 +26,6 @@ use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Service\ShortMessage\ShortMessageTransporterInterface; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\PersonRepository; -use DateInterval; -use DateTimeImmutable; use libphonenumber\PhoneNumber; use libphonenumber\PhoneNumberFormat; use libphonenumber\PhoneNumberType; @@ -38,39 +36,18 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; -use UnexpectedValueException; -use function count; class SendTestShortMessageOnCalendarCommand extends Command { - private ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder; - - private PersonRepository $personRepository; - - private PhoneNumberHelperInterface $phoneNumberHelper; - - private PhoneNumberUtil $phoneNumberUtil; - - private ShortMessageTransporterInterface $transporter; - - private UserRepositoryInterface $userRepository; - public function __construct( - PersonRepository $personRepository, - PhoneNumberUtil $phoneNumberUtil, - PhoneNumberHelperInterface $phoneNumberHelper, - ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder, - ShortMessageTransporterInterface $transporter, - UserRepositoryInterface $userRepository + private readonly PersonRepository $personRepository, + private readonly PhoneNumberUtil $phoneNumberUtil, + private readonly PhoneNumberHelperInterface $phoneNumberHelper, + private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder, + private readonly ShortMessageTransporterInterface $transporter, + private readonly UserRepositoryInterface $userRepository ) { parent::__construct(); - - $this->personRepository = $personRepository; - $this->phoneNumberUtil = $phoneNumberUtil; - $this->phoneNumberHelper = $phoneNumberHelper; - $this->messageForCalendarBuilder = $messageForCalendarBuilder; - $this->transporter = $transporter; - $this->userRepository = $userRepository; } public function getName() @@ -93,20 +70,20 @@ class SendTestShortMessageOnCalendarCommand extends Command // start date $question = new Question('When will start the appointment ? (default: "1 hour") ', '1 hour'); - $startDate = new DateTimeImmutable($helper->ask($input, $output, $question)); + $startDate = new \DateTimeImmutable($helper->ask($input, $output, $question)); if (false === $startDate) { - throw new UnexpectedValueException('could not create a date with this date and time'); + throw new \UnexpectedValueException('could not create a date with this date and time'); } $calendar->setStartDate($startDate); // end date $question = new Question('How long will last the appointment ? (default: "PT30M") ', 'PT30M'); - $interval = new DateInterval($helper->ask($input, $output, $question)); + $interval = new \DateInterval($helper->ask($input, $output, $question)); if (false === $interval) { - throw new UnexpectedValueException('could not create the interval'); + throw new \UnexpectedValueException('could not create the interval'); } $calendar->setEndDate($calendar->getStartDate()->add($interval)); @@ -116,17 +93,17 @@ class SendTestShortMessageOnCalendarCommand extends Command $question ->setValidator(function ($answer): Person { if (!is_numeric($answer)) { - throw new UnexpectedValueException('the answer must be numeric'); + throw new \UnexpectedValueException('the answer must be numeric'); } if (0 >= (int) $answer) { - throw new UnexpectedValueException('the answer must be greater than zero'); + throw new \UnexpectedValueException('the answer must be greater than zero'); } $person = $this->personRepository->find((int) $answer); if (null === $person) { - throw new UnexpectedValueException('The person is not found'); + throw new \UnexpectedValueException('The person is not found'); } return $person; @@ -140,17 +117,17 @@ class SendTestShortMessageOnCalendarCommand extends Command $question ->setValidator(function ($answer): User { if (!is_numeric($answer)) { - throw new UnexpectedValueException('the answer must be numeric'); + throw new \UnexpectedValueException('the answer must be numeric'); } if (0 >= (int) $answer) { - throw new UnexpectedValueException('the answer must be greater than zero'); + throw new \UnexpectedValueException('the answer must be greater than zero'); } $user = $this->userRepository->find((int) $answer); if (null === $user) { - throw new UnexpectedValueException('The user is not found'); + throw new \UnexpectedValueException('The user is not found'); } return $user; @@ -169,13 +146,13 @@ class SendTestShortMessageOnCalendarCommand extends Command $question->setNormalizer(function ($answer): PhoneNumber { if (null === $answer) { - throw new UnexpectedValueException('The person is not found'); + throw new \UnexpectedValueException('The person is not found'); } $phone = $this->phoneNumberUtil->parse($answer, 'BE'); if (!$this->phoneNumberUtil->isPossibleNumberForType($phone, PhoneNumberType::MOBILE)) { - throw new UnexpectedValueException('Phone number si not a mobile'); + throw new \UnexpectedValueException('Phone number si not a mobile'); } return $phone; @@ -188,7 +165,7 @@ class SendTestShortMessageOnCalendarCommand extends Command $messages = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); - if (0 === count($messages)) { + if (0 === \count($messages)) { $output->writeln('no message to send to this user'); } diff --git a/src/Bundle/ChillCalendarBundle/Controller/AdminController.php b/src/Bundle/ChillCalendarBundle/Controller/AdminController.php index 23f39a295..fceddf45a 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/AdminController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/AdminController.php @@ -23,6 +23,6 @@ class AdminController extends AbstractController */ public function indexAdminAction() { - return $this->render('ChillCalendarBundle:Admin:index.html.twig'); + return $this->render('@ChillCalendar/Admin/index.html.twig'); } } diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarAPIController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarAPIController.php index 8e0e8099c..1729c215b 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarAPIController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarAPIController.php @@ -15,7 +15,6 @@ use Chill\CalendarBundle\Repository\CalendarRepository; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Serializer\Model\Collection; -use DateTimeImmutable; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -24,12 +23,7 @@ use Symfony\Component\Routing\Annotation\Route; class CalendarAPIController extends ApiController { - private CalendarRepository $calendarRepository; - - public function __construct(CalendarRepository $calendarRepository) - { - $this->calendarRepository = $calendarRepository; - } + public function __construct(private readonly CalendarRepository $calendarRepository) {} /** * @Route("/api/1.0/calendar/calendar/by-user/{id}.{_format}", @@ -45,8 +39,8 @@ class CalendarAPIController extends ApiController throw new BadRequestHttpException('You must provide a dateFrom parameter'); } - if (false === $dateFrom = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateFrom = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateFrom') )) { throw new BadRequestHttpException('dateFrom not parsable'); @@ -56,8 +50,8 @@ class CalendarAPIController extends ApiController throw new BadRequestHttpException('You must provide a dateTo parameter'); } - if (false === $dateTo = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateTo = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateTo') )) { throw new BadRequestHttpException('dateTo not parsable'); diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index eed693451..f4694614f 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -30,11 +30,8 @@ use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\ThirdPartyBundle\Entity\ThirdParty; -use DateTimeImmutable; -use Exception; use http\Exception\UnexpectedValueException; use Psr\Log\LoggerInterface; -use RuntimeException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Form; @@ -49,57 +46,20 @@ use Symfony\Contracts\Translation\TranslatorInterface; class CalendarController extends AbstractController { - private AccompanyingPeriodRepository $accompanyingPeriodRepository; - - private CalendarACLAwareRepositoryInterface $calendarACLAwareRepository; - - private DocGeneratorTemplateRepository $docGeneratorTemplateRepository; - - private FilterOrderHelperFactoryInterface $filterOrderHelperFactory; - - private LoggerInterface $logger; - - private PaginatorFactory $paginator; - - private PersonRepository $personRepository; - - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - private SerializerInterface $serializer; - - private TranslatableStringHelperInterface $translatableStringHelper; - - private TranslatorInterface $translator; - - private UserRepositoryInterface $userRepository; - public function __construct( - CalendarACLAwareRepositoryInterface $calendarACLAwareRepository, - DocGeneratorTemplateRepository $docGeneratorTemplateRepository, - FilterOrderHelperFactoryInterface $filterOrderHelperFactory, - LoggerInterface $logger, - PaginatorFactory $paginator, - RemoteCalendarConnectorInterface $remoteCalendarConnector, - SerializerInterface $serializer, - TranslatableStringHelperInterface $translatableStringHelper, - PersonRepository $personRepository, - AccompanyingPeriodRepository $accompanyingPeriodRepository, - UserRepositoryInterface $userRepository, - TranslatorInterface $translator - ) { - $this->calendarACLAwareRepository = $calendarACLAwareRepository; - $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; - $this->filterOrderHelperFactory = $filterOrderHelperFactory; - $this->logger = $logger; - $this->paginator = $paginator; - $this->remoteCalendarConnector = $remoteCalendarConnector; - $this->serializer = $serializer; - $this->translatableStringHelper = $translatableStringHelper; - $this->personRepository = $personRepository; - $this->accompanyingPeriodRepository = $accompanyingPeriodRepository; - $this->userRepository = $userRepository; - $this->translator = $translator; - } + private readonly CalendarACLAwareRepositoryInterface $calendarACLAwareRepository, + private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository, + private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, + private readonly LoggerInterface $logger, + private readonly PaginatorFactory $paginator, + private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector, + private readonly SerializerInterface $serializer, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly PersonRepository $personRepository, + private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository, + private readonly UserRepositoryInterface $userRepository, + private readonly TranslatorInterface $translator + ) {} /** * Delete a calendar item. @@ -119,12 +79,12 @@ class CalendarController extends AbstractController $view = '@ChillCalendar/Calendar/confirm_deleteByPerson.html.twig'; $redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]); } else { - throw new RuntimeException('nor person or accompanying period'); + throw new \RuntimeException('nor person or accompanying period'); } $form = $this->createDeleteForm($entity); - if ($request->getMethod() === Request::METHOD_DELETE) { + if (Request::METHOD_DELETE === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -175,7 +135,7 @@ class CalendarController extends AbstractController $view = '@ChillCalendar/Calendar/editByPerson.html.twig'; $redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]); } else { - throw new RuntimeException('no person nor accompanying period'); + throw new \RuntimeException('no person nor accompanying period'); } $form = $this->createForm(CalendarType::class, $entity) @@ -185,7 +145,7 @@ class CalendarController extends AbstractController $templates = $this->docGeneratorTemplateRepository->findByEntity(Calendar::class); foreach ($templates as $template) { - $form->add('save_and_generate_doc_' . $template->getId(), SubmitType::class, [ + $form->add('save_and_generate_doc_'.$template->getId(), SubmitType::class, [ 'label' => $this->translatableStringHelper->localize($template->getName()), ]); } @@ -202,7 +162,7 @@ class CalendarController extends AbstractController } foreach ($templates as $template) { - if ($form->get('save_and_generate_doc_' . $template->getId())->isClicked()) { + if ($form->get('save_and_generate_doc_'.$template->getId())->isClicked()) { return $this->redirectToRoute('chill_docgenerator_generate_from_template', [ 'entityClassName' => Calendar::class, 'entityId' => $entity->getId(), @@ -364,7 +324,7 @@ class CalendarController extends AbstractController $form->add('save_and_upload_doc', SubmitType::class); foreach ($templates as $template) { - $form->add('save_and_generate_doc_' . $template->getId(), SubmitType::class, [ + $form->add('save_and_generate_doc_'.$template->getId(), SubmitType::class, [ 'label' => $this->translatableStringHelper->localize($template->getName()), ]); } @@ -379,12 +339,12 @@ class CalendarController extends AbstractController if ($form->get('save_and_upload_doc')->isClicked()) { return $this->redirectToRoute('chill_calendar_calendardoc_new', [ - 'id' => $entity->getId() + 'id' => $entity->getId(), ]); } foreach ($templates as $template) { - if ($form->get('save_and_generate_doc_' . $template->getId())->isClicked()) { + if ($form->get('save_and_generate_doc_'.$template->getId())->isClicked()) { return $this->redirectToRoute('chill_docgenerator_generate_from_template', [ 'entityClassName' => Calendar::class, 'entityId' => $entity->getId(), @@ -429,7 +389,7 @@ class CalendarController extends AbstractController */ public function showAction(Request $request, int $id): Response { - throw new Exception('not implemented'); + throw new \Exception('not implemented'); $view = null; $em = $this->getDoctrine()->getManager(); @@ -490,7 +450,7 @@ class CalendarController extends AbstractController 'entity' => $entity, 'user' => $user, 'activityData' => $activityData, - //'delete_form' => $deleteForm->createView(), + // 'delete_form' => $deleteForm->createView(), ]); } @@ -535,12 +495,12 @@ class CalendarController extends AbstractController 'returnPath' => $request->query->get('returnPath', null), ]; - if ($calendar->getContext() === 'accompanying_period') { + if ('accompanying_period' === $calendar->getContext()) { $routeParams['accompanying_period_id'] = $calendar->getAccompanyingPeriod()->getId(); - } elseif ($calendar->getContext() === 'person') { + } elseif ('person' === $calendar->getContext()) { $routeParams['person_id'] = $calendar->getPerson()->getId(); } else { - throw new RuntimeException('context not found for this calendar'); + throw new \RuntimeException('context not found for this calendar'); } return $this->redirectToRoute('chill_activity_activity_new', $routeParams); @@ -549,7 +509,7 @@ class CalendarController extends AbstractController private function buildListFilterOrder(): FilterOrderHelper { $filterOrder = $this->filterOrderHelperFactory->create(self::class); - $filterOrder->addDateRange('startDate', null, new DateTimeImmutable('3 days ago'), null); + $filterOrder->addDateRange('startDate', null, new \DateTimeImmutable('3 days ago'), null); return $filterOrder->build(); } diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php index d02e55f32..d0f5e623d 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarDocController.php @@ -16,7 +16,6 @@ use Chill\CalendarBundle\Entity\CalendarDoc; use Chill\CalendarBundle\Form\CalendarDocCreateType; use Chill\CalendarBundle\Form\CalendarDocEditType; use Chill\CalendarBundle\Security\Voter\CalendarDocVoter; -use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; @@ -27,41 +26,16 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Security; -use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Templating\EngineInterface; -use UnexpectedValueException; -class CalendarDocController +final readonly class CalendarDocController { - private DocGeneratorTemplateRepository $docGeneratorTemplateRepository; - - private EngineInterface $engine; - - private EntityManagerInterface $entityManager; - - private FormFactoryInterface $formFactory; - - private Security $security; - - private SerializerInterface $serializer; - - private UrlGeneratorInterface $urlGenerator; - public function __construct( - DocGeneratorTemplateRepository $docGeneratorTemplateRepository, - EngineInterface $engine, - EntityManagerInterface $entityManager, - FormFactoryInterface $formFactory, - Security $security, - UrlGeneratorInterface $urlGenerator - ) { - $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; - $this->engine = $engine; - $this->entityManager = $entityManager; - $this->formFactory = $formFactory; - $this->security = $security; - $this->urlGenerator = $urlGenerator; - } + private \Twig\Environment $engine, + private EntityManagerInterface $entityManager, + private FormFactoryInterface $formFactory, + private Security $security, + private UrlGeneratorInterface $urlGenerator, + ) {} /** * @Route("/{_locale}/calendar/calendar-doc/{id}/new", name="chill_calendar_calendardoc_new") @@ -91,7 +65,7 @@ class CalendarDocController break; default: - throw new UnexpectedValueException('Unsupported context'); + throw new \UnexpectedValueException('Unsupported context'); } $calendarDocDTO = new CalendarDoc\CalendarDocCreateDTO(); @@ -208,7 +182,7 @@ class CalendarDocController break; default: - throw new UnexpectedValueException('Unsupported context'); + throw new \UnexpectedValueException('Unsupported context'); } $calendarDocEditDTO = new CalendarDoc\CalendarDocEditDTO($calendarDoc); diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarRangeAPIController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarRangeAPIController.php index 383e24efc..459d8f6aa 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarRangeAPIController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarRangeAPIController.php @@ -15,22 +15,15 @@ use Chill\CalendarBundle\Repository\CalendarRangeRepository; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Serializer\Model\Collection; -use DateTimeImmutable; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; - use Symfony\Component\Routing\Annotation\Route; class CalendarRangeAPIController extends ApiController { - private CalendarRangeRepository $calendarRangeRepository; - - public function __construct(CalendarRangeRepository $calendarRangeRepository) - { - $this->calendarRangeRepository = $calendarRangeRepository; - } + public function __construct(private readonly CalendarRangeRepository $calendarRangeRepository) {} /** * @Route("/api/1.0/calendar/calendar-range-available/{id}.{_format}", @@ -40,15 +33,15 @@ class CalendarRangeAPIController extends ApiController */ public function availableRanges(User $user, Request $request, string $_format): JsonResponse { - //return new JsonResponse(['ok' => true], 200, [], false); + // return new JsonResponse(['ok' => true], 200, [], false); $this->denyAccessUnlessGranted('ROLE_USER'); if (!$request->query->has('dateFrom')) { throw new BadRequestHttpException('You must provide a dateFrom parameter'); } - if (false === $dateFrom = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateFrom = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateFrom') )) { throw new BadRequestHttpException('dateFrom not parsable'); @@ -58,8 +51,8 @@ class CalendarRangeAPIController extends ApiController throw new BadRequestHttpException('You must provide a dateTo parameter'); } - if (false === $dateTo = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateTo = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateTo') )) { throw new BadRequestHttpException('dateTo not parsable'); diff --git a/src/Bundle/ChillCalendarBundle/Controller/InviteApiController.php b/src/Bundle/ChillCalendarBundle/Controller/InviteApiController.php index 3016e1660..784a6f6ce 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/InviteApiController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/InviteApiController.php @@ -31,22 +31,10 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; -use function in_array; class InviteApiController { - private EntityManagerInterface $entityManager; - - private MessageBusInterface $messageBus; - - private Security $security; - - public function __construct(EntityManagerInterface $entityManager, MessageBusInterface $messageBus, Security $security) - { - $this->entityManager = $entityManager; - $this->messageBus = $messageBus; - $this->security = $security; - } + public function __construct(private readonly EntityManagerInterface $entityManager, private readonly MessageBusInterface $messageBus, private readonly Security $security) {} /** * Give an answer to a calendar invite. @@ -69,7 +57,7 @@ class InviteApiController throw new AccessDeniedHttpException('not allowed to answer on this invitation'); } - if (!in_array($answer, Invite::STATUSES, true)) { + if (!\in_array($answer, Invite::STATUSES, true)) { throw new BadRequestHttpException('answer not valid'); } diff --git a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarConnectAzureController.php b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarConnectAzureController.php index 9352e42fa..75b417e93 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarConnectAzureController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarConnectAzureController.php @@ -30,17 +30,7 @@ use TheNetworg\OAuth2\Client\Token\AccessToken; class RemoteCalendarConnectAzureController { - private ClientRegistry $clientRegistry; - - private OnBehalfOfUserTokenStorage $MSGraphTokenStorage; - - public function __construct( - ClientRegistry $clientRegistry, - OnBehalfOfUserTokenStorage $MSGraphTokenStorage - ) { - $this->clientRegistry = $clientRegistry; - $this->MSGraphTokenStorage = $MSGraphTokenStorage; - } + public function __construct(private readonly ClientRegistry $clientRegistry, private readonly OnBehalfOfUserTokenStorage $MSGraphTokenStorage) {} /** * @Route("/{_locale}/connect/azure", name="chill_calendar_remote_connect_azure") diff --git a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarMSGraphSyncController.php b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarMSGraphSyncController.php index 535dda2f5..e7d423abd 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarMSGraphSyncController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarMSGraphSyncController.php @@ -19,22 +19,15 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Controller; use Chill\CalendarBundle\Messenger\Message\MSGraphChangeNotificationMessage; -use JsonException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; -use const JSON_THROW_ON_ERROR; class RemoteCalendarMSGraphSyncController { - private MessageBusInterface $messageBus; - - public function __construct(MessageBusInterface $messageBus) - { - $this->messageBus = $messageBus; - } + public function __construct(private readonly MessageBusInterface $messageBus) {} /** * @Route("/public/incoming-hook/calendar/msgraph/events/{userId}", name="chill_calendar_remote_msgraph_incoming_webhook_events", @@ -49,8 +42,8 @@ class RemoteCalendarMSGraphSyncController } try { - $body = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException $e) { + $body = json_decode($request->getContent(), true, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { throw new BadRequestHttpException('could not decode json', $e); } diff --git a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php index a95aa1a3f..673912c0a 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php @@ -22,32 +22,19 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterfa use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Serializer\Model\Collection; -use DateTimeImmutable; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; -use function count; /** * Contains method to get events (Calendar) from remote calendar. */ class RemoteCalendarProxyController { - private PaginatorFactory $paginatorFactory; - - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - private SerializerInterface $serializer; - - public function __construct(PaginatorFactory $paginatorFactory, RemoteCalendarConnectorInterface $remoteCalendarConnector, SerializerInterface $serializer) - { - $this->paginatorFactory = $paginatorFactory; - $this->remoteCalendarConnector = $remoteCalendarConnector; - $this->serializer = $serializer; - } + public function __construct(private readonly PaginatorFactory $paginatorFactory, private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector, private readonly SerializerInterface $serializer) {} /** * @Route("api/1.0/calendar/proxy/calendar/by-user/{id}/events") @@ -58,8 +45,8 @@ class RemoteCalendarProxyController throw new BadRequestHttpException('You must provide a dateFrom parameter'); } - if (false === $dateFrom = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateFrom = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateFrom') )) { throw new BadRequestHttpException('dateFrom not parsable'); @@ -69,8 +56,8 @@ class RemoteCalendarProxyController throw new BadRequestHttpException('You must provide a dateTo parameter'); } - if (false === $dateTo = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, + if (false === $dateTo = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::ATOM, $request->query->get('dateTo') )) { throw new BadRequestHttpException('dateTo not parsable'); @@ -98,8 +85,8 @@ class RemoteCalendarProxyController // in some case, we cannot paginate: we have to fetch all the items at once. We must avoid // further requests by forcing the number of items returned. - if (count($events) > $paginator->getItemsPerPage()) { - $paginator->setItemsPerPage(count($events)); + if (\count($events) > $paginator->getItemsPerPage()) { + $paginator->setItemsPerPage(\count($events)); } $collection = new Collection($events, $paginator); diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarACL.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarACL.php new file mode 100644 index 000000000..2ef7365ca --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarACL.php @@ -0,0 +1,54 @@ +setRole($role); + $manager->persist($r); + } + + foreach (LoadPermissionsGroup::$refs as $permissionGroupRef) { + /** @var PermissionsGroup $group */ + $group = $this->getReference($permissionGroupRef); + + foreach ($roleScopes as $scope) { + $group->addRoleScope($scope); + } + } + + $manager->flush(); + } + + public function getOrder(): int + { + return 16000; + } +} diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php index 805386669..f222823bf 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCalendarRange.php @@ -18,7 +18,6 @@ use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\LocationType; use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Repository\UserRepository; -use DateTimeImmutable; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; @@ -29,13 +28,7 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere { public static array $references = []; - private UserRepository $userRepository; - - public function __construct( - UserRepository $userRepository - ) { - $this->userRepository = $userRepository; - } + public function __construct(private readonly UserRepository $userRepository) {} public static function getGroups(): array { @@ -49,10 +42,6 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere public function load(ObjectManager $manager): void { - $arr = range(-50, 50); - - echo "Creating calendar range ('plage de disponibilités')\n"; - $users = $this->userRepository->findAll(); $location = (new Location()) @@ -73,6 +62,8 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere $manager->persist($type); $manager->persist($location); + $now = new \DateTimeImmutable(); + $days = [ '2021-08-23', '2021-08-24', @@ -82,8 +73,12 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere '2021-08-31', '2021-09-01', '2021-09-02', - (new DateTimeImmutable('tomorrow'))->format('Y-m-d'), - (new DateTimeImmutable('today'))->format('Y-m-d'), + (new \DateTimeImmutable('tomorrow'))->format('Y-m-d'), + (new \DateTimeImmutable('today'))->format('Y-m-d'), + $now->add(new \DateInterval('P7D'))->format('Y-m-d'), + $now->add(new \DateInterval('P8D'))->format('Y-m-d'), + $now->add(new \DateInterval('P9D'))->format('Y-m-d'), + $now->add(new \DateInterval('P10D'))->format('Y-m-d'), ]; $hours = [ @@ -96,9 +91,9 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere foreach ($users as $u) { foreach ($days as $d) { foreach ($hours as $h) { - $event = $d . ' ' . $h; - $startEvent = new DateTimeImmutable($event); - $endEvent = new DateTimeImmutable($event . ' + 1 hours'); + $event = $d.' '.$h; + $startEvent = new \DateTimeImmutable($event); + $endEvent = new \DateTimeImmutable($event.' + 1 hours'); $calendarRange = (new CalendarRange()) ->setUser($u) ->setStartDate($startEvent) diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php index bc5de7f70..d7e552d5d 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php @@ -39,12 +39,12 @@ class LoadCancelReason extends Fixture implements FixtureGroupInterface ]; foreach ($arr as $a) { - echo 'Creating calendar cancel reason : ' . $a['name'] . "\n"; + echo 'Creating calendar cancel reason : '.$a['name']."\n"; $cancelReason = (new CancelReason()) ->setCanceledBy($a['name']) ->setActive(true); $manager->persist($cancelReason); - $reference = 'CancelReason_' . $a['name']; + $reference = 'CancelReason_'.$a['name']; $this->addReference($reference, $cancelReason); static::$references[] = $reference; } diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php index ba325e296..f677a4283 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadInvite.php @@ -46,12 +46,12 @@ class LoadInvite extends Fixture implements FixtureGroupInterface ]; foreach ($arr as $a) { - echo 'Creating calendar invite : ' . $a['name']['fr'] . "\n"; + echo 'Creating calendar invite : '.$a['name']['fr']."\n"; $invite = (new Invite()) ->setStatus($a['status']) ->setUser($this->getRandomUser()); $manager->persist($invite); - $reference = 'Invite_' . $a['name']['fr']; + $reference = 'Invite_'.$a['name']['fr']; $this->addReference($reference, $invite); static::$references[] = $reference; } diff --git a/src/Bundle/ChillCalendarBundle/DependencyInjection/ChillCalendarExtension.php b/src/Bundle/ChillCalendarBundle/DependencyInjection/ChillCalendarExtension.php index c848366bb..5aa8d8507 100644 --- a/src/Bundle/ChillCalendarBundle/DependencyInjection/ChillCalendarExtension.php +++ b/src/Bundle/ChillCalendarBundle/DependencyInjection/ChillCalendarExtension.php @@ -31,7 +31,7 @@ class ChillCalendarExtension extends Extension implements PrependExtensionInterf $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); $loader->load('services/exports.yaml'); $loader->load('services/controller.yml'); diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index 79219a6e0..32308a50c 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -24,28 +24,26 @@ use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\ThirdPartyBundle\Entity\ThirdParty; -use DateInterval; -use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\ReadableCollection; +use Doctrine\Common\Collections\Selectable; use Doctrine\ORM\Mapping as ORM; -use LogicException; use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints\NotBlank; - use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Mapping\ClassMetadata; -use function in_array; /** * @ORM\Table( * name="chill_calendar.calendar", * uniqueConstraints={@ORM\UniqueConstraint(name="idx_calendar_remote", columns={"remoteId"}, options={"where": "remoteId <> ''"})} * ) + * * @ORM\Entity + * * @Serializer\DiscriminatorMap(typeProperty="type", mapping={ * "chill_calendar_calendar": Calendar::class * }) @@ -58,20 +56,20 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente use TrackUpdateTrait; - public const SMS_CANCEL_PENDING = 'sms_cancel_pending'; + final public const SMS_CANCEL_PENDING = 'sms_cancel_pending'; - public const SMS_PENDING = 'sms_pending'; + final public const SMS_PENDING = 'sms_pending'; - public const SMS_SENT = 'sms_sent'; + final public const SMS_SENT = 'sms_sent'; - public const STATUS_CANCELED = 'canceled'; + final public const STATUS_CANCELED = 'canceled'; /** * @deprecated */ - public const STATUS_MOVED = 'moved'; + final public const STATUS_MOVED = 'moved'; - public const STATUS_VALID = 'valid'; + final public const STATUS_VALID = 'valid'; /** * a list of invite which have been added during this session. @@ -93,6 +91,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; @@ -104,6 +103,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @ORM\OneToOne(targetEntity="CalendarRange", inversedBy="calendar") + * * @Serializer\Groups({"calendar:read", "read"}) */ private ?CalendarRange $calendarRange = null; @@ -115,6 +115,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @ORM\Embedded(class=CommentEmbeddable::class, columnPrefix="comment_") + * * @Serializer\Groups({"calendar:read", "read", "docgen:read"}) */ private CommentEmbeddable $comment; @@ -125,22 +126,28 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente private int $dateTimeVersion = 0; /** - * @var Collection + * @var Collection + * * @ORM\OneToMany(targetEntity=CalendarDoc::class, mappedBy="calendar", orphanRemoval=true) */ private Collection $documents; /** * @ORM\Column(type="datetime_immutable", nullable=false) + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) + * * @Assert\NotNull(message="calendar.An end date is required") */ - private ?DateTimeImmutable $endDate = null; + private ?\DateTimeImmutable $endDate = null; /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) */ private ?int $id = null; @@ -152,57 +159,80 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente * orphanRemoval=true, * cascade={"persist", "remove", "merge", "detach"} * ) + * * @ORM\JoinTable(name="chill_calendar.calendar_to_invites") + * * @Serializer\Groups({"read", "docgen:read"}) + * + * @var Collection&Selectable */ - private Collection $invites; + private Collection&Selectable $invites; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location") + * * @Serializer\Groups({"read", "docgen:read"}) + * * @Assert\NotNull(message="calendar.A location is required") */ private ?Location $location = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) + * * @Serializer\Context(normalizationContext={"read"}, groups={"calendar:light"}) + * * @Assert\NotNull(message="calendar.A main user is mandatory") */ private ?User $mainUser = null; /** * @ORM\ManyToOne(targetEntity=Person::class) + * * @ORM\JoinColumn(nullable=true) */ private ?Person $person = null; /** * @ORM\ManyToMany(targetEntity="Chill\PersonBundle\Entity\Person", inversedBy="calendars") + * * @ORM\JoinTable(name="chill_calendar.calendar_to_persons") + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) + * * @Serializer\Context(normalizationContext={"read"}, groups={"calendar:light"}) + * * @Assert\Count(min=1, minMessage="calendar.At least {{ limit }} person is required.") + * + * @var Collection */ private Collection $persons; /** * @ORM\Embedded(class=PrivateCommentEmbeddable::class, columnPrefix="privateComment_") + * * @Serializer\Groups({"calendar:read"}) */ private PrivateCommentEmbeddable $privateComment; /** + * @var Collection + * * @ORM\ManyToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty") + * * @ORM\JoinTable(name="chill_calendar.calendar_to_thirdparties") + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) + * * @Serializer\Context(normalizationContext={"read"}, groups={"calendar:light"}) */ private Collection $professionals; /** * @ORM\Column(type="boolean", nullable=true) + * * @Serializer\Groups({"docgen:read"}) */ private ?bool $sendSMS = false; @@ -214,21 +244,27 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @ORM\Column(type="datetime_immutable", nullable=false) + * * @Serializer\Groups({"calendar:read", "read", "calendar:light", "docgen:read"}) + * * @Serializer\Context(normalizationContext={"read"}, groups={"calendar:light"}) + * * @Assert\NotNull(message="calendar.A start date is required") */ - private ?DateTimeImmutable $startDate = null; + private ?\DateTimeImmutable $startDate = null; /** * @ORM\Column(type="string", length=255, nullable=false, options={"default": "valid"}) + * * @Serializer\Groups({"calendar:read", "read", "calendar:light"}) + * * @Serializer\Context(normalizationContext={"read"}, groups={"calendar:light"}) */ private string $status = self::STATUS_VALID; /** * @ORM\Column(type="boolean", nullable=true) + * * @Serializer\Groups({"docgen:read"}) */ private ?bool $urgent = false; @@ -261,7 +297,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente public function addInvite(Invite $invite): self { if ($invite->getCalendar() instanceof Calendar && $invite->getCalendar() !== $this) { - throw new LogicException('Not allowed to move an invitation to another Calendar'); + throw new \LogicException('Not allowed to move an invitation to another Calendar'); } $this->invites[] = $invite; @@ -317,16 +353,11 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente public function getCenters(): ?iterable { - switch ($this->getContext()) { - case 'person': - return [$this->getPerson()->getCenter()]; - - case 'accompanying_period': - return $this->getAccompanyingPeriod()->getCenters(); - - default: - throw new LogicException('context not supported: ' . $this->getContext()); - } + return match ($this->getContext()) { + 'person' => [$this->getPerson()->getCenter()], + 'accompanying_period' => $this->getAccompanyingPeriod()->getCenters(), + default => throw new \LogicException('context not supported: '.$this->getContext()), + }; } public function getComment(): CommentEmbeddable @@ -339,11 +370,11 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente */ public function getContext(): ?string { - if ($this->getAccompanyingPeriod() !== null) { + if (null !== $this->getAccompanyingPeriod()) { return 'accompanying_period'; } - if ($this->getPerson() !== null) { + if (null !== $this->getPerson()) { return 'person'; } @@ -366,16 +397,16 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @Serializer\Groups({"docgen:read"}) */ - public function getDuration(): ?DateInterval + public function getDuration(): ?\DateInterval { - if ($this->getStartDate() === null || $this->getEndDate() === null) { + if (null === $this->getStartDate() || null === $this->getEndDate()) { return null; } return $this->getStartDate()->diff($this->getEndDate()); } - public function getEndDate(): ?DateTimeImmutable + public function getEndDate(): ?\DateTimeImmutable { return $this->endDate; } @@ -454,7 +485,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente $personsNotAssociated = []; foreach ($this->persons as $person) { - if (!in_array($person, $this->getPersonsAssociated(), true)) { + if (!\in_array($person, $this->getPersonsAssociated(), true)) { $personsNotAssociated[] = $person; } } @@ -488,7 +519,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente return $this->smsStatus; } - public function getStartDate(): ?DateTimeImmutable + public function getStartDate(): ?\DateTimeImmutable { return $this->startDate; } @@ -510,6 +541,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente /** * @return ReadableCollection<(int|string), User> + * * @Serializer\Groups({"calendar:read", "read"}) */ public function getUsers(): ReadableCollection @@ -559,7 +591,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente public function removeDocument(CalendarDoc $calendarDoc): self { if ($calendarDoc->getCalendar() !== $this) { - throw new LogicException('cannot remove document of another calendar'); + throw new \LogicException('cannot remove document of another calendar'); } return $this; @@ -653,7 +685,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente return $this; } - public function setEndDate(DateTimeImmutable $endDate): self + public function setEndDate(\DateTimeImmutable $endDate): self { if (null === $this->endDate || $this->endDate->getTimestamp() !== $endDate->getTimestamp()) { $this->increaseaDatetimeVersion(); @@ -711,7 +743,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente return $this; } - public function setStartDate(DateTimeImmutable $startDate): self + public function setStartDate(\DateTimeImmutable $startDate): self { if (null === $this->startDate || $this->startDate->getTimestamp() !== $startDate->getTimestamp()) { $this->increaseaDatetimeVersion(); @@ -726,7 +758,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente { $this->status = $status; - if (self::STATUS_CANCELED === $status && $this->getSmsStatus() === self::SMS_SENT) { + if (self::STATUS_CANCELED === $status && self::SMS_SENT === $this->getSmsStatus()) { $this->setSmsStatus(self::SMS_CANCEL_PENDING); } diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc.php index 7012b64e0..5ea958fab 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc.php @@ -22,6 +22,7 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity + * * @ORM\Table( * name="chill_calendar.calendar_doc", * ) @@ -34,6 +35,7 @@ class CalendarDoc implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\ManyToOne(targetEntity=Calendar::class, inversedBy="documents") + * * @ORM\JoinColumn(nullable=false) */ private Calendar $calendar; @@ -45,27 +47,26 @@ class CalendarDoc implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ private ?int $id = null; - /** - * @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"}) - * @ORM\JoinColumn(nullable=false) - */ - private ?StoredObject $storedObject; - /** * @ORM\Column(type="boolean", nullable=false, options={"default": false}) */ private bool $trackDateTimeVersion = false; - public function __construct(Calendar $calendar, ?StoredObject $storedObject) + public function __construct(Calendar $calendar, /** + * @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"}) + * + * @ORM\JoinColumn(nullable=false) + */ + private ?StoredObject $storedObject) { $this->setCalendar($calendar); - - $this->storedObject = $storedObject; $this->datetimeVersion = $calendar->getDateTimeVersion(); } @@ -112,8 +113,6 @@ class CalendarDoc implements TrackCreationInterface, TrackUpdateInterface /** * @internal use @see{Calendar::removeDocument} instead - * - * @param Calendar $calendar */ public function setCalendar(?Calendar $calendar): CalendarDoc { diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocCreateDTO.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocCreateDTO.php index b7209e46f..ff4e10402 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocCreateDTO.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocCreateDTO.php @@ -18,12 +18,14 @@ class CalendarDocCreateDTO { /** * @Assert\NotNull + * * @Assert\Valid */ public ?StoredObject $doc = null; /** * @Assert\NotBlank + * * @Assert\NotNull */ public ?string $title = ''; diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocEditDTO.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocEditDTO.php index ff57d9876..2e8970db6 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocEditDTO.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarDoc/CalendarDocEditDTO.php @@ -24,6 +24,7 @@ class CalendarDocEditDTO /** * @Assert\NotBlank + * * @Assert\NotNull */ public ?string $title = ''; diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php index 5dbc4286f..0c46db57c 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php @@ -17,7 +17,6 @@ use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; @@ -27,6 +26,7 @@ use Symfony\Component\Validator\Constraints as Assert; * name="chill_calendar.calendar_range", * uniqueConstraints={@ORM\UniqueConstraint(name="idx_calendar_range_remote", columns={"remoteId"}, options={"where": "remoteId <> ''"})} * ) + * * @ORM\Entity */ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface @@ -44,37 +44,49 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="datetime_immutable", nullable=false) + * * @Groups({"read", "write", "calendar:read"}) + * * @Assert\NotNull */ - private ?DateTimeImmutable $endDate = null; + private ?\DateTimeImmutable $endDate = null; /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") + * * @Groups({"read"}) */ - private $id; + private ?int $id = null; /** * @ORM\ManyToOne(targetEntity=Location::class) + * * @ORM\JoinColumn(nullable=false) + * * @Groups({"read", "write", "calendar:read"}) + * * @Assert\NotNull */ private ?Location $location = null; /** * @ORM\Column(type="datetime_immutable", nullable=false) + * * @groups({"read", "write", "calendar:read"}) + * * @Assert\NotNull */ - private ?DateTimeImmutable $startDate = null; + private ?\DateTimeImmutable $startDate = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") + * * @Groups({"read", "write", "calendar:read"}) + * * @Assert\NotNull */ private ?User $user = null; @@ -84,7 +96,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface return $this->calendar; } - public function getEndDate(): ?DateTimeImmutable + public function getEndDate(): ?\DateTimeImmutable { return $this->endDate; } @@ -99,7 +111,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface return $this->location; } - public function getStartDate(): ?DateTimeImmutable + public function getStartDate(): ?\DateTimeImmutable { return $this->startDate; } @@ -117,7 +129,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface $this->calendar = $calendar; } - public function setEndDate(DateTimeImmutable $endDate): self + public function setEndDate(\DateTimeImmutable $endDate): self { $this->endDate = $endDate; @@ -131,7 +143,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface return $this; } - public function setStartDate(DateTimeImmutable $startDate): self + public function setStartDate(\DateTimeImmutable $startDate): self { $this->startDate = $startDate; diff --git a/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php b/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php index a262842c2..cff54e70b 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php @@ -16,37 +16,40 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Table(name="chill_calendar.cancel_reason") + * * @ORM\Entity(repositoryClass=CancelReasonRepository::class) */ class CancelReason { - public const CANCELEDBY_DONOTCOUNT = 'CANCELEDBY_DONOTCOUNT'; + final public const CANCELEDBY_DONOTCOUNT = 'CANCELEDBY_DONOTCOUNT'; - public const CANCELEDBY_PERSON = 'CANCELEDBY_PERSON'; + final public const CANCELEDBY_PERSON = 'CANCELEDBY_PERSON'; - public const CANCELEDBY_USER = 'CANCELEDBY_USER'; + final public const CANCELEDBY_USER = 'CANCELEDBY_USER'; /** * @ORM\Column(type="boolean") */ - private $active; + private ?bool $active = null; /** * @ORM\Column(type="string", length=255) */ - private $canceledBy; + private ?string $canceledBy = null; /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ - private $id; + private ?int $id = null; /** * @ORM\Column(type="json") */ - private $name = []; + private array $name = []; public function getActive(): ?bool { diff --git a/src/Bundle/ChillCalendarBundle/Entity/Invite.php b/src/Bundle/ChillCalendarBundle/Entity/Invite.php index c2d79aff2..48fe865b0 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Invite.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Invite.php @@ -17,7 +17,6 @@ use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\MainBundle\Entity\User; use Doctrine\ORM\Mapping as ORM; -use LogicException; use Symfony\Component\Serializer\Annotation as Serializer; /** @@ -30,6 +29,7 @@ use Symfony\Component\Serializer\Annotation as Serializer; * name="chill_calendar.invite", * uniqueConstraints={@ORM\UniqueConstraint(name="idx_calendar_invite_remote", columns={"remoteId"}, options={"where": "remoteId <> ''"})} * ) + * * @ORM\Entity */ class Invite implements TrackUpdateInterface, TrackCreationInterface @@ -40,23 +40,23 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface use TrackUpdateTrait; - public const ACCEPTED = 'accepted'; + final public const ACCEPTED = 'accepted'; - public const DECLINED = 'declined'; + final public const DECLINED = 'declined'; - public const PENDING = 'pending'; + final public const PENDING = 'pending'; /** * all statuses in one const. */ - public const STATUSES = [ + final public const STATUSES = [ self::ACCEPTED, self::DECLINED, self::PENDING, self::TENTATIVELY_ACCEPTED, ]; - public const TENTATIVELY_ACCEPTED = 'tentative'; + final public const TENTATIVELY_ACCEPTED = 'tentative'; /** * @ORM\ManyToOne(targetEntity=Calendar::class, inversedBy="invites") @@ -65,21 +65,27 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") + * * @Serializer\Groups(groups={"calendar:read", "read"}) */ private ?int $id = null; /** * @ORM\Column(type="text", nullable=false, options={"default": "pending"}) + * * @Serializer\Groups(groups={"calendar:read", "read", "docgen:read"}) */ private string $status = self::PENDING; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") + * * @ORM\JoinColumn(nullable=false) + * * @Serializer\Groups(groups={"calendar:read", "read", "docgen:read"}) */ private ?User $user = null; @@ -122,7 +128,7 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface public function setUser(?User $user): self { if ($user instanceof User && $this->user instanceof User && $user !== $this->user) { - throw new LogicException('Not allowed to associate an invite to a different user'); + throw new \LogicException('Not allowed to associate an invite to a different user'); } $this->user = $user; diff --git a/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php b/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php index 298a1ef9a..82c76eea4 100644 --- a/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php +++ b/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php @@ -15,16 +15,9 @@ use Chill\ActivityBundle\Entity\Activity; use Doctrine\Persistence\Event\LifecycleEventArgs; use Symfony\Component\HttpFoundation\RequestStack; -use function array_key_exists; - class ListenToActivityCreate { - private RequestStack $requestStack; - - public function __construct(RequestStack $requestStack) - { - $this->requestStack = $requestStack; - } + public function __construct(private readonly RequestStack $requestStack) {} public function postPersist(Activity $activity, LifecycleEventArgs $event): void { @@ -38,7 +31,7 @@ class ListenToActivityCreate if ($request->query->has('activityData')) { $activityData = $request->query->get('activityData'); - if (array_key_exists('calendarId', $activityData)) { + if (\array_key_exists('calendarId', $activityData)) { $calendarId = $activityData['calendarId']; // Attach the activity to the calendar diff --git a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php index a5e5a679a..dd2c0b9c2 100644 --- a/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php +++ b/src/Bundle/ChillCalendarBundle/Exception/UserAbsenceSyncException.php @@ -13,7 +13,7 @@ namespace Chill\CalendarBundle\Exception; class UserAbsenceSyncException extends \LogicException { - public function __construct(string $message = "", int $code = 20_230_706, ?\Throwable $previous = null) + public function __construct(string $message = '', int $code = 20_230_706, \Throwable $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php index 1b1b170b8..5e2091fac 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php @@ -15,24 +15,12 @@ use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Entity\UserRender; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -final class AgentAggregator implements AggregatorInterface +final readonly class AgentAggregator implements AggregatorInterface { - private UserRender $userRender; - - private UserRepository $userRepository; - - public function __construct( - UserRepository $userRepository, - UserRender $userRender - ) { - $this->userRepository = $userRepository; - $this->userRender = $userRender; - } + public function __construct(private UserRepository $userRepository, private UserRender $userRender) {} public function addRole(): ?string { @@ -41,7 +29,7 @@ final class AgentAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('caluser', $qb->getAllAliases(), true)) { + if (!\in_array('caluser', $qb->getAllAliases(), true)) { $qb->join('cal.mainUser', 'caluser'); } @@ -58,12 +46,13 @@ final class AgentAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php index a9967c470..7c84653d2 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php @@ -15,24 +15,12 @@ use Chill\CalendarBundle\Export\Declarations; use Chill\CalendarBundle\Repository\CancelReasonRepository; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; class CancelReasonAggregator implements AggregatorInterface { - private CancelReasonRepository $cancelReasonRepository; - - private TranslatableStringHelper $translatableStringHelper; - - public function __construct( - CancelReasonRepository $cancelReasonRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->cancelReasonRepository = $cancelReasonRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly CancelReasonRepository $cancelReasonRepository, private readonly TranslatableStringHelper $translatableStringHelper) {} public function addRole(): ?string { @@ -42,7 +30,7 @@ class CancelReasonAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { // TODO: still needs to take into account calendars without a cancel reason somehow - if (!in_array('calcancel', $qb->getAllAliases(), true)) { + if (!\in_array('calcancel', $qb->getAllAliases(), true)) { $qb->join('cal.cancelReason', 'calcancel'); } @@ -59,12 +47,13 @@ class CancelReasonAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php index 51291b49e..76cbe5cd8 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php @@ -12,27 +12,22 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Export\Aggregator; use Chill\CalendarBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\UserJobRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Closure; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -final class JobAggregator implements AggregatorInterface +final readonly class JobAggregator implements AggregatorInterface { - private UserJobRepository $jobRepository; - - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'cal_agg_job'; public function __construct( - UserJobRepository $jobRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->jobRepository = $jobRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private UserJobRepository $jobRepository, + private TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -41,12 +36,28 @@ final class JobAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(caluser.userJob) as job_aggregator'); - $qb->addGroupBy('job_aggregator'); + $qb + ->leftJoin('cal.mainUser', "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // job_at based on cal.startDate + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'cal.startDate'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'cal.startDate') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.job) AS {$p}_select") + ->addGroupBy("{$p}_select"); } public function applyOn(): string @@ -54,16 +65,14 @@ final class JobAggregator implements AggregatorInterface return Declarations::CALENDAR_TYPE; } - public function buildForm(FormBuilderInterface $builder) - { - // no form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { @@ -74,7 +83,9 @@ final class JobAggregator implements AggregatorInterface return ''; } - $j = $this->jobRepository->find($value); + if (null === $j = $this->jobRepository->find($value)) { + return ''; + } return $this->translatableStringHelper->localize( $j->getLabel() @@ -84,11 +95,11 @@ final class JobAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['job_aggregator']; + return [self::PREFIX.'_select']; } public function getTitle(): string { - return 'Group calendars by agent job'; + return 'export.aggregator.calendar.agent_job.Group calendars by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php index 952d0c5d5..6481f95b4 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php @@ -14,20 +14,12 @@ namespace Chill\CalendarBundle\Export\Aggregator; use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\LocationRepository; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -final class LocationAggregator implements AggregatorInterface +final readonly class LocationAggregator implements AggregatorInterface { - private LocationRepository $locationRepository; - - public function __construct( - LocationRepository $locationRepository - ) { - $this->locationRepository = $locationRepository; - } + public function __construct(private LocationRepository $locationRepository) {} public function addRole(): ?string { @@ -36,7 +28,7 @@ final class LocationAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('calloc', $qb->getAllAliases(), true)) { + if (!\in_array('calloc', $qb->getAllAliases(), true)) { $qb->join('cal.location', 'calloc'); } $qb->addSelect('IDENTITY(cal.location) as location_aggregator'); @@ -52,12 +44,13 @@ final class LocationAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php index a9b369af0..be9406cfa 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php @@ -15,24 +15,12 @@ use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\LocationTypeRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -final class LocationTypeAggregator implements AggregatorInterface +final readonly class LocationTypeAggregator implements AggregatorInterface { - private LocationTypeRepository $locationTypeRepository; - - private TranslatableStringHelper $translatableStringHelper; - - public function __construct( - LocationTypeRepository $locationTypeRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->locationTypeRepository = $locationTypeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private LocationTypeRepository $locationTypeRepository, private TranslatableStringHelper $translatableStringHelper) {} public function addRole(): ?string { @@ -41,7 +29,7 @@ final class LocationTypeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('calloc', $qb->getAllAliases(), true)) { + if (!\in_array('calloc', $qb->getAllAliases(), true)) { $qb->join('cal.location', 'calloc'); } @@ -58,12 +46,13 @@ final class LocationTypeAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php index b3c2aaf19..6bf65b8ef 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php @@ -13,7 +13,6 @@ namespace Chill\CalendarBundle\Export\Aggregator; use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; -use Closure; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -40,12 +39,13 @@ class MonthYearAggregator implements AggregatorInterface { // No form needed } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return static function ($value): string { if ('_header' === $value) { diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php index 01874b0e2..4998f6d1f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php @@ -12,27 +12,22 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Export\Aggregator; use Chill\CalendarBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\AggregatorInterface; use Chill\MainBundle\Repository\ScopeRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Closure; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; -use function in_array; -final class ScopeAggregator implements AggregatorInterface +final readonly class ScopeAggregator implements AggregatorInterface { - private ScopeRepository $scopeRepository; - - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'cal_agg_scope'; public function __construct( - ScopeRepository $scopeRepository, - TranslatableStringHelper $translatableStringHelper - ) { - $this->scopeRepository = $scopeRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private ScopeRepository $scopeRepository, + private TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -41,12 +36,28 @@ final class ScopeAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); - } + $p = self::PREFIX; - $qb->addSelect('IDENTITY(caluser.mainScope) as scope_aggregator'); - $qb->addGroupBy('scope_aggregator'); + $qb + ->leftJoin('cal.mainUser', "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // scope_at based on cal.startDate + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'cal.startDate'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'cal.startDate') + ) + ) + ) + ->addSelect("IDENTITY({$p}_history.scope) AS {$p}_select") + ->addGroupBy("{$p}_select"); } public function applyOn(): string @@ -54,16 +65,14 @@ final class ScopeAggregator implements AggregatorInterface return Declarations::CALENDAR_TYPE; } - public function buildForm(FormBuilderInterface $builder) - { - // no form - } + public function buildForm(FormBuilderInterface $builder) {} + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { @@ -74,7 +83,9 @@ final class ScopeAggregator implements AggregatorInterface return ''; } - $s = $this->scopeRepository->find($value); + if (null === $s = $this->scopeRepository->find($value)) { + return ''; + } return $this->translatableStringHelper->localize( $s->getName() @@ -84,11 +95,11 @@ final class ScopeAggregator implements AggregatorInterface public function getQueryKeys($data): array { - return ['scope_aggregator']; + return [self::PREFIX.'_select']; } public function getTitle(): string { - return 'Group calendars by agent scope'; + return 'export.aggregator.calendar.agent_scope.Group calendars by agent scope'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php index 66ab8b42e..e9213d3cb 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php +++ b/src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php @@ -20,21 +20,13 @@ namespace Chill\CalendarBundle\Export\Aggregator; use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\AggregatorInterface; -use Closure; use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; class UrgencyAggregator implements AggregatorInterface { - private TranslatorInterface $translator; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - } + public function __construct(private readonly TranslatorInterface $translator) {} public function addRole(): ?string { @@ -56,28 +48,24 @@ class UrgencyAggregator implements AggregatorInterface { // no form } + public function getFormDefaultData(): array { return []; } - public function getLabels($key, array $values, $data): Closure + public function getLabels($key, array $values, $data): \Closure { return function ($value): string { if ('_header' === $value) { return 'Urgency'; } - switch ($value) { - case true: - return $this->translator->trans('is urgent'); - - case false: - return $this->translator->trans('is not urgent'); - - default: - throw new LogicException(sprintf('The value %s is not valid', $value)); - } + return match ($value) { + true => $this->translator->trans('is urgent'), + false => $this->translator->trans('is not urgent'), + default => throw new \LogicException(sprintf('The value %s is not valid', $value)), + }; }; } diff --git a/src/Bundle/ChillCalendarBundle/Export/Declarations.php b/src/Bundle/ChillCalendarBundle/Export/Declarations.php index 0df90749c..a007424e5 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Declarations.php +++ b/src/Bundle/ChillCalendarBundle/Export/Declarations.php @@ -16,5 +16,5 @@ namespace Chill\CalendarBundle\Export; */ abstract class Declarations { - public const CALENDAR_TYPE = 'calendar'; + final public const CALENDAR_TYPE = 'calendar'; } diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php index e0391948e..2e156d7a0 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php @@ -13,11 +13,11 @@ namespace Chill\CalendarBundle\Export\Export; use Chill\CalendarBundle\Export\Declarations; use Chill\CalendarBundle\Repository\CalendarRepository; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\PersonBundle\Security\Authorization\PersonVoter; -use Closure; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -25,17 +25,13 @@ use Symfony\Component\Validator\Exception\LogicException; class CountCalendars implements ExportInterface, GroupedExportInterface { - private CalendarRepository $calendarRepository; - - public function __construct(CalendarRepository $calendarRepository) - { - $this->calendarRepository = $calendarRepository; - } + public function __construct(private readonly CalendarRepository $calendarRepository) {} public function buildForm(FormBuilderInterface $builder) { // No form necessary } + public function getFormDefaultData(): array { return []; @@ -98,6 +94,9 @@ class CountCalendars implements ExportInterface, GroupedExportInterface $qb = $this->calendarRepository->createQueryBuilder('cal'); $qb->select('COUNT(cal.id) AS export_result'); + $qb->leftJoin('cal.accompanyingPeriod', 'acp'); + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); return $qb; } diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php index dcbfb695b..b69185a17 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarAvgDuration.php @@ -13,29 +13,24 @@ namespace Chill\CalendarBundle\Export\Export; use Chill\CalendarBundle\Export\Declarations; use Chill\CalendarBundle\Repository\CalendarRepository; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { - private CalendarRepository $calendarRepository; - - public function __construct( - CalendarRepository $calendarRepository - ) { - $this->calendarRepository = $calendarRepository; - } + public function __construct(private readonly CalendarRepository $calendarRepository) {} public function buildForm(FormBuilderInterface $builder): void { // no form needed } + public function getFormDefaultData(): array { return []; @@ -59,7 +54,7 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_result' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } $labels = array_combine($values, $values); @@ -92,8 +87,10 @@ class StatCalendarAvgDuration implements ExportInterface, GroupedExportInterface { $qb = $this->calendarRepository->createQueryBuilder('cal'); - $qb - ->select('AVG(cal.endDate - cal.startDate) AS export_result'); + $qb->select('AVG(cal.endDate - cal.startDate) AS export_result'); + $qb->join('cal.accompanyingPeriod', 'acp'); + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); return $qb; } diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php index 7f509a896..8ea23014c 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php +++ b/src/Bundle/ChillCalendarBundle/Export/Export/StatCalendarSumDuration.php @@ -13,29 +13,24 @@ namespace Chill\CalendarBundle\Export\Export; use Chill\CalendarBundle\Export\Declarations; use Chill\CalendarBundle\Repository\CalendarRepository; +use Chill\MainBundle\Export\AccompanyingCourseExportHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\FormatterInterface; use Chill\MainBundle\Export\GroupedExportInterface; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; -use LogicException; use Symfony\Component\Form\FormBuilderInterface; class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { - private CalendarRepository $calendarRepository; - - public function __construct( - CalendarRepository $calendarRepository - ) { - $this->calendarRepository = $calendarRepository; - } + public function __construct(private readonly CalendarRepository $calendarRepository) {} public function buildForm(FormBuilderInterface $builder): void { // no form needed } + public function getFormDefaultData(): array { return []; @@ -59,7 +54,7 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface public function getLabels($key, array $values, $data) { if ('export_result' !== $key) { - throw new LogicException("the key {$key} is not used by this export"); + throw new \LogicException("the key {$key} is not used by this export"); } $labels = array_combine($values, $values); @@ -92,8 +87,10 @@ class StatCalendarSumDuration implements ExportInterface, GroupedExportInterface { $qb = $this->calendarRepository->createQueryBuilder('cal'); - $qb - ->select('SUM(cal.endDate - cal.startDate) AS export_result'); + $qb->select('SUM(cal.endDate - cal.startDate) AS export_result'); + $qb->join('cal.accompanyingPeriod', 'acp'); + + AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); return $qb; } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php index 0cef89c20..c16c148fc 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php @@ -22,12 +22,7 @@ use Symfony\Component\Form\FormBuilderInterface; class AgentFilter implements FilterInterface { - private UserRender $userRender; - - public function __construct(UserRender $userRender) - { - $this->userRender = $userRender; - } + public function __construct(private readonly UserRender $userRender) {} public function addRole(): ?string { @@ -63,6 +58,7 @@ class AgentFilter implements FilterInterface 'expanded' => true, ]); } + public function getFormDefaultData(): array { return []; diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php index 4260ecd99..90a004388 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php @@ -21,12 +21,7 @@ use Symfony\Component\Form\FormBuilderInterface; class BetweenDatesFilter implements FilterInterface { - private RollingDateConverterInterface $rollingDateConverter; - - public function __construct(RollingDateConverterInterface $rollingDateConverter) - { - $this->rollingDateConverter = $rollingDateConverter; - } + public function __construct(private readonly RollingDateConverterInterface $rollingDateConverter) {} public function addRole(): ?string { @@ -63,6 +58,7 @@ class BetweenDatesFilter implements FilterInterface ->add('date_from', PickRollingDateType::class, []) ->add('date_to', PickRollingDateType::class, []); } + public function getFormDefaultData(): array { return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)]; diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php index 84ec77e6b..63149509f 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php @@ -20,7 +20,6 @@ namespace Chill\CalendarBundle\Export\Filter; use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Export\FilterInterface; -use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; @@ -35,12 +34,7 @@ class CalendarRangeFilter implements FilterInterface private const DEFAULT_CHOICE = 'false'; - private TranslatorInterface $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } + public function __construct(private readonly TranslatorInterface $translator) {} public function addRole(): ?string { @@ -71,6 +65,7 @@ class CalendarRangeFilter implements FilterInterface 'empty_data' => self::DEFAULT_CHOICE, ]); } + public function getFormDefaultData(): array { return ['hasCalendarRange' => self::DEFAULT_CHOICE]; diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php index d02bb8e9d..c122a298d 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php @@ -12,29 +12,22 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Export\Filter; use Chill\CalendarBundle\Export\Declarations; +use Chill\MainBundle\Entity\User\UserJobHistory; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\Query\Expr\Andx; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Contracts\Translation\TranslatorInterface; -use function in_array; -class JobFilter implements FilterInterface +final readonly class JobFilter implements FilterInterface { - protected TranslatorInterface $translator; - - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'cal_filter_job'; public function __construct( - TranslatorInterface $translator, - TranslatableStringHelper $translatableStringHelper - ) { - $this->translator = $translator; - $this->translatableStringHelper = $translatableStringHelper; - } + private TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -43,21 +36,31 @@ class JobFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); - } + $p = self::PREFIX; - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('caluser.userJob', ':job'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('job', $data['job']); + $qb + ->leftJoin('cal.mainUser', "{$p}_user") + ->leftJoin( + UserJobHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // job_at based on cal.startDate + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'cal.startDate'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'cal.startDate') + ) + ) + ) + ->andWhere($qb->expr()->in("{$p}_history.job", ":{$p}_job")) + ->setParameter( + "{$p}_job", + $data['job'] + ); } public function applyOn(): string @@ -67,18 +70,15 @@ class JobFilter implements FilterInterface public function buildForm(FormBuilderInterface $builder) { - $builder->add('job', EntityType::class, [ - 'class' => UserJob::class, - 'choice_label' => fn (UserJob $j) => $this->translatableStringHelper->localize( - $j->getLabel() - ), - 'multiple' => true, - 'expanded' => true, - ]); - } - public function getFormDefaultData(): array - { - return []; + $builder + ->add('job', 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'): array @@ -91,13 +91,20 @@ class JobFilter implements FilterInterface ); } - return ['Filtered by agent job: only %jobs%', [ + return ['export.filter.calendar.agent_job.Filtered by agent job: only %jobs%', [ '%jobs%' => implode(', ', $userJobs), ]]; } + public function getFormDefaultData(): array + { + return [ + 'job' => [], + ]; + } + public function getTitle(): string { - return 'Filter calendars by agent job'; + return 'export.filter.calendar.agent_job.Filter calendars by agent job'; } } diff --git a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php index d8a40da72..93edc1b3a 100644 --- a/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php +++ b/src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php @@ -13,28 +13,23 @@ namespace Chill\CalendarBundle\Export\Filter; use Chill\CalendarBundle\Export\Declarations; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Entity\User\UserScopeHistory; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\Query\Expr\Andx; +use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Contracts\Translation\TranslatorInterface; -use function in_array; class ScopeFilter implements FilterInterface { - protected TranslatorInterface $translator; - - private TranslatableStringHelper $translatableStringHelper; + private const PREFIX = 'cal_filter_scope'; public function __construct( - TranslatorInterface $translator, - TranslatableStringHelper $translatableStringHelper - ) { - $this->translator = $translator; - $this->translatableStringHelper = $translatableStringHelper; - } + protected TranslatorInterface $translator, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function addRole(): ?string { @@ -43,45 +38,52 @@ class ScopeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { - if (!in_array('caluser', $qb->getAllAliases(), true)) { - $qb->join('cal.mainUser', 'caluser'); - } + $p = self::PREFIX; - $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('caluser.mainScope', ':scope'); - - if ($where instanceof Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('scope', $data['scope']); + $qb + ->leftJoin('cal.mainUser', "{$p}_user") + ->leftJoin( + UserScopeHistory::class, + "{$p}_history", + Join::WITH, + $qb->expr()->eq("{$p}_history.user", "{$p}_user") + ) + // scope_at based on cal.startDate + ->andWhere( + $qb->expr()->andX( + $qb->expr()->lte("{$p}_history.startDate", 'cal.startDate'), + $qb->expr()->orX( + $qb->expr()->isNull("{$p}_history.endDate"), + $qb->expr()->gt("{$p}_history.endDate", 'cal.startDate') + ) + ) + ) + ->andWhere($qb->expr()->in("{$p}_history.scope", ":{$p}_scope")) + ->setParameter( + "{$p}_scope", + $data['scope'] + ); } - public function applyOn() + public function applyOn(): string { return Declarations::CALENDAR_TYPE; } public function buildForm(FormBuilderInterface $builder) { - $builder->add('scope', EntityType::class, [ - 'class' => Scope::class, - 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( - $s->getName() - ), - 'multiple' => true, - 'expanded' => true, - ]); - } - public function getFormDefaultData(): array - { - return []; + $builder + ->add('scope', EntityType::class, [ + 'class' => Scope::class, + 'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize( + $s->getName() + ), + 'multiple' => true, + 'expanded' => true, + ]); } - public function describeAction($data, $format = 'string') + public function describeAction($data, $format = 'string'): array { $scopes = []; @@ -91,13 +93,20 @@ class ScopeFilter implements FilterInterface ); } - return ['Filtered by agent scope: only %scopes%', [ + return ['export.filter.calendar.agent_scope.Filtered by agent scope: only %scopes%', [ '%scopes%' => implode(', ', $scopes), ]]; } - public function getTitle() + public function getFormDefaultData(): array { - return 'Filter calendars by agent scope'; + return [ + 'scope' => [], + ]; + } + + public function getTitle(): string + { + return 'export.filter.calendar.agent_scope.Filter calendars by agent scope'; } } diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php index 34a501028..224a74f01 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php @@ -12,7 +12,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Form; use Chill\CalendarBundle\Entity\CalendarDoc\CalendarDocEditDTO; -use Chill\DocStoreBundle\Form\StoredObjectType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php index a2d15484f..eec0b3f9f 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php @@ -21,7 +21,6 @@ use Chill\MainBundle\Form\Type\CommentType; use Chill\MainBundle\Form\Type\PrivateCommentType; use Chill\PersonBundle\Form\DataTransformer\PersonsToIdDataTransformer; use Chill\ThirdPartyBundle\Form\DataTransformer\ThirdPartiesToIdDataTransformer; -use DateTimeImmutable; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; @@ -32,33 +31,14 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class CalendarType extends AbstractType { - private IdToCalendarRangeDataTransformer $calendarRangeDataTransformer; - - private IdToLocationDataTransformer $idToLocationDataTransformer; - - private IdToUserDataTransformer $idToUserDataTransformer; - - private IdToUsersDataTransformer $idToUsersDataTransformer; - - private ThirdPartiesToIdDataTransformer $partiesToIdDataTransformer; - - private PersonsToIdDataTransformer $personsToIdDataTransformer; - public function __construct( - PersonsToIdDataTransformer $personsToIdDataTransformer, - IdToUserDataTransformer $idToUserDataTransformer, - IdToUsersDataTransformer $idToUsersDataTransformer, - IdToLocationDataTransformer $idToLocationDataTransformer, - ThirdPartiesToIdDataTransformer $partiesToIdDataTransformer, - IdToCalendarRangeDataTransformer $idToCalendarRangeDataTransformer - ) { - $this->personsToIdDataTransformer = $personsToIdDataTransformer; - $this->idToUserDataTransformer = $idToUserDataTransformer; - $this->idToUsersDataTransformer = $idToUsersDataTransformer; - $this->idToLocationDataTransformer = $idToLocationDataTransformer; - $this->partiesToIdDataTransformer = $partiesToIdDataTransformer; - $this->calendarRangeDataTransformer = $idToCalendarRangeDataTransformer; - } + private readonly PersonsToIdDataTransformer $personsToIdDataTransformer, + private readonly IdToUserDataTransformer $idToUserDataTransformer, + private readonly IdToUsersDataTransformer $idToUsersDataTransformer, + private readonly IdToLocationDataTransformer $idToLocationDataTransformer, + private readonly ThirdPartiesToIdDataTransformer $partiesToIdDataTransformer, + private readonly IdToCalendarRangeDataTransformer $calendarRangeDataTransformer + ) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -91,42 +71,42 @@ class CalendarType extends AbstractType $builder->add('startDate', HiddenType::class); $builder->get('startDate') ->addModelTransformer(new CallbackTransformer( - static function (?DateTimeImmutable $dateTimeImmutable): string { + static function (?\DateTimeImmutable $dateTimeImmutable): string { if (null !== $dateTimeImmutable) { - $res = date_format($dateTimeImmutable, DateTimeImmutable::ATOM); + $res = date_format($dateTimeImmutable, \DateTimeImmutable::ATOM); } else { $res = ''; } return $res; }, - static function (?string $dateAsString): ?DateTimeImmutable { + static function (?string $dateAsString): ?\DateTimeImmutable { if ('' === $dateAsString || null === $dateAsString) { return null; } - return DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, $dateAsString); + return \DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, $dateAsString); } )); $builder->add('endDate', HiddenType::class); $builder->get('endDate') ->addModelTransformer(new CallbackTransformer( - static function (?DateTimeImmutable $dateTimeImmutable): string { + static function (?\DateTimeImmutable $dateTimeImmutable): string { if (null !== $dateTimeImmutable) { - $res = date_format($dateTimeImmutable, DateTimeImmutable::ATOM); + $res = date_format($dateTimeImmutable, \DateTimeImmutable::ATOM); } else { $res = ''; } return $res; }, - static function (?string $dateAsString): ?DateTimeImmutable { + static function (?string $dateAsString): ?\DateTimeImmutable { if ('' === $dateAsString || null === $dateAsString) { return null; } - return DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, $dateAsString); + return \DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, $dateAsString); } )); diff --git a/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php index 4b9dca19f..6dd5bfa52 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -19,17 +19,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface { - protected TranslatorInterface $translator; - - private Security $security; - - public function __construct( - Security $security, - TranslatorInterface $translator - ) { - $this->security = $security; - $this->translator = $translator; - } + public function __construct(private readonly Security $security, protected TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillCalendarBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/PersonMenuBuilder.php index eccbe1ffb..e92a72bb7 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/PersonMenuBuilder.php @@ -19,17 +19,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class PersonMenuBuilder implements LocalMenuBuilderInterface { - protected TranslatorInterface $translator; - - private Security $security; - - public function __construct( - Security $security, - TranslatorInterface $translator - ) { - $this->security = $security; - $this->translator = $translator; - } + public function __construct(private readonly Security $security, protected TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php index 525039910..3a062f7b8 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php @@ -18,17 +18,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class UserMenuBuilder implements LocalMenuBuilderInterface { - public TranslatorInterface $translator; - - private Security $security; - - public function __construct( - Security $security, - TranslatorInterface $translator - ) { - $this->security = $security; - $this->translator = $translator; - } + public function __construct(private readonly Security $security, public TranslatorInterface $translator) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php index f97cbc7b2..8f62fdcdb 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php @@ -21,7 +21,6 @@ namespace Chill\CalendarBundle\Messenger\Doctrine; 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; @@ -30,15 +29,7 @@ use Symfony\Component\Security\Core\Security; class CalendarEntityListener { - private MessageBusInterface $messageBus; - - private Security $security; - - public function __construct(MessageBusInterface $messageBus, Security $security) - { - $this->messageBus = $messageBus; - $this->security = $security; - } + public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {} public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php index 4df548277..8b875bdcb 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarRangeEntityListener.php @@ -21,7 +21,6 @@ namespace Chill\CalendarBundle\Messenger\Doctrine; 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; @@ -30,15 +29,7 @@ use Symfony\Component\Security\Core\Security; class CalendarRangeEntityListener { - private MessageBusInterface $messageBus; - - private Security $security; - - public function __construct(MessageBusInterface $messageBus, Security $security) - { - $this->messageBus = $messageBus; - $this->security = $security; - } + public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {} public function postPersist(CalendarRange $calendarRange, PostPersistEventArgs $eventArgs): void { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeRemoveToRemoteHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeRemoveToRemoteHandler.php index 4e3ae5891..7749d503c 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeRemoveToRemoteHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeRemoveToRemoteHandler.php @@ -31,15 +31,7 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class CalendarRangeRemoveToRemoteHandler implements MessageHandlerInterface { - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - private UserRepository $userRepository; - - public function __construct(RemoteCalendarConnectorInterface $remoteCalendarConnector, UserRepository $userRepository) - { - $this->remoteCalendarConnector = $remoteCalendarConnector; - $this->userRepository = $userRepository; - } + public function __construct(private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector, private readonly UserRepository $userRepository) {} public function __invoke(CalendarRangeRemovedMessage $calendarRangeRemovedMessage) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeToRemoteHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeToRemoteHandler.php index 79bcd24ee..c9fd1b939 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeToRemoteHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRangeToRemoteHandler.php @@ -32,21 +32,7 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class CalendarRangeToRemoteHandler implements MessageHandlerInterface { - private CalendarRangeRepository $calendarRangeRepository; - - private EntityManagerInterface $entityManager; - - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - public function __construct( - CalendarRangeRepository $calendarRangeRepository, - RemoteCalendarConnectorInterface $remoteCalendarConnector, - EntityManagerInterface $entityManager - ) { - $this->calendarRangeRepository = $calendarRangeRepository; - $this->remoteCalendarConnector = $remoteCalendarConnector; - $this->entityManager = $entityManager; - } + public function __construct(private readonly CalendarRangeRepository $calendarRangeRepository, private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector, private readonly EntityManagerInterface $entityManager) {} public function __invoke(CalendarRangeMessage $calendarRangeMessage): void { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRemoveHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRemoveHandler.php index f087766ec..73e8a0c37 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRemoveHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarRemoveHandler.php @@ -31,18 +31,7 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class CalendarRemoveHandler implements MessageHandlerInterface { - private CalendarRangeRepository $calendarRangeRepository; - - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - private UserRepositoryInterface $userRepository; - - public function __construct(RemoteCalendarConnectorInterface $remoteCalendarConnector, CalendarRangeRepository $calendarRangeRepository, UserRepositoryInterface $userRepository) - { - $this->remoteCalendarConnector = $remoteCalendarConnector; - $this->calendarRangeRepository = $calendarRangeRepository; - $this->userRepository = $userRepository; - } + public function __construct(private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector, private readonly CalendarRangeRepository $calendarRangeRepository, private readonly UserRepositoryInterface $userRepository) {} public function __invoke(CalendarRemovedMessage $message) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php index eabdf9063..6a1388d2e 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/CalendarToRemoteHandler.php @@ -37,33 +37,7 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class CalendarToRemoteHandler implements MessageHandlerInterface { - private RemoteCalendarConnectorInterface $calendarConnector; - - private CalendarRangeRepository $calendarRangeRepository; - - private CalendarRepository $calendarRepository; - - private EntityManagerInterface $entityManager; - - private InviteRepository $inviteRepository; - - private UserRepository $userRepository; - - public function __construct( - CalendarRangeRepository $calendarRangeRepository, - CalendarRepository $calendarRepository, - EntityManagerInterface $entityManager, - InviteRepository $inviteRepository, - RemoteCalendarConnectorInterface $calendarConnector, - UserRepository $userRepository - ) { - $this->calendarConnector = $calendarConnector; - $this->calendarRepository = $calendarRepository; - $this->calendarRangeRepository = $calendarRangeRepository; - $this->entityManager = $entityManager; - $this->userRepository = $userRepository; - $this->inviteRepository = $inviteRepository; - } + public function __construct(private readonly CalendarRangeRepository $calendarRangeRepository, private readonly CalendarRepository $calendarRepository, private readonly EntityManagerInterface $entityManager, private readonly InviteRepository $inviteRepository, private readonly RemoteCalendarConnectorInterface $calendarConnector, private readonly UserRepository $userRepository) {} public function __invoke(CalendarMessage $calendarMessage) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/InviteUpdateHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/InviteUpdateHandler.php index e1df3ac3d..7ca5f2c12 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/InviteUpdateHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/InviteUpdateHandler.php @@ -31,18 +31,7 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class InviteUpdateHandler implements MessageHandlerInterface { - private EntityManagerInterface $em; - - private InviteRepository $inviteRepository; - - private RemoteCalendarConnectorInterface $remoteCalendarConnector; - - public function __construct(EntityManagerInterface $em, InviteRepository $inviteRepository, RemoteCalendarConnectorInterface $remoteCalendarConnector) - { - $this->em = $em; - $this->inviteRepository = $inviteRepository; - $this->remoteCalendarConnector = $remoteCalendarConnector; - } + public function __construct(private readonly EntityManagerInterface $em, private readonly InviteRepository $inviteRepository, private readonly RemoteCalendarConnectorInterface $remoteCalendarConnector) {} public function __invoke(InviteUpdateMessage $inviteUpdateMessage): void { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php b/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php index a09c70c1e..7a67bee61 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Handler/MSGraphChangeNotificationHandler.php @@ -36,48 +36,14 @@ use Symfony\Component\Messenger\Handler\MessageHandlerInterface; */ class MSGraphChangeNotificationHandler implements MessageHandlerInterface { - private CalendarRangeRepository $calendarRangeRepository; - - private CalendarRangeSyncer $calendarRangeSyncer; - - private CalendarRepository $calendarRepository; - - private CalendarSyncer $calendarSyncer; - - private EntityManagerInterface $em; - - private LoggerInterface $logger; - - private MapCalendarToUser $mapCalendarToUser; - - private UserRepository $userRepository; - - public function __construct( - CalendarRangeRepository $calendarRangeRepository, - CalendarRangeSyncer $calendarRangeSyncer, - CalendarRepository $calendarRepository, - CalendarSyncer $calendarSyncer, - EntityManagerInterface $em, - LoggerInterface $logger, - MapCalendarToUser $mapCalendarToUser, - UserRepository $userRepository - ) { - $this->calendarRangeRepository = $calendarRangeRepository; - $this->calendarRangeSyncer = $calendarRangeSyncer; - $this->calendarRepository = $calendarRepository; - $this->calendarSyncer = $calendarSyncer; - $this->em = $em; - $this->logger = $logger; - $this->mapCalendarToUser = $mapCalendarToUser; - $this->userRepository = $userRepository; - } + public function __construct(private readonly CalendarRangeRepository $calendarRangeRepository, private readonly CalendarRangeSyncer $calendarRangeSyncer, private readonly CalendarRepository $calendarRepository, private readonly CalendarSyncer $calendarSyncer, private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly MapCalendarToUser $mapCalendarToUser, private readonly UserRepository $userRepository) {} public function __invoke(MSGraphChangeNotificationMessage $changeNotificationMessage): void { $user = $this->userRepository->find($changeNotificationMessage->getUserId()); if (null === $user) { - $this->logger->warning(self::class . ' notification concern non-existent user, skipping'); + $this->logger->warning(self::class.' notification concern non-existent user, skipping'); return; } @@ -86,7 +52,7 @@ class MSGraphChangeNotificationHandler implements MessageHandlerInterface $secret = $this->mapCalendarToUser->getSubscriptionSecret($user); if ($secret !== ($notification['clientState'] ?? -1)) { - $this->logger->warning(self::class . ' could not validate secret, skipping'); + $this->logger->warning(self::class.' could not validate secret, skipping'); continue; } @@ -101,7 +67,7 @@ class MSGraphChangeNotificationHandler implements MessageHandlerInterface $this->calendarSyncer->handleCalendarSync($calendar, $notification, $user); $this->em->flush(); } else { - $this->logger->info(self::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 c8a8f8aeb..9bcd81c67 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarMessage.php @@ -24,15 +24,13 @@ use Chill\MainBundle\Entity\User; class CalendarMessage { - public const CALENDAR_PERSIST = 'CHILL_CALENDAR_CALENDAR_PERSIST'; + final public const CALENDAR_PERSIST = 'CHILL_CALENDAR_CALENDAR_PERSIST'; - public const CALENDAR_UPDATE = 'CHILL_CALENDAR_CALENDAR_UPDATE'; + final public const CALENDAR_UPDATE = 'CHILL_CALENDAR_CALENDAR_UPDATE'; - private string $action; + private readonly int $byUserId; - private int $byUserId; - - private int $calendarId; + private readonly int $calendarId; private array $newInvitesIds = []; @@ -47,12 +45,11 @@ class CalendarMessage public function __construct( Calendar $calendar, - string $action, + private readonly string $action, User $byUser ) { $this->calendarId = $calendar->getId(); $this->byUserId = $byUser->getId(); - $this->action = $action; $this->previousCalendarRangeId = null !== $calendar->previousCalendarRange ? $calendar->previousCalendarRange->getId() : null; $this->previousMainUserId = null !== $calendar->previousMainUser ? diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeMessage.php index 526826ff8..13669a0a2 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeMessage.php @@ -23,19 +23,16 @@ use Chill\MainBundle\Entity\User; class CalendarRangeMessage { - public const CALENDAR_RANGE_PERSIST = 'CHILL_CALENDAR_CALENDAR_RANGE_PERSIST'; + final public const CALENDAR_RANGE_PERSIST = 'CHILL_CALENDAR_CALENDAR_RANGE_PERSIST'; - public const CALENDAR_RANGE_UPDATE = 'CHILL_CALENDAR_CALENDAR_RANGE_UPDATE'; - - private string $action; + final public const CALENDAR_RANGE_UPDATE = 'CHILL_CALENDAR_CALENDAR_RANGE_UPDATE'; private ?int $byUserId = null; - private int $calendarRangeId; + private readonly int $calendarRangeId; - public function __construct(CalendarRange $calendarRange, string $action, ?User $byUser) + public function __construct(CalendarRange $calendarRange, private readonly string $action, ?User $byUser) { - $this->action = $action; $this->calendarRangeId = $calendarRange->getId(); if (null !== $byUser) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeRemovedMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeRemovedMessage.php index 783484592..eb8be6838 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeRemovedMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRangeRemovedMessage.php @@ -25,11 +25,11 @@ class CalendarRangeRemovedMessage { private ?int $byUserId = null; - private int $calendarRangeUserId; + private readonly int $calendarRangeUserId; - private array $remoteAttributes; + private readonly array $remoteAttributes; - private string $remoteId; + private readonly string $remoteId; public function __construct(CalendarRange $calendarRange, ?User $byUser) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php index 65831ebe0..53dcea28c 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php @@ -27,11 +27,11 @@ class CalendarRemovedMessage private ?int $byUserId = null; - private int $calendarUserId; + private readonly int $calendarUserId; - private array $remoteAttributes; + private readonly array $remoteAttributes; - private string $remoteId; + private readonly string $remoteId; public function __construct(Calendar $calendar, ?User $byUser) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/InviteUpdateMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/InviteUpdateMessage.php index 35f78fc7d..d18ab8db1 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/InviteUpdateMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/InviteUpdateMessage.php @@ -23,9 +23,9 @@ use Chill\MainBundle\Entity\User; class InviteUpdateMessage { - private int $byUserId; + private readonly int $byUserId; - private int $inviteId; + private readonly int $inviteId; public function __construct(Invite $invite, User $byUser) { diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/MSGraphChangeNotificationMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/MSGraphChangeNotificationMessage.php index f1d3b6b04..15b8c6733 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/MSGraphChangeNotificationMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/MSGraphChangeNotificationMessage.php @@ -20,15 +20,7 @@ namespace Chill\CalendarBundle\Messenger\Message; class MSGraphChangeNotificationMessage { - private array $content; - - private int $userId; - - public function __construct(array $content, int $userId) - { - $this->content = $content; - $this->userId = $userId; - } + public function __construct(private readonly array $content, private readonly int $userId) {} public function getContent(): array { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/AddressConverter.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/AddressConverter.php index 8b86ba0ec..2535e23ca 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/AddressConverter.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/AddressConverter.php @@ -24,15 +24,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface; class AddressConverter { - private AddressRender $addressRender; - - private TranslatableStringHelperInterface $translatableStringHelper; - - public function __construct(AddressRender $addressRender, TranslatableStringHelperInterface $translatableStringHelper) - { - $this->addressRender = $addressRender; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly AddressRender $addressRender, private readonly TranslatableStringHelperInterface $translatableStringHelper) {} public function addressToRemote(Address $address): array { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php index c400b6694..080140d86 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/EventsOnUserSubscriptionCreator.php @@ -19,8 +19,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; -use LogicException; use Psr\Log\LoggerInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; @@ -30,39 +28,21 @@ use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; */ class EventsOnUserSubscriptionCreator { - private LoggerInterface $logger; - - private MachineHttpClient $machineHttpClient; - - private MapCalendarToUser $mapCalendarToUser; - - private UrlGeneratorInterface $urlGenerator; - - public function __construct( - LoggerInterface $logger, - MachineHttpClient $machineHttpClient, - MapCalendarToUser $mapCalendarToUser, - UrlGeneratorInterface $urlGenerator - ) { - $this->logger = $logger; - $this->machineHttpClient = $machineHttpClient; - $this->mapCalendarToUser = $mapCalendarToUser; - $this->urlGenerator = $urlGenerator; - } + public function __construct(private readonly LoggerInterface $logger, private readonly MachineHttpClient $machineHttpClient, private readonly MapCalendarToUser $mapCalendarToUser, private readonly UrlGeneratorInterface $urlGenerator) {} /** + * @return array{secret: string, id: string, expiration: int} + * * @throws ClientExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface - * - * @return array */ - public function createSubscriptionForUser(User $user, DateTimeImmutable $expiration): array + public function createSubscriptionForUser(User $user, \DateTimeImmutable $expiration): array { if (null === $userId = $this->mapCalendarToUser->getUserId($user)) { - throw new LogicException('no user id'); + throw new \LogicException('no user id'); } $subscription = [ @@ -74,7 +54,7 @@ class EventsOnUserSubscriptionCreator ), 'resource' => "/users/{$userId}/calendar/events", 'clientState' => $secret = base64_encode(openssl_random_pseudo_bytes(92, $cstrong)), - 'expirationDateTime' => $expiration->format(DateTimeImmutable::ATOM), + 'expirationDateTime' => $expiration->format(\DateTimeImmutable::ATOM), ]; try { @@ -97,26 +77,26 @@ class EventsOnUserSubscriptionCreator } /** + * @return array{secret: string, id: string, expiration: int} + * * @throws ClientExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface - * - * @return array */ - public function renewSubscriptionForUser(User $user, DateTimeImmutable $expiration): array + public function renewSubscriptionForUser(User $user, \DateTimeImmutable $expiration): array { if (null === $userId = $this->mapCalendarToUser->getUserId($user)) { - throw new LogicException('no user id'); + throw new \LogicException('no user id'); } if (null === $subscriptionId = $this->mapCalendarToUser->getActiveSubscriptionId($user)) { - throw new LogicException('no user id'); + throw new \LogicException('no user id'); } $subscription = [ - 'expirationDateTime' => $expiration->format(DateTimeImmutable::ATOM), + 'expirationDateTime' => $expiration->format(\DateTimeImmutable::ATOM), ]; try { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/LocationConverter.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/LocationConverter.php index 396dfd931..f14683b9e 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/LocationConverter.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/LocationConverter.php @@ -22,12 +22,7 @@ use Chill\MainBundle\Entity\Location; class LocationConverter { - private AddressConverter $addressConverter; - - public function __construct(AddressConverter $addressConverter) - { - $this->addressConverter = $addressConverter; - } + public function __construct(private readonly AddressConverter $addressConverter) {} public function locationToRemote(Location $location): array { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php index a81ef34c3..37e3e1996 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReader.php @@ -13,7 +13,6 @@ namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use Chill\CalendarBundle\Exception\UserAbsenceSyncException; use Chill\MainBundle\Entity\User; -use Psr\Log\LoggerInterface; use Symfony\Component\Clock\ClockInterface; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; @@ -33,7 +32,7 @@ final readonly class MSUserAbsenceReader implements MSUserAbsenceReaderInterface /** * @throw UserAbsenceSyncException when the data cannot be reached or is not valid from microsoft */ - public function isUserAbsent(User $user): bool|null + public function isUserAbsent(User $user): null|bool { $id = $this->mapCalendarToUser->getUserId($user); @@ -43,25 +42,24 @@ final readonly class MSUserAbsenceReader implements MSUserAbsenceReaderInterface try { $automaticRepliesSettings = $this->machineHttpClient - ->request('GET', 'users/' . $id . '/mailboxSettings/automaticRepliesSetting') + ->request('GET', 'users/'.$id.'/mailboxSettings/automaticRepliesSetting') ->toArray(true); } catch (ClientExceptionInterface|DecodingExceptionInterface|RedirectionExceptionInterface|TransportExceptionInterface $e) { - throw new UserAbsenceSyncException("Error receiving response for mailboxSettings", 0, $e); + throw new UserAbsenceSyncException('Error receiving response for mailboxSettings', 0, $e); } catch (ServerExceptionInterface $e) { - throw new UserAbsenceSyncException("Server error receiving response for mailboxSettings", 0, $e); + throw new UserAbsenceSyncException('Server error receiving response for mailboxSettings', 0, $e); } - if (!array_key_exists("status", $automaticRepliesSettings)) { - throw new \LogicException("no key \"status\" on automatic replies settings: " . json_encode($automaticRepliesSettings, JSON_THROW_ON_ERROR)); + if (!array_key_exists('status', $automaticRepliesSettings)) { + throw new \LogicException('no key "status" on automatic replies settings: '.json_encode($automaticRepliesSettings, JSON_THROW_ON_ERROR)); } return match ($automaticRepliesSettings['status']) { 'disabled' => false, 'alwaysEnabled' => true, - 'scheduled' => - RemoteEventConverter::convertStringDateWithoutTimezone($automaticRepliesSettings['scheduledStartDateTime']['dateTime']) < $this->clock->now() + 'scheduled' => RemoteEventConverter::convertStringDateWithoutTimezone($automaticRepliesSettings['scheduledStartDateTime']['dateTime']) < $this->clock->now() && RemoteEventConverter::convertStringDateWithoutTimezone($automaticRepliesSettings['scheduledEndDateTime']['dateTime']) > $this->clock->now(), - default => throw new UserAbsenceSyncException("this status is not documented by Microsoft") + default => throw new UserAbsenceSyncException('this status is not documented by Microsoft') }; } } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php index a918bb7ea..f67562e27 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderInterface.php @@ -18,5 +18,5 @@ interface MSUserAbsenceReaderInterface /** * @throw UserAbsenceSyncException when the data cannot be reached or is not valid from microsoft */ - public function isUserAbsent(User $user): bool|null; + public function isUserAbsent(User $user): null|bool; } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php index a54fa217f..318580ffc 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSync.php @@ -36,13 +36,13 @@ readonly class MSUserAbsenceSync return; } - $this->logger->info("will change user absence", ['userId' => $user->getId()]); + $this->logger->info('will change user absence', ['userId' => $user->getId()]); if ($absence) { - $this->logger->debug("make user absent", ['userId' => $user->getId()]); + $this->logger->debug('make user absent', ['userId' => $user->getId()]); $user->setAbsenceStart($this->clock->now()); } else { - $this->logger->debug("make user present", ['userId' => $user->getId()]); + $this->logger->debug('make user present', ['userId' => $user->getId()]); $user->setAbsenceStart(null); } } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineHttpClient.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineHttpClient.php index cc1692fb7..ce490ce3f 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineHttpClient.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineHttpClient.php @@ -19,7 +19,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use League\OAuth2\Client\Tool\BearerAuthorizationTrait; -use LogicException; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\ResponseInterface; use Symfony\Contracts\HttpClient\ResponseStreamInterface; @@ -28,22 +27,16 @@ class MachineHttpClient implements HttpClientInterface { use BearerAuthorizationTrait; - private HttpClientInterface $decoratedClient; + private readonly HttpClientInterface $decoratedClient; - private MachineTokenStorage $machineTokenStorage; - - /** - * @param HttpClientInterface $decoratedClient - */ - public function __construct(MachineTokenStorage $machineTokenStorage, ?HttpClientInterface $decoratedClient = null) + public function __construct(private readonly MachineTokenStorage $machineTokenStorage, HttpClientInterface $decoratedClient = null) { $this->decoratedClient = $decoratedClient ?? \Symfony\Component\HttpClient\HttpClient::create(); - $this->machineTokenStorage = $machineTokenStorage; } /** * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface - * @throws LogicException if method is not supported + * @throws \LogicException if method is not supported */ public function request(string $method, string $url, array $options = []): ResponseInterface { @@ -69,13 +62,13 @@ class MachineHttpClient implements HttpClientInterface break; default: - throw new LogicException("Method not supported: {$method}"); + throw new \LogicException("Method not supported: {$method}"); } return $this->decoratedClient->request($method, $url, $options); } - public function stream($responses, ?float $timeout = null): ResponseStreamInterface + public function stream($responses, float $timeout = null): ResponseStreamInterface { return $this->decoratedClient->stream($responses, $timeout); } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineTokenStorage.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineTokenStorage.php index ac62d44ac..f2a0fc096 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineTokenStorage.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MachineTokenStorage.php @@ -29,15 +29,7 @@ class MachineTokenStorage private ?AccessTokenInterface $accessToken = null; - private Azure $azure; - - private ChillRedis $chillRedis; - - public function __construct(Azure $azure, ChillRedis $chillRedis) - { - $this->azure = $azure; - $this->chillRedis = $chillRedis; - } + public function __construct(private readonly Azure $azure, private readonly ChillRedis $chillRedis) {} public function getToken(): AccessTokenInterface { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php index 563bd3a38..4b214e6d0 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/MapCalendarToUser.php @@ -19,46 +19,33 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; 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; /** * Write metadata to user, which allow to find his default calendar. */ class MapCalendarToUser { - public const EXPIRATION_SUBSCRIPTION_EVENT = 'subscription_events_expiration'; + final public const EXPIRATION_SUBSCRIPTION_EVENT = 'subscription_events_expiration'; - public const ID_SUBSCRIPTION_EVENT = 'subscription_events_id'; + final public const ID_SUBSCRIPTION_EVENT = 'subscription_events_id'; - public const METADATA_KEY = 'msgraph'; + final public const METADATA_KEY = 'msgraph'; - public const SECRET_SUBSCRIPTION_EVENT = 'subscription_events_secret'; + final public const SECRET_SUBSCRIPTION_EVENT = 'subscription_events_secret'; - private LoggerInterface $logger; - - private HttpClientInterface $machineHttpClient; - - public function __construct( - HttpClientInterface $machineHttpClient, - LoggerInterface $logger - ) { - $this->machineHttpClient = $machineHttpClient; - $this->logger = $logger; - } + public function __construct(private readonly HttpClientInterface $machineHttpClient, private readonly LoggerInterface $logger) {} public function getActiveSubscriptionId(User $user): string { - if (!array_key_exists(self::METADATA_KEY, $user->getAttributes())) { - throw new LogicException('do not contains msgraph metadata'); + if (!\array_key_exists(self::METADATA_KEY, $user->getAttributes())) { + throw new \LogicException('do not contains msgraph metadata'); } - if (!array_key_exists(self::ID_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { - throw new LogicException('do not contains metadata for subscription id'); + if (!\array_key_exists(self::ID_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { + throw new \LogicException('do not contains metadata for subscription id'); } return $user->getAttributes()[self::METADATA_KEY][self::ID_SUBSCRIPTION_EVENT]; @@ -93,12 +80,12 @@ class MapCalendarToUser public function getSubscriptionSecret(User $user): string { - if (!array_key_exists(self::METADATA_KEY, $user->getAttributes())) { - throw new LogicException('do not contains msgraph metadata'); + if (!\array_key_exists(self::METADATA_KEY, $user->getAttributes())) { + throw new \LogicException('do not contains msgraph metadata'); } - if (!array_key_exists(self::SECRET_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { - throw new LogicException('do not contains secret in msgraph'); + if (!\array_key_exists(self::SECRET_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { + throw new \LogicException('do not contains secret in msgraph'); } return $user->getAttributes()[self::METADATA_KEY][self::SECRET_SUBSCRIPTION_EVENT]; @@ -124,25 +111,25 @@ class MapCalendarToUser public function hasActiveSubscription(User $user): bool { - if (!array_key_exists(self::METADATA_KEY, $user->getAttributes())) { + if (!\array_key_exists(self::METADATA_KEY, $user->getAttributes())) { return false; } - if (!array_key_exists(self::EXPIRATION_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { + if (!\array_key_exists(self::EXPIRATION_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY])) { return false; } return $user->getAttributes()[self::METADATA_KEY][self::EXPIRATION_SUBSCRIPTION_EVENT] - >= (new DateTimeImmutable('now'))->getTimestamp(); + >= (new \DateTimeImmutable('now'))->getTimestamp(); } public function hasSubscriptionSecret(User $user): bool { - if (!array_key_exists(self::METADATA_KEY, $user->getAttributes())) { + if (!\array_key_exists(self::METADATA_KEY, $user->getAttributes())) { return false; } - return array_key_exists(self::SECRET_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY]); + return \array_key_exists(self::SECRET_SUBSCRIPTION_EVENT, $user->getAttributes()[self::METADATA_KEY]); } public function hasUserId(User $user): bool @@ -151,11 +138,11 @@ class MapCalendarToUser return false; } - if (!array_key_exists(self::METADATA_KEY, $user->getAttributes())) { + if (!\array_key_exists(self::METADATA_KEY, $user->getAttributes())) { return false; } - return array_key_exists('id', $user->getAttributes()[self::METADATA_KEY]); + return \array_key_exists('id', $user->getAttributes()[self::METADATA_KEY]); } public function writeMetadata(User $user): User @@ -189,8 +176,8 @@ class MapCalendarToUser public function writeSubscriptionMetadata( User $user, int $expiration, - ?string $id = null, - ?string $secret = null + string $id = null, + string $secret = null ): void { $user->setAttributeByDomain(self::METADATA_KEY, self::EXPIRATION_SUBSCRIPTION_EVENT, $expiration); diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserHttpClient.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserHttpClient.php index 9777bf4c0..d969a56b6 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserHttpClient.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserHttpClient.php @@ -19,7 +19,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; use League\OAuth2\Client\Tool\BearerAuthorizationTrait; -use LogicException; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\ResponseInterface; use Symfony\Contracts\HttpClient\ResponseStreamInterface; @@ -28,17 +27,11 @@ class OnBehalfOfUserHttpClient { use BearerAuthorizationTrait; - private HttpClientInterface $decoratedClient; + private readonly HttpClientInterface $decoratedClient; - private OnBehalfOfUserTokenStorage $tokenStorage; - - /** - * @param HttpClientInterface $decoratedClient - */ - public function __construct(OnBehalfOfUserTokenStorage $tokenStorage, ?HttpClientInterface $decoratedClient = null) + public function __construct(private readonly OnBehalfOfUserTokenStorage $tokenStorage, HttpClientInterface $decoratedClient = null) { $this->decoratedClient = $decoratedClient ?? \Symfony\Component\HttpClient\HttpClient::create(); - $this->tokenStorage = $tokenStorage; } public function request(string $method, string $url, array $options = []): ResponseInterface @@ -64,13 +57,13 @@ class OnBehalfOfUserHttpClient break; default: - throw new LogicException("Method not supported: {$method}"); + throw new \LogicException("Method not supported: {$method}"); } return $this->decoratedClient->request($method, $url, $options); } - public function stream($responses, ?float $timeout = null): ResponseStreamInterface + public function stream($responses, float $timeout = null): ResponseStreamInterface { return $this->decoratedClient->stream($responses, $timeout); } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php index 28f68e0e9..d8fff109b 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/OnBehalfOfUserTokenStorage.php @@ -18,7 +18,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph; -use LogicException; use Symfony\Component\HttpFoundation\Session\SessionInterface; use TheNetworg\OAuth2\Client\Provider\Azure; use TheNetworg\OAuth2\Client\Token\AccessToken; @@ -28,17 +27,9 @@ use TheNetworg\OAuth2\Client\Token\AccessToken; */ class OnBehalfOfUserTokenStorage { - public const MS_GRAPH_ACCESS_TOKEN = 'msgraph_access_token'; + final public const MS_GRAPH_ACCESS_TOKEN = 'msgraph_access_token'; - private Azure $azure; - - private SessionInterface $session; - - public function __construct(Azure $azure, SessionInterface $session) - { - $this->azure = $azure; - $this->session = $session; - } + public function __construct(private readonly Azure $azure, private readonly SessionInterface $session) {} public function getToken(): AccessToken { @@ -46,7 +37,7 @@ class OnBehalfOfUserTokenStorage $token = $this->session->get(self::MS_GRAPH_ACCESS_TOKEN, null); if (null === $token) { - throw new LogicException('unexisting token'); + throw new \LogicException('unexisting token'); } if ($token->hasExpired()) { diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php index 176dbe0b0..94b488ddd 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteEventConverter.php @@ -24,11 +24,7 @@ use Chill\CalendarBundle\Entity\Invite; use Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Templating\Entity\PersonRenderInterface; -use DateTimeImmutable; -use DateTimeZone; use Psr\Log\LoggerInterface; -use RuntimeException; -use Symfony\Component\Templating\EngineInterface; use Symfony\Contracts\Translation\TranslatorInterface; /** @@ -41,44 +37,29 @@ class RemoteEventConverter * valid when the remote string contains also a timezone, like in * lastModifiedDate. */ - public const REMOTE_DATETIMEZONE_FORMAT = 'Y-m-d\\TH:i:s.u?P'; + final public const REMOTE_DATETIMEZONE_FORMAT = 'Y-m-d\\TH:i:s.u?P'; /** * Same as above, but sometimes the date is expressed with only 6 milliseconds. */ - public const REMOTE_DATETIMEZONE_FORMAT_ALT = 'Y-m-d\\TH:i:s.uP'; + final public const REMOTE_DATETIMEZONE_FORMAT_ALT = 'Y-m-d\\TH:i:s.uP'; private const REMOTE_DATE_FORMAT = 'Y-m-d\TH:i:s.u0'; private const REMOTE_DATETIME_WITHOUT_TZ_FORMAT = 'Y-m-d\TH:i:s.u?'; - private DateTimeZone $defaultDateTimeZone; + private readonly \DateTimeZone $defaultDateTimeZone; - private EngineInterface $engine; - - private LocationConverter $locationConverter; - - private LoggerInterface $logger; - - private PersonRenderInterface $personRender; - - private DateTimeZone $remoteDateTimeZone; - - private TranslatorInterface $translator; + private readonly \DateTimeZone $remoteDateTimeZone; public function __construct( - EngineInterface $engine, - LocationConverter $locationConverter, - LoggerInterface $logger, - PersonRenderInterface $personRender, - TranslatorInterface $translator + private readonly \Twig\Environment $engine, + private readonly LocationConverter $locationConverter, + private readonly LoggerInterface $logger, + private readonly PersonRenderInterface $personRender, + private readonly TranslatorInterface $translator ) { - $this->engine = $engine; - $this->locationConverter = $locationConverter; - $this->logger = $logger; - $this->translator = $translator; - $this->personRender = $personRender; - $this->defaultDateTimeZone = (new DateTimeImmutable())->getTimezone(); + $this->defaultDateTimeZone = (new \DateTimeImmutable())->getTimezone(); $this->remoteDateTimeZone = self::getRemoteTimeZone(); } @@ -118,7 +99,7 @@ class RemoteEventConverter { $result = array_merge( [ - 'subject' => '[Chill] ' . + 'subject' => '[Chill] '. implode( ', ', $calendar->getPersons()->map(fn (Person $p) => $this->personRender->renderString($p, []))->toArray() @@ -134,7 +115,7 @@ class RemoteEventConverter 'timeZone' => 'UTC', ], 'allowNewTimeProposals' => false, - 'transactionId' => 'calendar_' . $calendar->getId(), + 'transactionId' => 'calendar_'.$calendar->getId(), 'body' => [ 'contentType' => 'text', 'content' => $this->engine->render( @@ -167,45 +148,45 @@ class RemoteEventConverter public function convertAvailabilityToRemoteEvent(array $event): RemoteEvent { $startDate = - DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['start']['dateTime'], $this->remoteDateTimeZone) + \DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['start']['dateTime'], $this->remoteDateTimeZone) ->setTimezone($this->defaultDateTimeZone); $endDate = - DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['end']['dateTime'], $this->remoteDateTimeZone) + \DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['end']['dateTime'], $this->remoteDateTimeZone) ->setTimezone($this->defaultDateTimeZone); return new RemoteEvent( uniqid('generated_'), - $this->translator->trans('remote_ms_graph.freebusy_statuses.' . $event['status']), + $this->translator->trans('remote_ms_graph.freebusy_statuses.'.$event['status']), '', $startDate, $endDate ); } - public static function convertStringDateWithoutTimezone(string $date): DateTimeImmutable + public static function convertStringDateWithoutTimezone(string $date): \DateTimeImmutable { - $d = DateTimeImmutable::createFromFormat( + $d = \DateTimeImmutable::createFromFormat( self::REMOTE_DATETIME_WITHOUT_TZ_FORMAT, $date, self::getRemoteTimeZone() ); if (false === $d) { - throw new RuntimeException("could not convert string date to datetime: {$date}"); + throw new \RuntimeException("could not convert string date to datetime: {$date}"); } - return $d->setTimezone((new DateTimeImmutable())->getTimezone()); + return $d->setTimezone((new \DateTimeImmutable())->getTimezone()); } - public static function convertStringDateWithTimezone(string $date): DateTimeImmutable + public static function convertStringDateWithTimezone(string $date): \DateTimeImmutable { - $d = DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT, $date); + $d = \DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT, $date); if (false === $d) { - throw new RuntimeException("could not convert string date to datetime: {$date}"); + throw new \RuntimeException("could not convert string date to datetime: {$date}"); } - $d->setTimezone((new DateTimeImmutable())->getTimezone()); + $d->setTimezone((new \DateTimeImmutable())->getTimezone()); return $d; } @@ -213,10 +194,10 @@ class RemoteEventConverter public function convertToRemote(array $event): RemoteEvent { $startDate = - DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['start']['dateTime'], $this->remoteDateTimeZone) + \DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['start']['dateTime'], $this->remoteDateTimeZone) ->setTimezone($this->defaultDateTimeZone); $endDate = - DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['end']['dateTime'], $this->remoteDateTimeZone) + \DateTimeImmutable::createFromFormat(self::REMOTE_DATE_FORMAT, $event['end']['dateTime'], $this->remoteDateTimeZone) ->setTimezone($this->defaultDateTimeZone); return new RemoteEvent( @@ -229,26 +210,22 @@ class RemoteEventConverter ); } - public function getLastModifiedDate(array $event): DateTimeImmutable + public function getLastModifiedDate(array $event): \DateTimeImmutable { - $date = DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT, $event['lastModifiedDateTime']); + $date = \DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT, $event['lastModifiedDateTime']); if (false === $date) { - $date = DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT_ALT, $event['lastModifiedDateTime']); + $date = \DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT_ALT, $event['lastModifiedDateTime']); } if (false === $date) { - $this->logger->error(self::class . ' Could not convert lastModifiedDate', [ + $this->logger->error(self::class.' Could not convert lastModifiedDate', [ 'actual' => $event['lastModifiedDateTime'], 'format' => self::REMOTE_DATETIMEZONE_FORMAT, 'format_alt' => self::REMOTE_DATETIMEZONE_FORMAT_ALT, ]); - throw new RuntimeException(sprintf( - 'could not convert lastModifiedDate: %s, expected format: %s', - $event['lastModifiedDateTime'], - self::REMOTE_DATETIMEZONE_FORMAT . ' and ' . self::REMOTE_DATETIMEZONE_FORMAT_ALT - )); + throw new \RuntimeException(sprintf('could not convert lastModifiedDate: %s, expected format: %s', $event['lastModifiedDateTime'], self::REMOTE_DATETIMEZONE_FORMAT.' and '.self::REMOTE_DATETIMEZONE_FORMAT_ALT)); } return $date; @@ -262,9 +239,9 @@ class RemoteEventConverter return 'Y-m-d\TH:i:s'; } - public static function getRemoteTimeZone(): DateTimeZone + public static function getRemoteTimeZone(): \DateTimeZone { - return new DateTimeZone('UTC'); + return new \DateTimeZone('UTC'); } private function buildInviteToAttendee(Invite $invite): array diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php index d05adfed7..1dffe198c 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarRangeSyncer.php @@ -24,30 +24,15 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter; use Chill\MainBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; -use RuntimeException; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; class CalendarRangeSyncer { - private EntityManagerInterface $em; - - private LoggerInterface $logger; - - private HttpClientInterface $machineHttpClient; - /** * @param MachineHttpClient $machineHttpClient */ - public function __construct( - EntityManagerInterface $em, - LoggerInterface $logger, - HttpClientInterface $machineHttpClient - ) { - $this->em = $em; - $this->logger = $logger; - $this->machineHttpClient = $machineHttpClient; - } + public function __construct(private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly HttpClientInterface $machineHttpClient) {} public function handleCalendarRangeSync(CalendarRange $calendarRange, array $notification, User $user): void { @@ -59,7 +44,7 @@ class CalendarRangeSyncer } $calendarRange->preventEnqueueChanges = true; - $this->logger->info(self::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 +56,7 @@ class CalendarRangeSyncer $notification['resource'] )->toArray(); } catch (ClientExceptionInterface $clientException) { - $this->logger->warning(self::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 +67,7 @@ class CalendarRangeSyncer $lastModified = RemoteEventConverter::convertStringDateWithTimezone($new['lastModifiedDateTime']); if ($calendarRange->getRemoteAttributes()['lastModifiedDateTime'] === $lastModified->getTimestamp()) { - $this->logger->info(self::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'], ]); @@ -104,7 +89,7 @@ class CalendarRangeSyncer break; default: - throw new RuntimeException('This changeType is not suppored: ' . $notification['changeType']); + throw new \RuntimeException('This changeType is not suppored: '.$notification['changeType']); } } } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php index b3febf4d4..9b4daf626 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraph/RemoteToLocalSync/CalendarSyncer.php @@ -23,44 +23,21 @@ use Chill\CalendarBundle\Entity\Invite; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Repository\UserRepositoryInterface; -use LogicException; use Psr\Log\LoggerInterface; -use RuntimeException; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -use function in_array; class CalendarSyncer { - private LoggerInterface $logger; - - private HttpClientInterface $machineHttpClient; - - private UserRepositoryInterface $userRepository; - - public function __construct(LoggerInterface $logger, HttpClientInterface $machineHttpClient, UserRepositoryInterface $userRepository) - { - $this->logger = $logger; - $this->machineHttpClient = $machineHttpClient; - $this->userRepository = $userRepository; - } + public function __construct(private readonly LoggerInterface $logger, private readonly HttpClientInterface $machineHttpClient, private readonly UserRepositoryInterface $userRepository) {} public function handleCalendarSync(Calendar $calendar, array $notification, User $user): void { - switch ($notification['changeType']) { - case 'deleted': - $this->handleDeleteCalendar($calendar, $notification, $user); - - break; - - case 'updated': - $this->handleUpdateCalendar($calendar, $notification, $user); - - break; - - default: - throw new RuntimeException('this change type is not supported: ' . $notification['changeType']); - } + match ($notification['changeType']) { + 'deleted' => $this->handleDeleteCalendar($calendar, $notification, $user), + 'updated' => $this->handleUpdateCalendar($calendar, $notification, $user), + default => throw new \RuntimeException('this change type is not supported: '.$notification['changeType']), + }; } private function handleDeleteCalendar(Calendar $calendar, array $notification, User $user): void @@ -79,7 +56,7 @@ class CalendarSyncer $notification['resource'] )->toArray(); } catch (ClientExceptionInterface $clientException) { - $this->logger->warning(self::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 +73,7 @@ class CalendarSyncer ); if ($calendar->getRemoteAttributes()['lastModifiedDateTime'] === $lastModified->getTimestamp()) { - $this->logger->info(self::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'], ]); @@ -137,7 +114,7 @@ class CalendarSyncer } $email = $attendee['emailAddress']['address']; - $emails[] = strtolower($email); + $emails[] = strtolower((string) $email); $user = $this->userRepository->findOneByUsernameOrEmail($email); if (null === $user) { @@ -150,38 +127,17 @@ class CalendarSyncer $invite = $calendar->getInviteForUser($user); - switch ($status) { - // possible cases: none, organizer, tentativelyAccepted, accepted, declined, notResponded. - case 'none': - case 'notResponded': - $invite->setStatus(Invite::PENDING); - - break; - - case 'tentativelyAccepted': - $invite->setStatus(Invite::TENTATIVELY_ACCEPTED); - - break; - - case 'accepted': - $invite->setStatus(Invite::ACCEPTED); - - break; - - case 'declined': - $invite->setStatus(Invite::DECLINED); - - break; - - default: - throw new LogicException('should not happens, not implemented: ' . $status); - - break; - } + match ($status) { + 'none', 'notResponded' => $invite->setStatus(Invite::PENDING), + 'tentativelyAccepted' => $invite->setStatus(Invite::TENTATIVELY_ACCEPTED), + 'accepted' => $invite->setStatus(Invite::ACCEPTED), + 'declined' => $invite->setStatus(Invite::DECLINED), + default => throw new \LogicException('should not happens, not implemented: '.$status), + }; } foreach ($calendar->getUsers() as $user) { - if (!in_array(strtolower($user->getEmailCanonical()), $emails, true)) { + if (!\in_array(strtolower($user->getEmailCanonical()), $emails, true)) { $calendar->removeUser($user); } } diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php index 0e3beff5f..768ad2a44 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/MSGraphRemoteCalendarConnector.php @@ -28,8 +28,6 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter; use Chill\CalendarBundle\Repository\CalendarRangeRepository; use Chill\CalendarBundle\Repository\CalendarRepository; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; -use Exception; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; @@ -38,62 +36,14 @@ use Symfony\Component\Security\Core\Security; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\Translation\TranslatorInterface; -use function array_key_exists; -use function count; class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface { private array $cacheScheduleTimeForUser = []; - private CalendarRangeRepository $calendarRangeRepository; + public function __construct(private readonly CalendarRepository $calendarRepository, private readonly CalendarRangeRepository $calendarRangeRepository, private readonly HttpClientInterface $machineHttpClient, private readonly MapCalendarToUser $mapCalendarToUser, private readonly LoggerInterface $logger, private readonly OnBehalfOfUserTokenStorage $tokenStorage, private readonly OnBehalfOfUserHttpClient $userHttpClient, private readonly RemoteEventConverter $remoteEventConverter, private readonly TranslatorInterface $translator, private readonly UrlGeneratorInterface $urlGenerator, private readonly Security $security) {} - private CalendarRepository $calendarRepository; - - private LoggerInterface $logger; - - private HttpClientInterface $machineHttpClient; - - private MapCalendarToUser $mapCalendarToUser; - - private RemoteEventConverter $remoteEventConverter; - - private OnBehalfOfUserTokenStorage $tokenStorage; - - private TranslatorInterface $translator; - - private UrlGeneratorInterface $urlGenerator; - - private OnBehalfOfUserHttpClient $userHttpClient; - - private Security $security; - - public function __construct( - CalendarRepository $calendarRepository, - CalendarRangeRepository $calendarRangeRepository, - HttpClientInterface $machineHttpClient, - MapCalendarToUser $mapCalendarToUser, - LoggerInterface $logger, - OnBehalfOfUserTokenStorage $tokenStorage, - OnBehalfOfUserHttpClient $userHttpClient, - RemoteEventConverter $remoteEventConverter, - TranslatorInterface $translator, - UrlGeneratorInterface $urlGenerator, - Security $security - ) { - $this->calendarRepository = $calendarRepository; - $this->calendarRangeRepository = $calendarRangeRepository; - $this->machineHttpClient = $machineHttpClient; - $this->mapCalendarToUser = $mapCalendarToUser; - $this->logger = $logger; - $this->remoteEventConverter = $remoteEventConverter; - $this->tokenStorage = $tokenStorage; - $this->translator = $translator; - $this->urlGenerator = $urlGenerator; - $this->userHttpClient = $userHttpClient; - $this->security = $security; - } - - public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int + public function countEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): int { $userId = $this->mapCalendarToUser->getUserId($user); @@ -104,7 +54,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $data = $this->userHttpClient->request( 'GET', - 'users/' . $userId . '/calendarView', + 'users/'.$userId.'/calendarView', [ 'query' => [ 'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), @@ -116,7 +66,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface )->toArray(); } catch (ClientExceptionInterface $e) { if (403 === $e->getResponse()->getStatusCode()) { - return count($this->getScheduleTimesForUser($user, $startDate, $endDate)); + return \count($this->getScheduleTimesForUser($user, $startDate, $endDate)); } $this->logger->error('Could not get list of event on MSGraph', [ @@ -153,6 +103,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $this->logger->debug('mark user ready for msgraph calendar as he does not have any mapping', [ 'userId' => $user->getId(), ]); + return true; } @@ -160,14 +111,14 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface } /** + * @return array|\Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent[] + * * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface - * - * @return array|\Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent[] */ - public function listEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array + public function listEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array { $userId = $this->mapCalendarToUser->getUserId($user); @@ -178,7 +129,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $bareEvents = $this->userHttpClient->request( 'GET', - 'users/' . $userId . '/calendarView', + 'users/'.$userId.'/calendarView', [ 'query' => [ 'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), @@ -218,7 +169,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface } } - public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, ?CalendarRange $associatedCalendarRange = null): void + public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, CalendarRange $associatedCalendarRange = null): void { if ('' === $remoteId) { return; @@ -268,7 +219,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $calendar->getRemoteId(), $this->translator->trans('remote_ms_graph.cancel_event_because_main_user_is_%label%', ['%label%' => $calendar->getMainUser()]), $previousMainUser, - 'calendar_' . $calendar->getRemoteId() + 'calendar_'.$calendar->getRemoteId() ); $this->createCalendarOnRemote($calendar); } else { @@ -346,7 +297,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface break; default: - throw new Exception('not supported'); + throw new \Exception('not supported'); } try { @@ -359,7 +310,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $this->logger->warning('could not update calendar range to remote', [ 'exception' => $e->getTraceAsString(), 'content' => $e->getResponse()->getContent(), - 'calendarRangeId' => 'invite_' . $invite->getId(), + 'calendarRangeId' => 'invite_'.$invite->getId(), ]); throw $e; @@ -401,7 +352,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface 'id' => $id, 'lastModifiedDateTime' => $lastModified, 'changeKey' => $changeKey - ] = $this->createOnRemote($eventData, $calendar->getMainUser(), 'calendar_' . $calendar->getId()); + ] = $this->createOnRemote($eventData, $calendar->getMainUser(), 'calendar_'.$calendar->getId()); if (null === $id) { return; @@ -436,7 +387,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $event = $this->machineHttpClient->request( 'POST', - 'users/' . $userId . '/calendar/events', + 'users/'.$userId.'/calendar/events', [ 'json' => $eventData, ] @@ -480,7 +431,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface ] = $this->createOnRemote( $eventData, $calendarRange->getUser(), - 'calendar_range_' . $calendarRange->getId() + 'calendar_range_'.$calendarRange->getId() ); $calendarRange->setRemoteId($id) @@ -503,7 +454,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $userId = $this->mapCalendarToUser->getUserId($user); if ('' === $iCalUid = ($event['iCalUId'] ?? '')) { - throw new Exception('no iCalUid for this event'); + throw new \Exception('no iCalUid for this event'); } try { @@ -521,8 +472,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface throw $clientException; } - if (1 !== count($events['value'])) { - throw new Exception('multiple events found with same iCalUid'); + if (1 !== \count($events['value'])) { + throw new \Exception('multiple events found with same iCalUid'); } return $events['value'][0]['id']; @@ -533,19 +484,13 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $userId = $this->mapCalendarToUser->getUserId($user); if (null === $userId) { - throw new Exception( - sprintf( - 'no remote calendar for this user: %s, remoteid: %s', - $user->getId(), - $remoteId - ) - ); + throw new \Exception(sprintf('no remote calendar for this user: %s, remoteid: %s', $user->getId(), $remoteId)); } try { return $this->machineHttpClient->request( 'GET', - 'users/' . $userId . '/calendar/events/' . $remoteId + 'users/'.$userId.'/calendar/events/'.$remoteId )->toArray(); } catch (ClientExceptionInterface $e) { $this->logger->warning('Could not get event from calendar', [ @@ -556,11 +501,11 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface } } - private function getScheduleTimesForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): array + private function getScheduleTimesForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): array { $userId = $this->mapCalendarToUser->getUserId($user); - if (array_key_exists($userId, $this->cacheScheduleTimeForUser)) { + if (\array_key_exists($userId, $this->cacheScheduleTimeForUser)) { return $this->cacheScheduleTimeForUser[$userId]; } @@ -575,17 +520,17 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $body = [ 'schedules' => [$user->getEmailCanonical()], 'startTime' => [ - 'dateTime' => ($startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat())), + 'dateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), 'timeZone' => 'UTC', ], 'endTime' => [ - 'dateTime' => ($endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat())), + 'dateTime' => $endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), 'timeZone' => 'UTC', ], ]; try { - $response = $this->userHttpClient->request('POST', 'users/' . $userId . '/calendar/getSchedule', [ + $response = $this->userHttpClient->request('POST', 'users/'.$userId.'/calendar/getSchedule', [ 'json' => $body, ])->toArray(); } catch (ClientExceptionInterface $e) { @@ -610,7 +555,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $eventDatas = []; $eventDatas[] = $this->remoteEventConverter->calendarToEvent($calendar); - if (0 < count($newInvites)) { + if (0 < \count($newInvites)) { // it seems that invitaiton are always send, even if attendee changes are mixed with other datas // $eventDatas[] = $this->remoteEventConverter->calendarToEventAttendeesOnly($calendar); } @@ -624,7 +569,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface $calendar->getRemoteId(), $eventData, $calendar->getMainUser(), - 'calendar_' . $calendar->getId() + 'calendar_'.$calendar->getId() ); $calendar->addRemoteAttributes([ @@ -655,7 +600,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $event = $this->machineHttpClient->request( 'PATCH', - 'users/' . $userId . '/calendar/events/' . $remoteId, + 'users/'.$userId.'/calendar/events/'.$remoteId, [ 'json' => $eventData, ] @@ -683,9 +628,9 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $this->machineHttpClient->request( 'DELETE', - 'users/' . $userId . '/calendar/events/' . $remoteId + 'users/'.$userId.'/calendar/events/'.$remoteId ); - } catch (ClientExceptionInterface $e) { + } catch (ClientExceptionInterface) { $this->logger->warning('could not remove event from calendar', [ 'event_remote_id' => $remoteId, 'user_id' => $user->getId(), @@ -710,7 +655,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $event = $this->machineHttpClient->request( 'GET', - 'users/' . $userId . '/calendar/events/' . $calendarRange->getRemoteId() + 'users/'.$userId.'/calendar/events/'.$calendarRange->getRemoteId() )->toArray(); } catch (ClientExceptionInterface $e) { $this->logger->warning('Could not get event from calendar', [ @@ -737,7 +682,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface try { $event = $this->machineHttpClient->request( 'PATCH', - 'users/' . $userId . '/calendar/events/' . $calendarRange->getRemoteId(), + 'users/'.$userId.'/calendar/events/'.$calendarRange->getRemoteId(), [ 'json' => $eventData, ] diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/NullRemoteCalendarConnector.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/NullRemoteCalendarConnector.php index c8fb569e8..b4e2a5d3a 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/NullRemoteCalendarConnector.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/NullRemoteCalendarConnector.php @@ -22,20 +22,18 @@ use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\Entity\Invite; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; -use LogicException; use Symfony\Component\HttpFoundation\Response; class NullRemoteCalendarConnector implements RemoteCalendarConnectorInterface { - public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int + public function countEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): int { return 0; } public function getMakeReadyResponse(string $returnPath): Response { - throw new LogicException('As this connector is always ready, this method should not be called'); + throw new \LogicException('As this connector is always ready, this method should not be called'); } public function isReady(): bool @@ -43,12 +41,12 @@ class NullRemoteCalendarConnector implements RemoteCalendarConnectorInterface return true; } - public function listEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array + public function listEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array { return []; } - public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, ?CalendarRange $associatedCalendarRange = null): void {} + public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, CalendarRange $associatedCalendarRange = null): void {} public function removeCalendarRange(string $remoteId, array $remoteAttributes, User $user): void {} diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/RemoteCalendarConnectorInterface.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/RemoteCalendarConnectorInterface.php index e3ef89ca4..53d2c8602 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/RemoteCalendarConnectorInterface.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Connector/RemoteCalendarConnectorInterface.php @@ -23,12 +23,11 @@ use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\Entity\Invite; use Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; use Symfony\Component\HttpFoundation\Response; interface RemoteCalendarConnectorInterface { - public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int; + public function countEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate): int; /** * Return a response, more probably a RedirectResponse, where the user @@ -46,9 +45,9 @@ interface RemoteCalendarConnectorInterface /** * @return array|RemoteEvent[] */ - public function listEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array; + public function listEventsForUser(User $user, \DateTimeImmutable $startDate, \DateTimeImmutable $endDate, ?int $offset = 0, ?int $limit = 50): array; - public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, ?CalendarRange $associatedCalendarRange = null): void; + public function removeCalendar(string $remoteId, array $remoteAttributes, User $user, CalendarRange $associatedCalendarRange = null): void; public function removeCalendarRange(string $remoteId, array $remoteAttributes, User $user): void; diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php index 6a986c9db..c52fc2866 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/DependencyInjection/RemoteCalendarCompilerPass.php @@ -28,7 +28,6 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraphRemoteCalendarConnector; use Chill\CalendarBundle\RemoteCalendar\Connector\NullRemoteCalendarConnector; use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface; -use RuntimeException; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -43,7 +42,7 @@ class RemoteCalendarCompilerPass implements CompilerPassInterface if (true === $config['remote_calendars_sync']['microsoft_graph']['enabled']) { $connector = MSGraphRemoteCalendarConnector::class; - $container->setAlias(HttpClientInterface::class . ' $machineHttpClient', MachineHttpClient::class); + $container->setAlias(HttpClientInterface::class.' $machineHttpClient', MachineHttpClient::class); } else { $connector = NullRemoteCalendarConnector::class; // remove services which cannot be loaded diff --git a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Model/RemoteEvent.php b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Model/RemoteEvent.php index 13c4a1c6a..40d1d1435 100644 --- a/src/Bundle/ChillCalendarBundle/RemoteCalendar/Model/RemoteEvent.php +++ b/src/Bundle/ChillCalendarBundle/RemoteCalendar/Model/RemoteEvent.php @@ -18,45 +18,31 @@ declare(strict_types=1); namespace Chill\CalendarBundle\RemoteCalendar\Model; -use DateTimeImmutable; use Symfony\Component\Serializer\Annotation as Serializer; class RemoteEvent { - public string $description; - - /** - * @Serializer\Groups({"read"}) - */ - public DateTimeImmutable $endDate; - - /** - * @Serializer\Groups({"read"}) - */ - public string $id; - - /** - * @Serializer\Groups({"read"}) - */ - public bool $isAllDay; - - /** - * @Serializer\Groups({"read"}) - */ - public DateTimeImmutable $startDate; - - /** - * @Serializer\Groups({"read"}) - */ - public string $title; - - public function __construct(string $id, string $title, string $description, DateTimeImmutable $startDate, DateTimeImmutable $endDate, bool $isAllDay = false) - { - $this->id = $id; - $this->title = $title; - $this->description = $description; - $this->startDate = $startDate; - $this->endDate = $endDate; - $this->isAllDay = $isAllDay; - } + public function __construct( + /** + * @Serializer\Groups({"read"}) + */ + public string $id, + /** + * @Serializer\Groups({"read"}) + */ + public string $title, + public string $description, + /** + * @Serializer\Groups({"read"}) + */ + public \DateTimeImmutable $startDate, + /** + * @Serializer\Groups({"read"}) + */ + public \DateTimeImmutable $endDate, + /** + * @Serializer\Groups({"read"}) + */ + public bool $isAllDay = false + ) {} } diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php index 7c6ef4e13..8f490f376 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepository.php @@ -23,25 +23,14 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface { - private AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository; + public function __construct(private readonly AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, private readonly EntityManagerInterface $em) {} - private EntityManagerInterface $em; - - public function __construct( - AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, - EntityManagerInterface $em - ) { - $this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; - $this->em = $em; - } - - public function buildQueryByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): QueryBuilder + public function buildQueryByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder { $qb = $this->em->createQueryBuilder(); $qb->from(Calendar::class, 'c'); @@ -64,7 +53,7 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface return $qb; } - public function buildQueryByAccompanyingPeriodIgnoredByDates(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): QueryBuilder + public function buildQueryByAccompanyingPeriodIgnoredByDates(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder { $qb = $this->em->createQueryBuilder(); $qb->from(Calendar::class, 'c'); @@ -90,7 +79,7 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface /** * Base implementation. The list of allowed accompanying period is retrieved "manually" from @see{AccompanyingPeriodACLAwareRepository}. */ - public function buildQueryByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): QueryBuilder + public function buildQueryByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder { $qb = $this->em->createQueryBuilder() ->from(Calendar::class, 'c'); @@ -114,7 +103,7 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface /** * Base implementation. The list of allowed accompanying period is retrieved "manually" from @see{AccompanyingPeriodACLAwareRepository}. */ - public function buildQueryByPersonIgnoredByDates(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): QueryBuilder + public function buildQueryByPersonIgnoredByDates(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): QueryBuilder { $qb = $this->em->createQueryBuilder() ->from(Calendar::class, 'c'); @@ -135,14 +124,14 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface return $qb; } - public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int + public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int { $qb = $this->buildQueryByAccompanyingPeriod($period, $startDate, $endDate)->select('count(c)'); return $qb->getQuery()->getSingleScalarResult(); } - public function countByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int + public function countByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int { return $this->buildQueryByPerson($person, $startDate, $endDate) ->select('COUNT(c)') @@ -150,14 +139,14 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface ->getSingleScalarResult(); } - public function countIgnoredByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int + public function countIgnoredByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int { $qb = $this->buildQueryByAccompanyingPeriodIgnoredByDates($period, $startDate, $endDate)->select('count(c)'); return $qb->getQuery()->getSingleScalarResult(); } - public function countIgnoredByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int + public function countIgnoredByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int { return $this->buildQueryByPersonIgnoredByDates($person, $startDate, $endDate) ->select('COUNT(c)') @@ -168,12 +157,12 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface /** * @return array|Calendar[] */ - public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array + public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], int $offset = null, int $limit = null): array { $qb = $this->buildQueryByAccompanyingPeriod($period, $startDate, $endDate)->select('c'); foreach ($orderBy as $sort => $order) { - $qb->addOrderBy('c.' . $sort, $order); + $qb->addOrderBy('c.'.$sort, $order); } if (null !== $offset) { @@ -187,13 +176,13 @@ class CalendarACLAwareRepository implements CalendarACLAwareRepositoryInterface return $qb->getQuery()->getResult(); } - public function findByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array + public function findByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], int $offset = null, int $limit = null): array { $qb = $this->buildQueryByPerson($person, $startDate, $endDate) ->select('c'); foreach ($orderBy as $sort => $order) { - $qb->addOrderBy('c.' . $sort, $order); + $qb->addOrderBy('c.'.$sort, $order); } if (null !== $offset) { diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepositoryInterface.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepositoryInterface.php index 70fb02590..f6d1b5c17 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarACLAwareRepositoryInterface.php @@ -21,33 +21,32 @@ namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\Calendar; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; interface CalendarACLAwareRepositoryInterface { - public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int; + public function countByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int; /** * Return the number or calendars associated with a person. See condition on @see{self::findByPerson}. */ - public function countByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int; + public function countByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int; /** * Return the number or calendars associated with an accompanyign period which **does not** match the date conditions. */ - public function countIgnoredByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int; + public function countIgnoredByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int; /** * Return the number or calendars associated with a person which **does not** match the date conditions. * * See condition on @see{self::findByPerson}. */ - public function countIgnoredByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate): int; + public function countIgnoredByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate): int; /** * @return array|Calendar[] */ - public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array; + public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], int $offset = null, int $limit = null): array; /** * Return all the calendars which are associated with a person, either on @see{Calendar::person} or within. @@ -59,5 +58,5 @@ interface CalendarACLAwareRepositoryInterface * * @return array|Calendar[] */ - public function findByPerson(Person $person, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?array $orderBy = [], ?int $offset = null, ?int $limit = null): array; + public function findByPerson(Person $person, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?array $orderBy = [], int $offset = null, int $limit = null): array; } diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php index bd1074b5f..fb71717d0 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepository.php @@ -18,7 +18,7 @@ use Doctrine\Persistence\ObjectRepository; class CalendarDocRepository implements ObjectRepository, CalendarDocRepositoryInterface { - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -35,7 +35,7 @@ class CalendarDocRepository implements ObjectRepository, CalendarDocRepositoryIn return $this->repository->findAll(); } - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null) + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null) { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepositoryInterface.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepositoryInterface.php index d2b1951df..6d86fd943 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepositoryInterface.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarDocRepositoryInterface.php @@ -25,7 +25,7 @@ interface CalendarDocRepositoryInterface /** * @return array|CalendarDoc[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null); + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null); public function findOneBy(array $criteria): ?CalendarDoc; diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRangeRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRangeRepository.php index dc3405b7e..a707ccde9 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRangeRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRangeRepository.php @@ -13,28 +13,23 @@ namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\CalendarRange; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\ResultSetMapping; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; -use function count; class CalendarRangeRepository implements ObjectRepository { - private EntityManagerInterface $em; + private readonly EntityRepository $repository; - private EntityRepository $repository; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private readonly EntityManagerInterface $em) { - $this->em = $entityManager; - $this->repository = $entityManager->getRepository(CalendarRange::class); + $this->repository = $em->getRepository(CalendarRange::class); } - public function countByAvailableRangesForUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): int + public function countByAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): int { return $this->buildQueryAvailableRangesForUser($user, $from, $to) ->select('COUNT(cr)') @@ -57,7 +52,7 @@ class CalendarRangeRepository implements ObjectRepository /** * @return array|CalendarRange[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null) + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null) { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } @@ -67,10 +62,10 @@ class CalendarRangeRepository implements ObjectRepository */ public function findByAvailableRangesForUser( User $user, - DateTimeImmutable $from, - DateTimeImmutable $to, - ?int $limit = null, - ?int $offset = null + \DateTimeImmutable $from, + \DateTimeImmutable $to, + int $limit = null, + int $offset = null ): array { $qb = $this->buildQueryAvailableRangesForUser($user, $from, $to); @@ -101,7 +96,7 @@ class CalendarRangeRepository implements ObjectRepository */ public function findRemoteIdsPresent(array $remoteIds): array { - if (0 === count($remoteIds)) { + if (0 === \count($remoteIds)) { return []; } @@ -116,7 +111,7 @@ class CalendarRangeRepository implements ObjectRepository $remoteIdsStr = implode( ', ', - array_fill(0, count($remoteIds), '((?))') + array_fill(0, \count($remoteIds), '((?))') ); $rsm = new ResultSetMapping(); @@ -146,7 +141,7 @@ class CalendarRangeRepository implements ObjectRepository return CalendarRange::class; } - private function buildQueryAvailableRangesForUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): QueryBuilder + private function buildQueryAvailableRangesForUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): QueryBuilder { $qb = $this->repository->createQueryBuilder('cr'); diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php index 4fd9b8a29..486493b21 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php @@ -14,20 +14,18 @@ namespace Chill\CalendarBundle\Repository; use Chill\CalendarBundle\Entity\Calendar; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\ResultSetMapping; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectRepository; -use function count; class CalendarRepository implements ObjectRepository { - private EntityManagerInterface $em; + private readonly EntityManagerInterface $em; - private EntityRepository $repository; + private readonly EntityRepository $repository; public function __construct(EntityManagerInterface $entityManager) { @@ -40,7 +38,7 @@ class CalendarRepository implements ObjectRepository return $this->repository->count(['accompanyingPeriod' => $period]); } - public function countByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): int + public function countByUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): int { return $this->buildQueryByUser($user, $from, $to) ->select('COUNT(c)') @@ -48,7 +46,7 @@ class CalendarRepository implements ObjectRepository ->getSingleScalarResult(); } - public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder + public function createQueryBuilder(string $alias, string $indexBy = null): QueryBuilder { return $this->repository->createQueryBuilder($alias, $indexBy); } @@ -69,7 +67,7 @@ class CalendarRepository implements ObjectRepository /** * @return array|Calendar[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } @@ -77,7 +75,7 @@ class CalendarRepository implements ObjectRepository /** * @return array|Calendar[] */ - public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array + public function findByAccompanyingPeriod(AccompanyingPeriod $period, array $orderBy = null, int $limit = null, int $offset = null): array { return $this->findBy( [ @@ -89,7 +87,7 @@ class CalendarRepository implements ObjectRepository ); } - public function findByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate, ?int $limit = null, ?int $offset = null): array + public function findByNotificationAvailable(\DateTimeImmutable $startDate, \DateTimeImmutable $endDate, int $limit = null, int $offset = null): array { $qb = $this->queryByNotificationAvailable($startDate, $endDate)->select('c'); @@ -107,7 +105,7 @@ class CalendarRepository implements ObjectRepository /** * @return array|Calendar[] */ - public function findByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to, ?int $limit = null, ?int $offset = null): array + public function findByUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to, int $limit = null, int $offset = null): array { $qb = $this->buildQueryByUser($user, $from, $to)->select('c'); @@ -138,13 +136,13 @@ class CalendarRepository implements ObjectRepository */ public function findRemoteIdsPresent(array $remoteIds): array { - if (0 === count($remoteIds)) { + if (0 === \count($remoteIds)) { return []; } $remoteIdsStr = implode( ', ', - array_fill(0, count($remoteIds), '((?))') + array_fill(0, \count($remoteIds), '((?))') ); $sql = "SELECT @@ -183,7 +181,7 @@ class CalendarRepository implements ObjectRepository return Calendar::class; } - private function buildQueryByUser(User $user, DateTimeImmutable $from, DateTimeImmutable $to): QueryBuilder + private function buildQueryByUser(User $user, \DateTimeImmutable $from, \DateTimeImmutable $to): QueryBuilder { $qb = $this->repository->createQueryBuilder('c'); @@ -202,7 +200,7 @@ class CalendarRepository implements ObjectRepository ]); } - private function queryByNotificationAvailable(DateTimeImmutable $startDate, DateTimeImmutable $endDate): QueryBuilder + private function queryByNotificationAvailable(\DateTimeImmutable $startDate, \DateTimeImmutable $endDate): QueryBuilder { $qb = $this->repository->createQueryBuilder('c'); diff --git a/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php b/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php index f0bd8fe88..c6f163aa3 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php @@ -18,7 +18,7 @@ use Doctrine\Persistence\ObjectRepository; class InviteRepository implements ObjectRepository { - private EntityRepository $entityRepository; + private readonly EntityRepository $entityRepository; public function __construct(EntityManagerInterface $em) { @@ -41,7 +41,7 @@ class InviteRepository implements ObjectRepository /** * @return array|Invite[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null) + public function findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null) { return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillCalendarBundle/Resources/config/services/fixtures.yml b/src/Bundle/ChillCalendarBundle/Resources/config/services/fixtures.yml index 2bef0bdc4..c57011511 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/config/services/fixtures.yml +++ b/src/Bundle/ChillCalendarBundle/Resources/config/services/fixtures.yml @@ -1,13 +1,10 @@ --- services: - Chill\CalendarBundle\DataFixtures\ORM\LoadCancelReason: - tags: - - { 'name': doctrine.fixture.orm } - Chill\CalendarBundle\DataFixtures\ORM\LoadInvite: - tags: - - { 'name': doctrine.fixture.orm } - Chill\CalendarBundle\DataFixtures\ORM\LoadCalendarRange: - autowire: true - autoconfigure: true - tags: - - { 'name': doctrine.fixture.orm } \ No newline at end of file + _defaults: + autowire: true + autoconfigure: true + + Chill\CalendarBundle\DataFixtures\ORM\: + resource: './../../../DataFixtures/ORM' + tags: + - { 'name': doctrine.fixture.orm } diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig index 2c3cde01a..9e87af8ef 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig @@ -69,7 +69,7 @@ or calendar.users|length > 0 %}
      - {% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with { + {% include '@ChillActivity/Activity/concernedGroups.html.twig' with { 'context': calendar.context == 'person' ? 'calendar_person' : 'calendar_accompanyingCourse', 'render': 'wrap-list', 'entity': calendar diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByAccompanyingCourse.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByAccompanyingCourse.html.twig index a167d5c18..728509909 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByAccompanyingCourse.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByAccompanyingCourse.html.twig @@ -7,7 +7,7 @@ {% block content %}
      - {% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillCalendar/Calendar/edit.html.twig' with {'context': 'accompanyingCourse'} %}
      {% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByPerson.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByPerson.html.twig index fc5319849..47d29d9bd 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByPerson.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByPerson.html.twig @@ -7,7 +7,7 @@ {% block content %}
      - {% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'person'} %} + {% include '@ChillCalendar/Calendar/edit.html.twig' with {'context': 'person'} %}
      {% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByUser.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByUser.html.twig index 0e2170c20..3b3a92847 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByUser.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/editByUser.html.twig @@ -6,7 +6,7 @@
      {# <=== vue component #} - {% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'user'} %} + {% include '@ChillCalendar/Calendar/edit.html.twig' with {'context': 'user'} %}
      {% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByAccompanyingCourse.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByAccompanyingCourse.html.twig index 43fe6cb04..4c206c706 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByAccompanyingCourse.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByAccompanyingCourse.html.twig @@ -8,7 +8,7 @@
      {# <=== vue component #} - {% include 'ChillCalendarBundle:Calendar:new.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillCalendar/Calendar/new.html.twig' with {'context': 'accompanyingCourse'} %}
      {% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByPerson.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByPerson.html.twig index b561e6aa7..a8d851656 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByPerson.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/newByPerson.html.twig @@ -8,7 +8,7 @@
      {# <=== vue component #} - {% include 'ChillCalendarBundle:Calendar:new.html.twig' with {'context': 'person'} %} + {% include '@ChillCalendar/Calendar/new.html.twig' with {'context': 'person'} %}
      {% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig index d48844f67..df1cbb2df 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig @@ -15,7 +15,7 @@

      {{ 'Concerned groups calendar'|trans }}

      -{% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with {'context': 'calendar_' ~ context, 'render': 'bloc' } %} +{% include '@ChillActivity/Activity/concernedGroups.html.twig' with {'context': 'calendar_' ~ context, 'render': 'bloc' } %}

      {{ 'Calendar data'|trans }}

      diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByAccompanyingCourse.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByAccompanyingCourse.html.twig index fa0dd01af..b056ba998 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByAccompanyingCourse.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByAccompanyingCourse.html.twig @@ -7,7 +7,7 @@ {% block content -%}
      - {% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'accompanyingCourse'} %} + {% include '@ChillCalendar/Calendar/show.html.twig' with {'context': 'accompanyingCourse'} %}
      {% endblock content %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByUser.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByUser.html.twig index b8e172030..536ccc03a 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByUser.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/showByUser.html.twig @@ -5,7 +5,7 @@ {% block content -%}
      - {% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'user'} %} + {% include '@ChillCalendar/Calendar/show.html.twig' with {'context': 'user'} %}
      {% endblock content %} diff --git a/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarDocVoter.php b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarDocVoter.php index 452286e85..a0e653cb1 100644 --- a/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarDocVoter.php +++ b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarDocVoter.php @@ -15,47 +15,34 @@ use Chill\CalendarBundle\Entity\CalendarDoc; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Security; -use UnexpectedValueException; -use function in_array; class CalendarDocVoter extends Voter { - public const EDIT = 'CHILL_CALENDAR_DOC_EDIT'; + final public const EDIT = 'CHILL_CALENDAR_DOC_EDIT'; - public const SEE = 'CHILL_CALENDAR_DOC_SEE'; + final public const SEE = 'CHILL_CALENDAR_DOC_SEE'; private const ALL = [ 'CHILL_CALENDAR_DOC_EDIT', 'CHILL_CALENDAR_DOC_SEE', ]; - private Security $security; - - public function __construct(Security $security) - { - $this->security = $security; - } + public function __construct(private readonly Security $security) {} protected function supports($attribute, $subject): bool { - return in_array($attribute, self::ALL, true) && $subject instanceof CalendarDoc; + return \in_array($attribute, self::ALL, true) && $subject instanceof CalendarDoc; } /** * @param CalendarDoc $subject - * @param mixed $attribute */ protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool { - switch ($attribute) { - case self::EDIT: - return $this->security->isGranted(CalendarVoter::EDIT, $subject->getCalendar()); - - case self::SEE: - return $this->security->isGranted(CalendarVoter::SEE, $subject->getCalendar()); - - default: - throw new UnexpectedValueException('Attribute not supported: ' . $attribute); - } + return match ($attribute) { + self::EDIT => $this->security->isGranted(CalendarVoter::EDIT, $subject->getCalendar()), + self::SEE => $this->security->isGranted(CalendarVoter::SEE, $subject->getCalendar()), + default => throw new \UnexpectedValueException('Attribute not supported: '.$attribute), + }; } } diff --git a/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php index 0e2be1d0f..8f4c3a065 100644 --- a/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php +++ b/src/Bundle/ChillCalendarBundle/Security/Voter/CalendarVoter.php @@ -20,41 +20,31 @@ namespace Chill\CalendarBundle\Security\Voter; use Chill\CalendarBundle\Entity\Calendar; use Chill\MainBundle\Security\Authorization\AbstractChillVoter; -use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface; use Chill\MainBundle\Security\Authorization\VoterHelperInterface; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; -use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use LogicException; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security; class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const CREATE = 'CHILL_CALENDAR_CALENDAR_CREATE'; + final public const CREATE = 'CHILL_CALENDAR_CALENDAR_CREATE'; - public const DELETE = 'CHILL_CALENDAR_CALENDAR_DELETE'; + final public const DELETE = 'CHILL_CALENDAR_CALENDAR_DELETE'; - public const EDIT = 'CHILL_CALENDAR_CALENDAR_EDIT'; + final public const EDIT = 'CHILL_CALENDAR_CALENDAR_EDIT'; - public const SEE = 'CHILL_CALENDAR_CALENDAR_SEE'; + final public const SEE = 'CHILL_CALENDAR_CALENDAR_SEE'; - private AuthorizationHelperInterface $authorizationHelper; - - private CenterResolverManagerInterface $centerResolverManager; - - private Security $security; - - private VoterHelperInterface $voterHelper; + private readonly VoterHelperInterface $voterHelper; public function __construct( - Security $security, - VoterHelperFactoryInterface $voterHelperFactory + private readonly Security $security, + VoterHelperFactoryInterface $voterHelperFactory, ) { - $this->security = $security; $this->voterHelper = $voterHelperFactory ->generate(self::class) ->addCheckFor(AccompanyingPeriod::class, [self::SEE, self::CREATE]) @@ -99,7 +89,7 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn switch ($attribute) { case self::SEE: case self::CREATE: - if ($subject->getStep() === AccompanyingPeriod::STEP_DRAFT) { + if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) { return false; } @@ -129,6 +119,6 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn } } - throw new LogicException('attribute or not implemented'); + throw new \LogicException('attribute or not implemented'); } } diff --git a/src/Bundle/ChillCalendarBundle/Security/Voter/InviteVoter.php b/src/Bundle/ChillCalendarBundle/Security/Voter/InviteVoter.php index 36ca66d05..72aa806e6 100644 --- a/src/Bundle/ChillCalendarBundle/Security/Voter/InviteVoter.php +++ b/src/Bundle/ChillCalendarBundle/Security/Voter/InviteVoter.php @@ -24,7 +24,7 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter; class InviteVoter extends Voter { - public const ANSWER = 'CHILL_CALENDAR_INVITE_ANSWER'; + final public const ANSWER = 'CHILL_CALENDAR_INVITE_ANSWER'; protected function supports($attribute, $subject): bool { diff --git a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php index cabb7dcce..087f5ea86 100644 --- a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php +++ b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContext.php @@ -29,45 +29,19 @@ use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -use function count; -final class CalendarContext implements CalendarContextInterface +final readonly class CalendarContext implements CalendarContextInterface { - private BaseContextData $baseContextData; - - private EntityManagerInterface $entityManager; - - private NormalizerInterface $normalizer; - - private PersonRender $personRender; - - private PersonRepository $personRepository; - - private ThirdPartyRepository $thirdPartyRepository; - - private ThirdPartyRender $thirdPartyRender; - - private TranslatableStringHelperInterface $translatableStringHelper; - public function __construct( - BaseContextData $baseContextData, - EntityManagerInterface $entityManager, - NormalizerInterface $normalizer, - PersonRender $personRender, - PersonRepository $personRepository, - ThirdPartyRender $thirdPartyRender, - ThirdPartyRepository $thirdPartyRepository, - TranslatableStringHelperInterface $translatableStringHelper - ) { - $this->baseContextData = $baseContextData; - $this->entityManager = $entityManager; - $this->normalizer = $normalizer; - $this->personRender = $personRender; - $this->personRepository = $personRepository; - $this->thirdPartyRender = $thirdPartyRender; - $this->thirdPartyRepository = $thirdPartyRepository; - $this->translatableStringHelper = $translatableStringHelper; - } + private BaseContextData $baseContextData, + private EntityManagerInterface $entityManager, + private NormalizerInterface $normalizer, + private PersonRender $personRender, + private PersonRepository $personRepository, + private ThirdPartyRender $thirdPartyRender, + private ThirdPartyRepository $thirdPartyRepository, + private TranslatableStringHelperInterface $translatableStringHelper + ) {} public function adminFormReverseTransform(array $data): array { @@ -147,8 +121,6 @@ final class CalendarContext implements CalendarContextInterface } } - /** - */ public function getData(DocGeneratorTemplate $template, mixed $entity, array $contextGenerationData = []): array { $options = $this->getOptions($template); @@ -198,7 +170,7 @@ final class CalendarContext implements CalendarContextInterface if ($options['askMainPerson']) { $data['mainPerson'] = null; - if (1 === count($entity->getPersons())) { + if (1 === \count($entity->getPersons())) { $data['mainPerson'] = $entity->getPersons()->first(); } } @@ -206,7 +178,7 @@ final class CalendarContext implements CalendarContextInterface if ($options['askThirdParty']) { $data['thirdParty'] = null; - if (1 === count($entity->getProfessionals())) { + if (1 === \count($entity->getProfessionals())) { $data['thirdParty'] = $entity->getProfessionals()->first(); } } diff --git a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContextInterface.php b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContextInterface.php index 74393a422..09a333f3f 100644 --- a/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContextInterface.php +++ b/src/Bundle/ChillCalendarBundle/Service/DocGenerator/CalendarContextInterface.php @@ -12,12 +12,8 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\DocGenerator; use Chill\CalendarBundle\Entity\Calendar; -use Chill\DocGeneratorBundle\Context\DocGeneratorContextInterface; use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithAdminFormInterface; use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithPublicFormInterface; -use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; -use Chill\DocStoreBundle\Entity\StoredObject; -use Symfony\Component\Form\FormBuilderInterface; /** * @extends DocGeneratorContextWithPublicFormInterface diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php index 530843723..5e4e7de83 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/AccompanyingPeriodCalendarGenericDocProvider.php @@ -22,7 +22,6 @@ use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\MappingException; @@ -44,7 +43,7 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen /** * @throws MappingException */ - public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -91,7 +90,7 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen return $this->security->isGranted(CalendarVoter::SEE, $accompanyingPeriod); } - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForPerson(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -136,8 +135,8 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen $storedObjectMetadata->getColumnName('createdAt') ); $orParams = [...$orParams, $participation->getAccompanyingPeriod()->getId(), - DateTimeImmutable::createFromInterface($participation->getStartDate()), - null === $participation->getEndDate() ? null : DateTimeImmutable::createFromInterface($participation->getEndDate())]; + \DateTimeImmutable::createFromInterface($participation->getStartDate()), + null === $participation->getEndDate() ? null : \DateTimeImmutable::createFromInterface($participation->getEndDate())]; $orTypes = [...$orTypes, Types::INTEGER, Types::DATE_IMMUTABLE, Types::DATE_IMMUTABLE]; } @@ -147,7 +146,7 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen return $query; } - $query->addWhereClause(implode(" OR ", $or), $orParams, $orTypes); + $query->addWhereClause(implode(' OR ', $or), $orParams, $orTypes); return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); } @@ -159,7 +158,7 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen return $this->security->isGranted(AccompanyingPeriodVoter::SEE, $person); } - private function addWhereClausesToQuery(FetchQuery $query, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?string $content): FetchQuery + private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -182,7 +181,7 @@ final readonly class AccompanyingPeriodCalendarGenericDocProvider implements Gen if (null !== $content) { $query->addWhereClause( sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), - ['%' . $content . '%'], + ['%'.$content.'%'], [Types::STRING] ); } diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php index 8bc2d4c4c..49e890ca0 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Providers/PersonCalendarGenericDocProvider.php @@ -19,8 +19,6 @@ use Chill\DocStoreBundle\GenericDoc\FetchQuery; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter; -use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\MappingException; @@ -28,7 +26,7 @@ use Service\GenericDoc\Providers\PersonCalendarGenericDocProviderTest; use Symfony\Component\Security\Core\Security; /** - * Provide calendar documents for calendar associated to persons + * Provide calendar documents for calendar associated to persons. * * @see PersonCalendarGenericDocProviderTest */ @@ -41,7 +39,7 @@ final readonly class PersonCalendarGenericDocProvider implements GenericDocForPe private EntityManagerInterface $em ) {} - private function addWhereClausesToQuery(FetchQuery $query, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null): FetchQuery + private function addWhereClausesToQuery(FetchQuery $query, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): FetchQuery { $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -64,7 +62,7 @@ final readonly class PersonCalendarGenericDocProvider implements GenericDocForPe if (null !== $content) { $query->addWhereClause( sprintf('doc_store.%s ilike ?', $storedObjectMetadata->getColumnName('title')), - ['%' . $content . '%'], + ['%'.$content.'%'], [Types::STRING] ); } @@ -75,7 +73,7 @@ final readonly class PersonCalendarGenericDocProvider implements GenericDocForPe /** * @throws MappingException */ - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForPerson(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $classMetadata = $this->em->getClassMetadata(CalendarDoc::class); $storedObjectMetadata = $this->em->getClassMetadata(StoredObject::class); @@ -114,10 +112,6 @@ final readonly class PersonCalendarGenericDocProvider implements GenericDocForPe return $this->addWhereClausesToQuery($query, $startDate, $endDate, $content); } - /** - * @param Person $person - * @return bool - */ public function isAllowedForPerson(Person $person): bool { return $this->security->isGranted(CalendarVoter::SEE, $person); diff --git a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php index b15c091c6..123afc164 100644 --- a/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php +++ b/src/Bundle/ChillCalendarBundle/Service/GenericDoc/Renderers/AccompanyingPeriodCalendarGenericDocRenderer.php @@ -17,18 +17,13 @@ use Chill\CalendarBundle\Service\GenericDoc\Providers\PersonCalendarGenericDocPr use Chill\DocStoreBundle\GenericDoc\GenericDocDTO; use Chill\DocStoreBundle\GenericDoc\Twig\GenericDocRendererInterface; -final class AccompanyingPeriodCalendarGenericDocRenderer implements GenericDocRendererInterface +final readonly class AccompanyingPeriodCalendarGenericDocRenderer implements GenericDocRendererInterface { - private CalendarDocRepository $repository; - - public function __construct(CalendarDocRepository $calendarDocRepository) - { - $this->repository = $calendarDocRepository; - } + public function __construct(private CalendarDocRepository $repository) {} public function supports(GenericDocDTO $genericDocDTO, $options = []): bool { - return $genericDocDTO->key === AccompanyingPeriodCalendarGenericDocProvider::KEY || $genericDocDTO->key === PersonCalendarGenericDocProvider::KEY; + return AccompanyingPeriodCalendarGenericDocProvider::KEY === $genericDocDTO->key || PersonCalendarGenericDocProvider::KEY === $genericDocDTO->key; } public function getTemplate(GenericDocDTO $genericDocDTO, $options = []): string diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php index 83826bbcf..9a4a92a94 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php @@ -19,38 +19,20 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\MessageBusInterface; class BulkCalendarShortMessageSender { - private EntityManagerInterface $em; - - private LoggerInterface $logger; - - private MessageBusInterface $messageBus; - - private ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder; - - private CalendarForShortMessageProvider $provider; - - public function __construct(CalendarForShortMessageProvider $provider, EntityManagerInterface $em, LoggerInterface $logger, MessageBusInterface $messageBus, ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder) - { - $this->provider = $provider; - $this->em = $em; - $this->logger = $logger; - $this->messageBus = $messageBus; - $this->messageForCalendarBuilder = $messageForCalendarBuilder; - } + public function __construct(private readonly CalendarForShortMessageProvider $provider, private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly MessageBusInterface $messageBus, private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder) {} public function sendBulkMessageToEligibleCalendars() { $countCalendars = 0; $countSms = 0; - foreach ($this->provider->getCalendars(new DateTimeImmutable('now')) as $calendar) { + foreach ($this->provider->getCalendars(new \DateTimeImmutable('now')) as $calendar) { $smses = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); foreach ($smses as $sms) { @@ -59,13 +41,13 @@ class BulkCalendarShortMessageSender } $this->em - ->createQuery('UPDATE ' . Calendar::class . ' c SET c.smsStatus = :smsStatus WHERE c.id = :id') + ->createQuery('UPDATE '.Calendar::class.' c SET c.smsStatus = :smsStatus WHERE c.id = :id') ->setParameters(['smsStatus' => Calendar::SMS_SENT, 'id' => $calendar->getId()]) ->execute(); ++$countCalendars; $this->em->refresh($calendar); } - $this->logger->info(self::class . 'a bulk of messages was sent', ['count_calendars' => $countCalendars, 'count_sms' => $countSms]); + $this->logger->info(self::class.'a bulk of messages was sent', ['count_calendars' => $countCalendars, 'count_sms' => $countSms]); } } diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/CalendarForShortMessageProvider.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/CalendarForShortMessageProvider.php index 2316a5408..31b870ed4 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/CalendarForShortMessageProvider.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/CalendarForShortMessageProvider.php @@ -20,27 +20,11 @@ namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Repository\CalendarRepository; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; -use function count; class CalendarForShortMessageProvider { - private CalendarRepository $calendarRepository; - - private EntityManagerInterface $em; - - private RangeGeneratorInterface $rangeGenerator; - - public function __construct( - CalendarRepository $calendarRepository, - EntityManagerInterface $em, - RangeGeneratorInterface $rangeGenerator - ) { - $this->calendarRepository = $calendarRepository; - $this->em = $em; - $this->rangeGenerator = $rangeGenerator; - } + public function __construct(private readonly CalendarRepository $calendarRepository, private readonly EntityManagerInterface $em, private readonly RangeGeneratorInterface $rangeGenerator) {} /** * Generate calendars instance. @@ -49,7 +33,7 @@ class CalendarForShortMessageProvider * * @return iterable|Calendar[] */ - public function getCalendars(DateTimeImmutable $at): iterable + public function getCalendars(\DateTimeImmutable $at): iterable { $range = $this->rangeGenerator->generateRange($at); @@ -76,6 +60,6 @@ class CalendarForShortMessageProvider $calendars = $this->calendarRepository ->findByNotificationAvailable($startDate, $endDate, $batchSize, $offset); - } while (count($calendars) === $batchSize); + } while (\count($calendars) === $batchSize); } } diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultRangeGenerator.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultRangeGenerator.php index 7d6da3ef0..b79118cf0 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultRangeGenerator.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultRangeGenerator.php @@ -18,9 +18,7 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\ShortMessageNotification; -use DateInterval; use Monolog\DateTimeImmutable; -use UnexpectedValueException; /** * * Lundi => Envoi des rdv du mardi et mercredi. @@ -33,7 +31,7 @@ class DefaultRangeGenerator implements RangeGeneratorInterface { public function generateRange(\DateTimeImmutable $date): ?array { - $onMidnight = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-d') . ' 00:00:00'); + $onMidnight = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-d').' 00:00:00'); switch ($dow = (int) $onMidnight->format('w')) { case 6: // Saturday @@ -42,32 +40,32 @@ class DefaultRangeGenerator implements RangeGeneratorInterface case 1: // Monday // send for Tuesday and Wednesday - $startDate = $onMidnight->add(new DateInterval('P1D')); - $endDate = $startDate->add(new DateInterval('P2D')); + $startDate = $onMidnight->add(new \DateInterval('P1D')); + $endDate = $startDate->add(new \DateInterval('P2D')); break; case 2: // tuesday case 3: // wednesday - $startDate = $onMidnight->add(new DateInterval('P2D')); - $endDate = $startDate->add(new DateInterval('P1D')); + $startDate = $onMidnight->add(new \DateInterval('P2D')); + $endDate = $startDate->add(new \DateInterval('P1D')); break; case 4: // thursday - $startDate = $onMidnight->add(new DateInterval('P2D')); - $endDate = $startDate->add(new DateInterval('P2D')); + $startDate = $onMidnight->add(new \DateInterval('P2D')); + $endDate = $startDate->add(new \DateInterval('P2D')); break; case 5: // friday - $startDate = $onMidnight->add(new DateInterval('P3D')); - $endDate = $startDate->add(new DateInterval('P1D')); + $startDate = $onMidnight->add(new \DateInterval('P3D')); + $endDate = $startDate->add(new \DateInterval('P1D')); break; default: - throw new UnexpectedValueException('a day of a week should not have the value: ' . $dow); + throw new \UnexpectedValueException('a day of a week should not have the value: '.$dow); } return ['startDate' => $startDate, 'endDate' => $endDate]; diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php index cd61a8624..880c9950f 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php @@ -20,17 +20,10 @@ namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; use Chill\MainBundle\Service\ShortMessage\ShortMessage; -use Symfony\Component\Templating\EngineInterface; class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface { - private EngineInterface $engine; - - public function __construct( - EngineInterface $engine - ) { - $this->engine = $engine; - } + public function __construct(private readonly \Twig\Environment $engine) {} public function buildMessageForCalendar(Calendar $calendar): array { diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/RangeGeneratorInterface.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/RangeGeneratorInterface.php index 357e264d9..a96664907 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/RangeGeneratorInterface.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/RangeGeneratorInterface.php @@ -18,12 +18,10 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\ShortMessageNotification; -use DateTimeImmutable; - interface RangeGeneratorInterface { /** - * @return ?array{startDate: DateTimeImmutable, endDate: DateTimeImmutable} when return is null, then no ShortMessage must be send + * @return ?array{startDate: \DateTimeImmutable, endDate: \DateTimeImmutable} when return is null, then no ShortMessage must be send */ - public function generateRange(DateTimeImmutable $date): ?array; + public function generateRange(\DateTimeImmutable $date): ?array; } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Controller/CalendarControllerTest.php b/src/Bundle/ChillCalendarBundle/Tests/Controller/CalendarControllerTest.php index f53fe1dea..80d01ada5 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Controller/CalendarControllerTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Controller/CalendarControllerTest.php @@ -11,28 +11,35 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Tests\Controller; +use Chill\MainBundle\Test\PrepareClientTrait; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpFoundation\Request; -use function random_int; /** * @internal + * * @coversNothing */ final class CalendarControllerTest extends WebTestCase { + use PrepareClientTrait; + + private KernelBrowser $client; + /** * Setup before each test method (see phpunit doc). */ protected function setUp(): void { - self::bootKernel(); - $this->client = self::createClient([], [ - 'PHP_AUTH_USER' => 'center a_social', - 'PHP_AUTH_PW' => 'password', - ]); + $this->client = $this->getClientAuthenticated(); + } + + protected function tearDown(): void + { + self::ensureKernelShutdown(); } public function provideAccompanyingPeriod(): iterable @@ -42,18 +49,38 @@ final class CalendarControllerTest extends WebTestCase $nb = $em->createQueryBuilder() ->from(AccompanyingPeriod::class, 'ac') - ->select('COUNT(ac) AS nb') + ->join('ac.participations', 'acp') + ->join('acp.person', 'person') + ->join('person.centerCurrent', 'pc') + ->join('pc.center', 'center') + ->where('center.name LIKE :n') + ->setParameter('n', 'Center A') + ->join('ac.scopes', 's') + ->andWhere('JSON_EXTRACT(s.name,\'fr\') LIKE :s') + ->setParameter('s', 'social') + ->select('COUNT(DISTINCT ac) AS nb') ->getQuery() ->getSingleScalarResult(); yield [$em->createQueryBuilder() ->from(AccompanyingPeriod::class, 'ac') ->select('ac.id') - ->setFirstResult(random_int(0, $nb)) + ->join('ac.participations', 'acp') + ->join('acp.person', 'person') + ->join('person.centerCurrent', 'pc') + ->join('pc.center', 'center') + ->where('center.name LIKE :n') + ->setParameter('n', 'Center A') + ->join('ac.scopes', 's') + ->andWhere('JSON_EXTRACT(s.name,\'fr\') LIKE :s') + ->setParameter('s', 'social') + ->setFirstResult(\random_int(0, $nb - 1)) ->setMaxResults(1) ->getQuery() ->getSingleScalarResult(), ]; + + self::ensureKernelShutdown(); } /** @@ -63,7 +90,7 @@ final class CalendarControllerTest extends WebTestCase { $this->client->request( Request::METHOD_GET, - sprintf('/fr/calendar/calendar/?accompanying_period_id=%d', $accompanyingPeriodId) + sprintf('/fr/calendar/calendar/by-period/%d', $accompanyingPeriodId) ); $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); diff --git a/src/Bundle/ChillCalendarBundle/Tests/Controller/RemoteCalendarMSGraphSyncControllerTest.php b/src/Bundle/ChillCalendarBundle/Tests/Controller/RemoteCalendarMSGraphSyncControllerTest.php index e805f71aa..0c53f2b8d 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Controller/RemoteCalendarMSGraphSyncControllerTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Controller/RemoteCalendarMSGraphSyncControllerTest.php @@ -23,6 +23,7 @@ use Symfony\Component\Messenger\Transport\InMemoryTransport; /** * @internal + * * @coversNothing */ final class RemoteCalendarMSGraphSyncControllerTest extends WebTestCase @@ -48,9 +49,9 @@ final class RemoteCalendarMSGraphSyncControllerTest extends WebTestCase } JSON; - protected function setUp(): void + protected function tearDown(): void { - self::bootKernel(); + self::ensureKernelShutdown(); } public function testSendNotification(): void diff --git a/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarDocTest.php b/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarDocTest.php index fa6132b03..98306b10c 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarDocTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarDocTest.php @@ -18,6 +18,7 @@ use PHPUnit\Framework\TestCase; /** * @internal + * * @coversNothing */ final class CalendarDocTest extends TestCase diff --git a/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarTest.php b/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarTest.php index e37436ad3..1cedea31c 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Entity/CalendarTest.php @@ -24,6 +24,7 @@ use PHPUnit\Framework\TestCase; /** * @internal + * * @coversNothing */ final class CalendarTest extends TestCase diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/AgentAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/AgentAggregatorTest.php index 6746282a4..ae1aa6663 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/AgentAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/AgentAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class AgentAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class AgentAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.agent_aggregator'); } @@ -52,17 +53,14 @@ final class AgentAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.mainUser', 'caluser'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/CancelReasonAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/CancelReasonAggregatorTest.php index 956a81174..0cc1ba58a 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/CancelReasonAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/CancelReasonAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class CancelReasonAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class CancelReasonAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.cancel_reason_aggregator'); } @@ -52,17 +53,14 @@ final class CancelReasonAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.cancelReason', 'calcancel'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/JobAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/JobAggregatorTest.php index b389b1536..50949c3e3 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/JobAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/JobAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class JobAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class JobAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.job_aggregator'); } @@ -52,17 +53,14 @@ final class JobAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.user', 'caluser'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationAggregatorTest.php index 50ee456e5..c46f9d6da 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class LocationAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class LocationAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.location_aggregator'); } @@ -52,17 +53,14 @@ final class LocationAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.location', 'calloc'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php index 55dcf317f..fcf4e2709 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/LocationTypeAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class LocationTypeAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class LocationTypeAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.location_type_aggregator'); } @@ -52,17 +53,14 @@ final class LocationTypeAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.location', 'calloc'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/MonthYearAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/MonthYearAggregatorTest.php index 8e016b54c..7c50a0b52 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/MonthYearAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/MonthYearAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class MonthYearAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class MonthYearAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.month_aggregator'); } @@ -52,9 +53,7 @@ final class MonthYearAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/ScopeAggregatorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/ScopeAggregatorTest.php index fa816f4a5..77ffc0bf1 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/ScopeAggregatorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Aggregator/ScopeAggregatorTest.php @@ -25,6 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ScopeAggregatorTest extends AbstractAggregatorTest @@ -33,7 +34,7 @@ final class ScopeAggregatorTest extends AbstractAggregatorTest protected function setUp(): void { - parent::setUp(); + self::bootKernel(); $this->aggregator = self::$container->get('chill.calendar.export.scope_aggregator'); } @@ -52,17 +53,14 @@ final class ScopeAggregatorTest extends AbstractAggregatorTest public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('count(cal.id)') - ->from(Calendar::class, 'cal') - ->join('cal.user', 'caluser'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/AgentFilterTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/AgentFilterTest.php index d5ec9b22d..3d4efdd83 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/AgentFilterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/AgentFilterTest.php @@ -26,6 +26,7 @@ use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class AgentFilterTest extends AbstractFilterTest @@ -50,8 +51,9 @@ final class AgentFilterTest extends AbstractFilterTest return $this->filter; } - public function getFormData(): array + public function getFormData(): iterable { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() @@ -63,26 +65,25 @@ final class AgentFilterTest extends AbstractFilterTest $data = []; foreach ($array as $a) { - $data[] = [ + yield [ 'accepted_agents' => $a, ]; } - return $data; + self::ensureKernelShutdown(); } - public function getQueryBuilders(): array + public function getQueryBuilders(): iterable { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); - return [ - $em->createQueryBuilder() - ->select('cal.id') - ->from(Calendar::class, 'cal'), - ]; + yield $em->createQueryBuilder() + ->select('cal.id') + ->from(Calendar::class, 'cal') + ; + + self::ensureKernelShutdown(); } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/BetweenDatesFilterTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/BetweenDatesFilterTest.php index 85db16c72..4a7751433 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/BetweenDatesFilterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/BetweenDatesFilterTest.php @@ -20,12 +20,13 @@ namespace Chill\CalendarBundle\Tests\Export\Filter; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Export\Filter\BetweenDatesFilter; +use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Test\Export\AbstractFilterTest; -use DateTime; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class BetweenDatesFilterTest extends AbstractFilterTest @@ -54,17 +55,15 @@ final class BetweenDatesFilterTest extends AbstractFilterTest { return [ [ - 'date_from' => DateTime::createFromFormat('Y-m-d', '2022-05-01'), - 'date_to' => DateTime::createFromFormat('Y-m-d', '2022-06-01'), + 'date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), + 'date_to' => new RollingDate(RollingDate::T_TODAY), ], ]; } public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/JobFilterTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/JobFilterTest.php index 61cb47120..e4bf1ac3b 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/JobFilterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/JobFilterTest.php @@ -22,10 +22,12 @@ use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Export\Filter\JobFilter; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Test\Export\AbstractFilterTest; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class JobFilterTest extends AbstractFilterTest @@ -50,40 +52,35 @@ final class JobFilterTest extends AbstractFilterTest return $this->filter; } - public function getFormData(): array + public function getFormData(): iterable { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(UserJob::class, 'uj') ->select('uj') ->getQuery() + ->setMaxResults(1) ->getResult(); - $data = []; - - foreach ($array as $a) { - $data[] = [ - 'job' => $a, - ]; - } - - return $data; + return [ + [ + 'job' => new ArrayCollection($array), + ], + ]; } public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('cal.id') - ->from(Calendar::class, 'cal') - ->join('cal.user', 'caluser'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/ScopeFilterTest.php b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/ScopeFilterTest.php index a6ab9ed7b..194a6cca7 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/ScopeFilterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Export/Filter/ScopeFilterTest.php @@ -22,10 +22,12 @@ use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Export\Filter\ScopeFilter; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Test\Export\AbstractFilterTest; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; /** * @internal + * * @coversNothing */ final class ScopeFilterTest extends AbstractFilterTest @@ -52,38 +54,33 @@ final class ScopeFilterTest extends AbstractFilterTest public function getFormData(): array { + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $array = $em->createQueryBuilder() ->from(Scope::class, 's') ->select('s') ->getQuery() + ->setMaxResults(1) ->getResult(); - $data = []; - - foreach ($array as $a) { - $data[] = [ - 'scope' => $a, - ]; - } - - return $data; + return [ + [ + 'scope' => new ArrayCollection($array), + ], + ]; } public function getQueryBuilders(): array { - if (null === self::$kernel) { - self::bootKernel(); - } + self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); return [ $em->createQueryBuilder() ->select('cal.id') - ->from(Calendar::class, 'cal') - ->join('cal.user', 'caluser'), + ->from(Calendar::class, 'cal'), ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php b/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php index 9195d5eac..0d1202b67 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php @@ -24,26 +24,29 @@ use Chill\CalendarBundle\Form\CalendarType; use Chill\CalendarBundle\Form\DataTransformer\IdToCalendarRangeDataTransformer; use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Form\DataMapper\PrivateCommentDataMapper; use Chill\MainBundle\Form\DataTransformer\IdToLocationDataTransformer; use Chill\MainBundle\Form\DataTransformer\IdToUserDataTransformer; use Chill\MainBundle\Form\DataTransformer\IdToUsersDataTransformer; use Chill\MainBundle\Form\Type\CommentType; +use Chill\MainBundle\Form\Type\PrivateCommentType; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Form\DataTransformer\PersonsToIdDataTransformer; use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Form\DataTransformer\ThirdPartiesToIdDataTransformer; -use DateTimeImmutable; +use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use Doctrine\Common\Collections\Collection; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use ReflectionProperty; use Symfony\Component\Form\PreloadedExtension; use Symfony\Component\Form\Test\TypeTestCase; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ final class CalendarTypeTest extends TypeTestCase @@ -70,7 +73,7 @@ final class CalendarTypeTest extends TypeTestCase $this->idToUserDataTransformer = $this->buildSingleToIdDataTransformer(IdToUserDataTransformer::class, User::class); $this->idToUsersDataTransformer = $this->buildMultiToIdDataTransformer(IdToUsersDataTransformer::class, User::class); $this->idToLocationDataTransformer = $this->buildSingleToIdDataTransformer(IdToLocationDataTransformer::class, Location::class); - $this->partiesToIdDataTransformer = $this->buildMultiToIdDataTransformer(ThirdPartiesToIdDataTransformer::class, ThirdParty::class); + $this->partiesToIdDataTransformer = $this->buildMultiToIdDataTransformerThirdParties(); $this->calendarRangeDataTransformer = $this->buildSingleToIdDataTransformer(IdToCalendarRangeDataTransformer::class, CalendarRange::class); $tokenStorage = $this->prophesize(TokenStorageInterface::class); $token = $this->prophesize(TokenInterface::class); @@ -86,9 +89,9 @@ final class CalendarTypeTest extends TypeTestCase $formData = [ 'mainUser' => '1', 'users' => '2,3', - 'professionnals' => '4,5', - 'startDate' => '2022-05-05 14:00:00', - 'endDate' => '2022-05-05 14:30:00', + 'professionnals' => '646', + 'startDate' => '2022-05-05T14:00:00+0200', + 'endDate' => '2022-05-05T14:30:00+0200', 'persons' => '7', 'calendarRange' => '8', 'location' => '9', @@ -97,9 +100,9 @@ final class CalendarTypeTest extends TypeTestCase $calendar = new Calendar(); $calendar->setMainUser(new class () extends User { - public function getId() + public function getId(): ?int { - return '1'; + return 1; } }); @@ -108,8 +111,8 @@ final class CalendarTypeTest extends TypeTestCase $form->submit($formData); $this->assertTrue($form->isSynchronized()); - $this->assertEquals(DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-05-05 14:00:00'), $calendar->getStartDate()); - $this->assertEquals(DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-05-05 14:30:00'), $calendar->getEndDate()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-05-05 14:00:00'), $calendar->getStartDate()); + $this->assertEquals(\DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-05-05 14:30:00'), $calendar->getEndDate()); $this->assertEquals(7, $calendar->getPersons()->first()->getId()); $this->assertEquals(8, $calendar->getCalendarRange()->getId()); $this->assertEquals(9, $calendar->getLocation()->getId()); @@ -120,8 +123,6 @@ final class CalendarTypeTest extends TypeTestCase protected function getExtensions() { - $parents = parent::getExtensions(); - $calendarType = new CalendarType( $this->personsToIdDataTransformer, $this->idToUserDataTransformer, @@ -132,12 +133,27 @@ final class CalendarTypeTest extends TypeTestCase ); $commentType = new CommentType($this->tokenStorage); + $user = $this->prophesize(User::class); + $user->getId()->willReturn(1); + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user->reveal()); + $privateCommentDataMapper = new PrivateCommentDataMapper($security->reveal()); + $privateCommentType = new PrivateCommentType($privateCommentDataMapper); + return array_merge( parent::getExtensions(), - [new PreloadedExtension([$calendarType, $commentType], [])] + [new PreloadedExtension([$calendarType, $commentType, $privateCommentType], [])] ); } + private function buildMultiToIdDataTransformerThirdParties(): ThirdPartiesToIdDataTransformer + { + $repository = $this->prophesize(ThirdPartyRepository::class); + $repository->findOneBy(Argument::type('array'))->willReturn(new ThirdParty()); + + return new ThirdPartiesToIdDataTransformer($repository->reveal()); + } + private function buildMultiToIdDataTransformer( string $classTransformer, string $objClass @@ -164,13 +180,13 @@ final class CalendarTypeTest extends TypeTestCase return array_map( static function ($id) use ($objClass) { $obj = new $objClass(); - $reflectionProperty = new ReflectionProperty($objClass, 'id'); + $reflectionProperty = new \ReflectionProperty($objClass, 'id'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($obj, (int) $id); return $obj; }, - explode(',', $args[0]) + explode(',', (string) $args[0]) ); }); @@ -192,7 +208,7 @@ final class CalendarTypeTest extends TypeTestCase return null; } $obj = new $class(); - $reflectionProperty = new ReflectionProperty($class, 'id'); + $reflectionProperty = new \ReflectionProperty($class, 'id'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($obj, (int) $args[0]); diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/AddressConverterTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/AddressConverterTest.php index 827e22381..eca929875 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/AddressConverterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/AddressConverterTest.php @@ -27,10 +27,10 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use Symfony\Component\Templating\EngineInterface; /** * @internal + * * @coversNothing */ final class AddressConverterTest extends TestCase @@ -61,7 +61,7 @@ final class AddressConverterTest extends TestCase private function buildAddressConverter(): AddressConverter { - $engine = $this->prophesize(EngineInterface::class); + $engine = $this->prophesize(\Twig\Environment::class); $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class); $translatableStringHelper->localize(Argument::type('array'))->will(static fn ($args): string => ($args[0] ?? ['fr' => 'not provided'])['fr'] ?? 'not provided'); diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarRangeSyncerTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarRangeSyncerTest.php index 92280f6c1..9f7df0c2c 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarRangeSyncerTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarRangeSyncerTest.php @@ -22,7 +22,6 @@ use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\CalendarRange; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteToLocalSync\CalendarRangeSyncer; use Chill\MainBundle\Entity\User; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; @@ -33,6 +32,7 @@ use Symfony\Component\HttpClient\Response\MockResponse; /** * @internal + * * @coversNothing */ final class CalendarRangeSyncerTest extends TestCase @@ -228,8 +228,8 @@ final class CalendarRangeSyncerTest extends TestCase $calendarRange = new CalendarRange(); $calendarRange ->setUser($user = new User()) - ->setStartDate(new DateTimeImmutable('2020-01-01 15:00:00')) - ->setEndDate(new DateTimeImmutable('2020-01-01 15:30:00')) + ->setStartDate(new \DateTimeImmutable('2020-01-01 15:00:00')) + ->setEndDate(new \DateTimeImmutable('2020-01-01 15:30:00')) ->addRemoteAttributes([ 'lastModifiedDateTime' => 0, 'changeKey' => 'abc', @@ -244,11 +244,11 @@ final class CalendarRangeSyncerTest extends TestCase $this->assertStringContainsString( '2022-06-10T15:30:00', - $calendarRange->getStartDate()->format(DateTimeImmutable::ATOM) + $calendarRange->getStartDate()->format(\DateTimeImmutable::ATOM) ); $this->assertStringContainsString( '2022-06-10T17:30:00', - $calendarRange->getEndDate()->format(DateTimeImmutable::ATOM) + $calendarRange->getEndDate()->format(\DateTimeImmutable::ATOM) ); $this->assertTrue($calendarRange->preventEnqueueChanges); } diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarSyncerTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarSyncerTest.php index 6ccd7a35e..8f6cb9335 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarSyncerTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/CalendarSyncerTest.php @@ -24,8 +24,6 @@ use Chill\CalendarBundle\Entity\Invite; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteToLocalSync\CalendarSyncer; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Repository\UserRepositoryInterface; -use DateTimeImmutable; -use DateTimeZone; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -35,6 +33,7 @@ use Symfony\Component\HttpClient\Response\MockResponse; /** * @internal + * * @coversNothing */ final class CalendarSyncerTest extends TestCase @@ -362,9 +361,9 @@ final class CalendarSyncerTest extends TestCase parent::setUp(); // all tests should run when timezone = +02:00 - $brussels = new DateTimeZone('Europe/Brussels'); + $brussels = new \DateTimeZone('Europe/Brussels'); - if (7200 === $brussels->getOffset(new DateTimeImmutable())) { + if (7200 === $brussels->getOffset(new \DateTimeImmutable())) { date_default_timezone_set('Europe/Brussels'); } else { date_default_timezone_set('Europe/Moscow'); @@ -403,8 +402,8 @@ final class CalendarSyncerTest extends TestCase $calendar = new Calendar(); $calendar ->setMainUser($user = new User()) - ->setStartDate(new DateTimeImmutable('2022-06-11 14:30:00')) - ->setEndDate(new DateTimeImmutable('2022-06-11 15:30:00')) + ->setStartDate(new \DateTimeImmutable('2022-06-11 14:30:00')) + ->setEndDate(new \DateTimeImmutable('2022-06-11 15:30:00')) ->addUser($userA) ->addUser($userB) ->setCalendarRange(new CalendarRange()) @@ -480,13 +479,14 @@ final class CalendarSyncerTest extends TestCase $calendar = new Calendar(); $calendar ->setMainUser($user = new User()) - ->setStartDate(new DateTimeImmutable('2020-01-01 10:00:00')) - ->setEndDate(new DateTimeImmutable('2020-01-01 12:00:00')) + ->setStartDate(new \DateTimeImmutable('2020-01-01 10:00:00')) + ->setEndDate(new \DateTimeImmutable('2020-01-01 12:00:00')) ->setCalendarRange(new CalendarRange()) ->addRemoteAttributes([ 'lastModifiedDateTime' => 0, 'changeKey' => 'abcd', ]); + $previousVersion = $calendar->getDateTimeVersion(); $notification = json_decode(self::NOTIF_UPDATE, true); $calendarSyncer->handleCalendarSync( @@ -497,14 +497,14 @@ final class CalendarSyncerTest extends TestCase $this->assertStringContainsString( '2022-06-10T15:30:00', - $calendar->getStartDate()->format(DateTimeImmutable::ATOM) + $calendar->getStartDate()->format(\DateTimeImmutable::ATOM) ); $this->assertStringContainsString( '2022-06-10T17:30:00', - $calendar->getEndDate()->format(DateTimeImmutable::ATOM) + $calendar->getEndDate()->format(\DateTimeImmutable::ATOM) ); $this->assertTrue($calendar->preventEnqueueChanges); - $this->assertEquals(Calendar::STATUS_MOVED, $calendar->getStatus()); + $this->assertGreaterThan($previousVersion, $calendar->getDateTimeVersion()); } public function testHandleNotMovedCalendar(): void @@ -523,8 +523,8 @@ final class CalendarSyncerTest extends TestCase $calendar = new Calendar(); $calendar ->setMainUser($user = new User()) - ->setStartDate(new DateTimeImmutable('2022-06-10 15:30:00')) - ->setEndDate(new DateTimeImmutable('2022-06-10 17:30:00')) + ->setStartDate(new \DateTimeImmutable('2022-06-10 15:30:00')) + ->setEndDate(new \DateTimeImmutable('2022-06-10 17:30:00')) ->setCalendarRange(new CalendarRange()) ->addRemoteAttributes([ 'lastModifiedDateTime' => 0, @@ -540,11 +540,11 @@ final class CalendarSyncerTest extends TestCase $this->assertStringContainsString( '2022-06-10T15:30:00', - $calendar->getStartDate()->format(DateTimeImmutable::ATOM) + $calendar->getStartDate()->format(\DateTimeImmutable::ATOM) ); $this->assertStringContainsString( '2022-06-10T17:30:00', - $calendar->getEndDate()->format(DateTimeImmutable::ATOM) + $calendar->getEndDate()->format(\DateTimeImmutable::ATOM) ); $this->assertTrue($calendar->preventEnqueueChanges); $this->assertEquals(Calendar::STATUS_VALID, $calendar->getStatus()); @@ -567,8 +567,8 @@ final class CalendarSyncerTest extends TestCase $calendar = new Calendar(); $calendar ->setMainUser($user = new User()) - ->setStartDate(new DateTimeImmutable('2020-01-01 10:00:00')) - ->setEndDate(new DateTimeImmutable('2020-01-01 12:00:00')) + ->setStartDate(new \DateTimeImmutable('2020-01-01 10:00:00')) + ->setEndDate(new \DateTimeImmutable('2020-01-01 12:00:00')) ->setCalendarRange(new CalendarRange()) ->addRemoteAttributes([ 'lastModifiedDateTime' => 0, @@ -584,11 +584,11 @@ final class CalendarSyncerTest extends TestCase $this->assertStringContainsString( '2020-01-01T10:00:00', - $calendar->getStartDate()->format(DateTimeImmutable::ATOM) + $calendar->getStartDate()->format(\DateTimeImmutable::ATOM) ); $this->assertStringContainsString( '2020-01-01T12:00:00', - $calendar->getEndDate()->format(DateTimeImmutable::ATOM) + $calendar->getEndDate()->format(\DateTimeImmutable::ATOM) ); $this->assertEquals(Calendar::STATUS_VALID, $calendar->getStatus()); diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/LocationConverterTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/LocationConverterTest.php index 604b707c0..55dfe427c 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/LocationConverterTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/LocationConverterTest.php @@ -30,6 +30,7 @@ use Prophecy\PhpUnit\ProphecyTrait; /** * @internal + * * @coversNothing */ final class LocationConverterTest extends TestCase diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php index 2ceab8b1f..4307f32a3 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceReaderTest.php @@ -22,6 +22,7 @@ use Symfony\Component\HttpClient\Response\MockResponse; /** * @internal + * * @coversNothing */ class MSUserAbsenceReaderTest extends TestCase @@ -55,7 +56,7 @@ class MSUserAbsenceReaderTest extends TestCase $absenceReader = new MSUserAbsenceReader($client, $mapUser->reveal(), $clock); - self::assertNull($absenceReader->isUserAbsent($user), "when no user found, absence should be null"); + self::assertNull($absenceReader->isUserAbsent($user), 'when no user found, absence should be null'); } public function provideDataTestUserAbsence(): iterable @@ -81,7 +82,7 @@ class MSUserAbsenceReaderTest extends TestCase } JSON, false, - "User is present" + 'User is present', ]; yield [ @@ -103,7 +104,7 @@ class MSUserAbsenceReaderTest extends TestCase } JSON, true, - 'User is absent with absence scheduled, we are within this period' + 'User is absent with absence scheduled, we are within this period', ]; yield [ @@ -125,7 +126,7 @@ class MSUserAbsenceReaderTest extends TestCase } JSON, false, - 'User is present: absence is scheduled for later' + 'User is present: absence is scheduled for later', ]; yield [ @@ -147,7 +148,7 @@ class MSUserAbsenceReaderTest extends TestCase } JSON, false, - 'User is present: absence is past' + 'User is present: absence is past', ]; yield [ @@ -169,7 +170,7 @@ class MSUserAbsenceReaderTest extends TestCase } JSON, true, - "User is absent: absence is always enabled" + 'User is absent: absence is always enabled', ]; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php index 1b0f1e416..244c7e468 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/RemoteCalendar/Connector/MSGraph/MSUserAbsenceSyncTest.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Tests\RemoteCalendar\Connector\MSGraph; -use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceReader; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceReaderInterface; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync; use Chill\MainBundle\Entity\User; @@ -22,6 +21,7 @@ use Symfony\Component\Clock\MockClock; /** * @internal + * * @coversNothing */ class MSUserAbsenceSyncTest extends TestCase @@ -48,21 +48,21 @@ class MSUserAbsenceSyncTest extends TestCase public function provideDataTestSyncUserAbsence(): iterable { - yield [new User(), false, false, null, "user present remains present"]; - yield [new User(), true, true, new \DateTimeImmutable('2023-07-01T12:00:00'), "user present becomes absent"]; + yield [new User(), false, false, null, 'user present remains present']; + yield [new User(), true, true, new \DateTimeImmutable('2023-07-01T12:00:00'), 'user present becomes absent']; $user = new User(); - $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); - yield [$user, true, true, $abs, "user absent remains absent"]; + $user->setAbsenceStart($abs = new \DateTimeImmutable('2023-07-01T12:00:00')); + yield [$user, true, true, $abs, 'user absent remains absent']; $user = new User(); - $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); - yield [$user, false, false, null, "user absent becomes present"]; + $user->setAbsenceStart($abs = new \DateTimeImmutable('2023-07-01T12:00:00')); + yield [$user, false, false, null, 'user absent becomes present']; - yield [new User(), null, false, null, "user not syncable: presence do not change"]; + yield [new User(), null, false, null, 'user not syncable: presence do not change']; $user = new User(); - $user->setAbsenceStart($abs = new \DateTimeImmutable("2023-07-01T12:00:00")); - yield [$user, null, true, $abs, "user not syncable: absence do not change"]; + $user->setAbsenceStart($abs = new \DateTimeImmutable('2023-07-01T12:00:00')); + yield [$user, null, true, $abs, 'user not syncable: absence do not change']; } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Repository/CalendarACLAwareRepositoryTest.php b/src/Bundle/ChillCalendarBundle/Tests/Repository/CalendarACLAwareRepositoryTest.php index 0fb4a662b..8d3101c5b 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Repository/CalendarACLAwareRepositoryTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Repository/CalendarACLAwareRepositoryTest.php @@ -15,13 +15,13 @@ use Chill\CalendarBundle\Repository\CalendarACLAwareRepository; use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** * @internal + * * @coversNothing */ final class CalendarACLAwareRepositoryTest extends KernelTestCase @@ -51,7 +51,7 @@ final class CalendarACLAwareRepositoryTest extends KernelTestCase $this->entityManager ); - $count = $calendarRepository->countByPerson($person, new DateTimeImmutable('yesterday'), new DateTimeImmutable('tomorrow')); + $count = $calendarRepository->countByPerson($person, new \DateTimeImmutable('yesterday'), new \DateTimeImmutable('tomorrow')); $this->assertIsInt($count); } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Serializer/Normalizer/CalendarNormalizerTest.php b/src/Bundle/ChillCalendarBundle/Tests/Serializer/Normalizer/CalendarNormalizerTest.php index 2a0975206..03ba7f164 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Serializer/Normalizer/CalendarNormalizerTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Serializer/Normalizer/CalendarNormalizerTest.php @@ -16,12 +16,12 @@ use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; use Chill\ThirdPartyBundle\Entity\ThirdParty; -use DateTimeImmutable; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * @internal + * * @coversNothing */ final class CalendarNormalizerTest extends KernelTestCase @@ -41,8 +41,8 @@ final class CalendarNormalizerTest extends KernelTestCase ->setComment( $comment = new CommentEmbeddable() ) - ->setStartDate(DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, '2020-10-15T15:00:00+0000')) - ->setEndDate(DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, '2020-15-15T15:30:00+0000')) + ->setStartDate(\DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, '2020-10-15T15:00:00+0000')) + ->setEndDate(\DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, '2020-15-15T15:30:00+0000')) ->addPerson(new Person()) ->addPerson(new Person()) ->addUser(new User()) diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php index cbb4ea3af..506baa98b 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php @@ -19,8 +19,10 @@ use Chill\DocGeneratorBundle\Service\Context\BaseContextData; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Templating\Entity\PersonRender; use Chill\ThirdPartyBundle\Entity\ThirdParty; +use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository; use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; @@ -31,11 +33,10 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -use function array_key_exists; -use function count; /** * @internal + * * @coversNothing */ final class CalendarContextTest extends TestCase @@ -83,13 +84,13 @@ final class CalendarContextTest extends TestCase // so, we expect the call to be twice for each method $formBuilder->add('thirdParty', EntityType::class, Argument::type('array')) ->should(static function ($calls, $object, $method) use ($tp1, $tp2) { - if (2 !== count($calls)) { - throw new FailedPredictionException(sprintf('the $builder->add should be called exactly 2, %d receivved', count($calls))); + if (2 !== \count($calls)) { + throw new FailedPredictionException(sprintf('the $builder->add should be called exactly 2, %d receivved', \count($calls))); } $opts = $calls[0]->getArguments()[2]; - if (!array_key_exists('label', $opts)) { + if (!\array_key_exists('label', $opts)) { throw new FailedPredictionException('the $builder->add should have a label key'); } @@ -103,13 +104,13 @@ final class CalendarContextTest extends TestCase }); $formBuilder->add('mainPerson', EntityType::class, Argument::type('array')) ->should(static function ($calls, $object, $method) use ($p1) { - if (2 !== count($calls)) { - throw new FailedPredictionException(sprintf('the $builder->add should be called exactly 2, %d receivved', count($calls))); + if (2 !== \count($calls)) { + throw new FailedPredictionException(sprintf('the $builder->add should be called exactly 2, %d receivved', \count($calls))); } $opts = $calls[0]->getArguments()[2]; - if (!array_key_exists('label', $opts)) { + if (!\array_key_exists('label', $opts)) { throw new FailedPredictionException('the $builder->add should have a label key'); } @@ -176,7 +177,7 @@ final class CalendarContextTest extends TestCase $em = $this->prophesize(EntityManagerInterface::class); $em->persist(Argument::type(CalendarDoc::class))->should( static function ($calls, $object, $method) use ($storedObject) { - if (1 !== count($calls)) { + if (1 !== \count($calls)) { throw new FailedPredictionException('the persist method should be called once'); } @@ -187,7 +188,7 @@ final class CalendarContextTest extends TestCase throw new FailedPredictionException('the stored object is not correct'); } - if ($calendarDoc->getStoredObject()->getTitle() !== 'blabla') { + if ('blabla' !== $calendarDoc->getStoredObject()->getTitle()) { throw new FailedPredictionException('the doc title should be the one provided'); } @@ -201,8 +202,8 @@ final class CalendarContextTest extends TestCase } private function buildCalendarContext( - ?EntityManagerInterface $entityManager = null, - ?NormalizerInterface $normalizer = null + EntityManagerInterface $entityManager = null, + NormalizerInterface $normalizer = null ): CalendarContext { $baseContext = $this->prophesize(BaseContextData::class); $baseContext->getData(null)->willReturn(['base_context' => 'data']); @@ -210,9 +211,15 @@ final class CalendarContextTest extends TestCase $personRender = $this->prophesize(PersonRender::class); $personRender->renderString(Argument::type(Person::class), [])->willReturn('person name'); + $personRepository = $this->prophesize(PersonRepository::class); + $personRepository->find(Argument::type('int'))->willReturn(new Person()); + $thirdPartyRender = $this->prophesize(ThirdPartyRender::class); $thirdPartyRender->renderString(Argument::type(ThirdParty::class), [])->willReturn('third party name'); + $thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class); + $thirdPartyRepository->find(Argument::type('int'))->willReturn(new ThirdParty()); + $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class); $translatableStringHelper->localize(Argument::type('array'))->willReturn('blabla'); @@ -229,7 +236,9 @@ final class CalendarContextTest extends TestCase $entityManager, $normalizer, $personRender->reveal(), + $personRepository->reveal(), $thirdPartyRender->reveal(), + $thirdPartyRepository->reveal(), $translatableStringHelper->reveal() ); } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php index 0c190f51d..308c17237 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php @@ -18,7 +18,6 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification; -use ArrayIterator; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Service\ShortMessageNotification\BulkCalendarShortMessageSender; use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider; @@ -27,20 +26,18 @@ use Chill\MainBundle\Entity\User; use Chill\MainBundle\Service\ShortMessage\ShortMessage; use Chill\MainBundle\Test\PrepareUserTrait; use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper; -use DateInterval; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use libphonenumber\PhoneNumberUtil; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Psr\Log\NullLogger; -use stdClass; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; /** * @internal + * * @coversNothing */ final class BulkCalendarShortMessageSenderTest extends KernelTestCase @@ -79,26 +76,26 @@ final class BulkCalendarShortMessageSenderTest extends KernelTestCase $calendar ->addPerson($this->getRandomPerson($em)) ->setMainUser($user = $this->prepareUser([])) - ->setStartDate(new DateTimeImmutable('now')) - ->setEndDate($calendar->getStartDate()->add(new DateInterval('PT30M'))) + ->setStartDate(new \DateTimeImmutable('now')) + ->setEndDate($calendar->getStartDate()->add(new \DateInterval('PT30M'))) ->setSendSMS(true); $user->setUsername(uniqid()); - $user->setEmail(uniqid() . '@gmail.com'); + $user->setEmail(uniqid().'@gmail.com'); $calendar->getPersons()->first()->setAcceptSMS(true); // hack to prevent side effect with messages $calendar->preventEnqueueChanges = true; $em->persist($user); - //$this->toDelete[] = [User::class, $user->getId()]; + // $this->toDelete[] = [User::class, $user->getId()]; $em->persist($calendar); - //$this->toDelete[] = [Calendar::class, $calendar->getId()]; + // $this->toDelete[] = [Calendar::class, $calendar->getId()]; $em->flush(); $provider = $this->prophesize(CalendarForShortMessageProvider::class); - $provider->getCalendars(Argument::type(DateTimeImmutable::class)) - ->willReturn(new ArrayIterator([$calendar])); + $provider->getCalendars(Argument::type(\DateTimeImmutable::class)) + ->willReturn(new \ArrayIterator([$calendar])); $messageBuilder = $this->prophesize(ShortMessageForCalendarBuilderInterface::class); $messageBuilder->buildMessageForCalendar(Argument::type(Calendar::class)) @@ -114,7 +111,7 @@ final class BulkCalendarShortMessageSenderTest extends KernelTestCase $bus = $this->prophesize(MessageBusInterface::class); $bus->dispatch(Argument::type(ShortMessage::class)) - ->willReturn(new Envelope(new stdClass())) + ->willReturn(new Envelope(new \stdClass())) ->shouldBeCalledTimes(1); $bulk = new BulkCalendarShortMessageSender( diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/CalendarForShortMessageProviderTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/CalendarForShortMessageProviderTest.php index 34867d8bd..47af7d68e 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/CalendarForShortMessageProviderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/CalendarForShortMessageProviderTest.php @@ -23,15 +23,14 @@ use Chill\CalendarBundle\Repository\CalendarRepository; use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider; use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultRangeGenerator; use Chill\CalendarBundle\Service\ShortMessageNotification\RangeGeneratorInterface; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use function count; /** * @internal + * * @coversNothing */ final class CalendarForShortMessageProviderTest extends TestCase @@ -42,13 +41,13 @@ final class CalendarForShortMessageProviderTest extends TestCase { $calendarRepository = $this->prophesize(CalendarRepository::class); $calendarRepository->findByNotificationAvailable( - Argument::type(DateTimeImmutable::class), - Argument::type(DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), Argument::type('int'), Argument::exact(0) )->shouldBeCalledTimes(0); $rangeGenerator = $this->prophesize(RangeGeneratorInterface::class); - $rangeGenerator->generateRange(Argument::type(DateTimeImmutable::class))->willReturn(null); + $rangeGenerator->generateRange(Argument::type(\DateTimeImmutable::class))->willReturn(null); $em = $this->prophesize(EntityManagerInterface::class); $em->clear()->shouldNotBeCalled(); @@ -59,23 +58,23 @@ final class CalendarForShortMessageProviderTest extends TestCase $rangeGenerator->reveal() ); - $calendars = iterator_to_array($provider->getCalendars(new DateTimeImmutable('now'))); + $calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now'))); - $this->assertEquals(0, count($calendars)); + $this->assertEquals(0, \count($calendars)); } public function testGetCalendars() { $calendarRepository = $this->prophesize(CalendarRepository::class); $calendarRepository->findByNotificationAvailable( - Argument::type(DateTimeImmutable::class), - Argument::type(DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), Argument::type('int'), Argument::exact(0) )->will(static fn ($args) => array_fill(0, $args[2], new Calendar()))->shouldBeCalledTimes(1); $calendarRepository->findByNotificationAvailable( - Argument::type(DateTimeImmutable::class), - Argument::type(DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), Argument::type('int'), Argument::not(0) )->will(static fn ($args) => array_fill(0, $args[2] - 1, new Calendar()))->shouldBeCalledTimes(1); @@ -89,10 +88,10 @@ final class CalendarForShortMessageProviderTest extends TestCase new DefaultRangeGenerator() ); - $calendars = iterator_to_array($provider->getCalendars(new DateTimeImmutable('now'))); + $calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now'))); - $this->assertGreaterThan(1, count($calendars)); - $this->assertLessThan(100, count($calendars)); + $this->assertGreaterThan(1, \count($calendars)); + $this->assertLessThan(100, \count($calendars)); $this->assertContainsOnly(Calendar::class, $calendars); } @@ -100,14 +99,14 @@ final class CalendarForShortMessageProviderTest extends TestCase { $calendarRepository = $this->prophesize(CalendarRepository::class); $calendarRepository->findByNotificationAvailable( - Argument::type(DateTimeImmutable::class), - Argument::type(DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), Argument::type('int'), Argument::exact(0) )->will(static fn ($args) => array_fill(0, 1, new Calendar()))->shouldBeCalledTimes(1); $calendarRepository->findByNotificationAvailable( - Argument::type(DateTimeImmutable::class), - Argument::type(DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), + Argument::type(\DateTimeImmutable::class), Argument::type('int'), Argument::not(0) )->will(static fn ($args) => [])->shouldBeCalledTimes(1); @@ -121,9 +120,9 @@ final class CalendarForShortMessageProviderTest extends TestCase new DefaultRangeGenerator() ); - $calendars = iterator_to_array($provider->getCalendars(new DateTimeImmutable('now'))); + $calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now'))); - $this->assertEquals(1, count($calendars)); + $this->assertEquals(1, \count($calendars)); $this->assertContainsOnly(Calendar::class, $calendars); } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultRangeGeneratorTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultRangeGeneratorTest.php index de2b97963..552595414 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultRangeGeneratorTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultRangeGeneratorTest.php @@ -19,12 +19,11 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification; use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultRangeGenerator; -use DateTimeImmutable; -use Iterator; use PHPUnit\Framework\TestCase; /** * @internal + * * @coversNothing */ final class DefaultRangeGeneratorTest extends TestCase @@ -36,46 +35,46 @@ final class DefaultRangeGeneratorTest extends TestCase * * Jeudi => envoi des rdv du samedi et dimanche * * Vendredi => Envoi des rdv du lundi. */ - public function generateData(): Iterator + public function generateData(): \Iterator { yield [ - new DateTimeImmutable('2022-06-13 10:45:00'), - new DateTimeImmutable('2022-06-14 00:00:00'), - new DateTimeImmutable('2022-06-16 00:00:00'), + new \DateTimeImmutable('2022-06-13 10:45:00'), + new \DateTimeImmutable('2022-06-14 00:00:00'), + new \DateTimeImmutable('2022-06-16 00:00:00'), ]; yield [ - new DateTimeImmutable('2022-06-14 15:45:00'), - new DateTimeImmutable('2022-06-16 00:00:00'), - new DateTimeImmutable('2022-06-17 00:00:00'), + new \DateTimeImmutable('2022-06-14 15:45:00'), + new \DateTimeImmutable('2022-06-16 00:00:00'), + new \DateTimeImmutable('2022-06-17 00:00:00'), ]; yield [ - new DateTimeImmutable('2022-06-15 13:45:18'), - new DateTimeImmutable('2022-06-17 00:00:00'), - new DateTimeImmutable('2022-06-18 00:00:00'), + new \DateTimeImmutable('2022-06-15 13:45:18'), + new \DateTimeImmutable('2022-06-17 00:00:00'), + new \DateTimeImmutable('2022-06-18 00:00:00'), ]; yield [ - new DateTimeImmutable('2022-06-16 01:30:55'), - new DateTimeImmutable('2022-06-18 00:00:00'), - new DateTimeImmutable('2022-06-20 00:00:00'), + new \DateTimeImmutable('2022-06-16 01:30:55'), + new \DateTimeImmutable('2022-06-18 00:00:00'), + new \DateTimeImmutable('2022-06-20 00:00:00'), ]; yield [ - new DateTimeImmutable('2022-06-17 21:30:55'), - new DateTimeImmutable('2022-06-20 00:00:00'), - new DateTimeImmutable('2022-06-21 00:00:00'), + new \DateTimeImmutable('2022-06-17 21:30:55'), + new \DateTimeImmutable('2022-06-20 00:00:00'), + new \DateTimeImmutable('2022-06-21 00:00:00'), ]; yield [ - new DateTimeImmutable('2022-06-18 21:30:55'), + new \DateTimeImmutable('2022-06-18 21:30:55'), null, null, ]; yield [ - new DateTimeImmutable('2022-06-19 21:30:55'), + new \DateTimeImmutable('2022-06-19 21:30:55'), null, null, ]; @@ -84,7 +83,7 @@ final class DefaultRangeGeneratorTest extends TestCase /** * @dataProvider generateData */ - public function testGenerateRange(DateTimeImmutable $date, ?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate) + public function testGenerateRange(\DateTimeImmutable $date, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate) { $generator = new DefaultRangeGenerator(); @@ -94,8 +93,8 @@ final class DefaultRangeGeneratorTest extends TestCase $this->assertNull($actualStartDate); $this->assertNull($actualEndDate); } else { - $this->assertEquals($startDate->format(DateTimeImmutable::ATOM), $actualStartDate->format(DateTimeImmutable::ATOM)); - $this->assertEquals($endDate->format(DateTimeImmutable::ATOM), $actualEndDate->format(DateTimeImmutable::ATOM)); + $this->assertEquals($startDate->format(\DateTimeImmutable::ATOM), $actualStartDate->format(\DateTimeImmutable::ATOM)); + $this->assertEquals($endDate->format(\DateTimeImmutable::ATOM), $actualEndDate->format(\DateTimeImmutable::ATOM)); } } } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php index 6d42540cc..222d3a451 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php @@ -23,17 +23,15 @@ use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultShortMessageFor use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; -use DateInterval; -use DateTimeImmutable; use libphonenumber\PhoneNumberFormat; use libphonenumber\PhoneNumberUtil; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; -use Symfony\Component\Templating\EngineInterface; /** * @internal + * * @coversNothing */ final class DefaultShortMessageForCalendarBuilderTest extends TestCase @@ -51,8 +49,8 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase { $calendar = new Calendar(); $calendar - ->setStartDate(new DateTimeImmutable('now')) - ->setEndDate($calendar->getStartDate()->add(new DateInterval('PT30M'))) + ->setStartDate(new \DateTimeImmutable('now')) + ->setEndDate($calendar->getStartDate()->add(new \DateInterval('PT30M'))) ->setMainUser($user = new User()) ->addPerson($person = new Person()) ->setSendSMS(false); @@ -64,7 +62,7 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase ->setMobilenumber($this->phoneNumberUtil->parse('+32470123456', 'BE')) ->setAcceptSMS(false); - $engine = $this->prophesize(EngineInterface::class); + $engine = $this->prophesize(\Twig\Environment::class); $engine->render(Argument::exact('@ChillCalendar/CalendarShortMessage/short_message.txt.twig'), Argument::withKey('calendar')) ->willReturn('message content') ->shouldBeCalledTimes(1); diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml index c56d7835f..d157683e0 100644 --- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml @@ -99,24 +99,32 @@ Get the sum of appointment durations according to various filters: Calcule la so 'Filtered by agent: only %agents%': "Filtré par agents: uniquement %agents%" Filter calendars by agent: Filtrer les rendez-vous par agents -Filter calendars by agent job: Filtrer les rendez-vous par métiers des agents -'Filtered by agent job: only %jobs%': 'Filtré par métiers des agents: uniquement les %jobs%' -Filter calendars by agent scope: Filtrer les rendez-vous par services des agents -'Filtered by agent scope: only %scopes%': 'Filtré par services des agents: uniquement les services %scopes%' Filter calendars between certain dates: Filtrer les rendez-vous par date du rendez-vous 'Filtered by calendars between %dateFrom% and %dateTo%': 'Filtré par rendez-vous entre %dateFrom% et %dateTo%' 'Filtered by calendar range: only %calendarRange%': 'Filtré par rendez-vous par plage de disponibilité: uniquement les %calendarRange%' Filter by calendar range: Filtrer par rendez-vous dans une plage de disponibilité ou non Group calendars by agent: Grouper les rendez-vous par agent -Group calendars by agent job: Grouper les rendez-vous par métier de l'agent -Group calendars by agent scope: Grouper les rendez-vous par service de l'agent Group calendars by location type: Grouper les rendez-vous par type de localisation Group calendars by location: Grouper les rendez-vous par lieu de rendez-vous Group calendars by cancel reason: Grouper les rendez-vous par motif d'annulation Group calendars by month and year: Grouper les rendez-vous par mois et année Group calendars by urgency: Grouper les rendez-vous par urgent ou non +export: + aggregator.calendar: + agent_job: + Group calendars by agent job: Grouper les rendez-vous par métier de l'agent + agent_scope: + Group calendars by agent scope: Grouper les rendez-vous par service de l'agent + filter.calendar: + agent_job: + Filter calendars by agent job: Filtrer les rendez-vous par métiers des agents (utilisateurs principaux) + 'Filtered by agent job: only %jobs%': 'Filtré par métiers des agents (utilisateurs principaux): uniquement les %jobs%' + agent_scope: + Filter calendars by agent scope: Filtrer les rendez-vous par services des agents (utilisateurs principaux) + 'Filtered by agent scope: only %scopes%': 'Filtré par services des agents (utilisateurs principaux): uniquement les services %scopes%' + Scope: Service Job: Métier Location type: Type de localisation diff --git a/src/Bundle/ChillCustomFieldsBundle/ChillCustomFieldsBundle.php b/src/Bundle/ChillCustomFieldsBundle/ChillCustomFieldsBundle.php index 4167efd2e..5d32ed7e9 100644 --- a/src/Bundle/ChillCustomFieldsBundle/ChillCustomFieldsBundle.php +++ b/src/Bundle/ChillCustomFieldsBundle/ChillCustomFieldsBundle.php @@ -19,6 +19,6 @@ class ChillCustomFieldsBundle extends Bundle public function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container) { parent::build($container); - $container->addCompilerPass(new CustomFieldCompilerPass()); + $container->addCompilerPass(new CustomFieldCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); } } diff --git a/src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php b/src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php index 2a03e90bb..08425bcf0 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php +++ b/src/Bundle/ChillCustomFieldsBundle/Command/CreateFieldsOnGroupCommand.php @@ -15,7 +15,6 @@ use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup; use Chill\CustomFieldsBundle\Service\CustomFieldProvider; use Doctrine\ORM\EntityManager; -use RuntimeException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; @@ -26,55 +25,26 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; -use function count; - /** * Class for the command 'chill:custom_fields:populate_group' that * Create custom fields from a yml file. */ class CreateFieldsOnGroupCommand extends Command { - public const ARG_DELETE = 'delete'; + final public const ARG_DELETE = 'delete'; - public const ARG_PATH = 'path'; - - private $availableLanguages; - - /** - * @var CustomFieldProvider - */ - private $customFieldProvider; - - private $customizablesEntities; - - /** - * @var EntityManager - */ - private $entityManager; - - /** - * @var ValidatorInterface - */ - private $validator; + final public const ARG_PATH = 'path'; /** * CreateFieldsOnGroupCommand constructor. - * - * @param $availableLanguages - * @param $customizablesEntities */ public function __construct( - CustomFieldProvider $customFieldProvider, - EntityManager $entityManager, - ValidatorInterface $validator, - $availableLanguages, - $customizablesEntities + private readonly CustomFieldProvider $customFieldProvider, + private readonly EntityManager $entityManager, + private readonly ValidatorInterface $validator, + private $availableLanguages, + private $customizablesEntities ) { - $this->customFieldProvider = $customFieldProvider; - $this->entityManager = $entityManager; - $this->validator = $validator; - $this->availableLanguages = $availableLanguages; - $this->customizablesEntities = $customizablesEntities; parent::__construct(); } @@ -109,10 +79,7 @@ class CreateFieldsOnGroupCommand extends Command } } - /** - * @return int|void|null - */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $helper = $this->getHelperSet()->get('question'); @@ -122,9 +89,9 @@ class CreateFieldsOnGroupCommand extends Command ->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class) ->findAll(); - if (count($customFieldsGroups) === 0) { + if (0 === \count($customFieldsGroups)) { $output->writeln('There aren\'t any CustomFieldsGroup recorded' - . ' Please create at least one.'); + .' Please create at least one.'); } $table = new Table($output); @@ -147,7 +114,7 @@ class CreateFieldsOnGroupCommand extends Command } } - throw new RuntimeException('The id does not match an existing CustomFieldsGroup'); + throw new \RuntimeException('The id does not match an existing CustomFieldsGroup'); } ); $customFieldsGroup = $helper->ask($input, $output, $question); @@ -162,6 +129,8 @@ class CreateFieldsOnGroupCommand extends Command ); $fields = $this->_addFields($customFieldsGroup, $fieldsInput, $output); + + return 0; } private function _addFields(CustomFieldsGroup $group, $values, OutputInterface $output) @@ -171,12 +140,11 @@ class CreateFieldsOnGroupCommand extends Command $languages = $this->availableLanguages; foreach ($values['fields'] as $slug => $field) { - //check the cf type exists + // check the cf type exists $cfType = $this->customFieldProvider->getCustomFieldByType($field['type']); if (null === $cfType) { - throw new RuntimeException('the type ' . $field['type'] . ' ' - . 'does not exists'); + throw new \RuntimeException('the type '.$field['type'].' does not exists'); } $cf = new CustomField(); @@ -187,21 +155,21 @@ class CreateFieldsOnGroupCommand extends Command ->setType($field['type']) ->setCustomFieldsGroup($group); - //add to table + // add to table $names = []; foreach ($languages as $lang) { - //todo replace with service to find lang when available + // todo replace with service to find lang when available $names[] = $cf->getName()[$lang] ?? 'Not available in this language'; } if ($this->validator->validate($cf)) { $em->persist($cf); $output->writeln('Adding Custom Field of type ' - . $cf->getType() . "\t with slug " . $cf->getSlug() . - "\t and names : " . implode(', ', $names) . ''); + .$cf->getType()."\t with slug ".$cf->getSlug(). + "\t and names : ".implode(', ', $names).''); } else { - throw new RuntimeException('Error in field ' . $slug); + throw new \RuntimeException('Error in field '.$slug); } } @@ -213,13 +181,13 @@ class CreateFieldsOnGroupCommand extends Command $parser = new Parser(); if (!file_exists($path)) { - throw new RuntimeException('file does not exist'); + throw new \RuntimeException('file does not exist'); } try { $values = $parser->parse(file_get_contents($path)); } catch (ParseException $ex) { - throw new RuntimeException('The yaml file is not valid', 0, $ex); + throw new \RuntimeException('The yaml file is not valid', 0, $ex); } return $values; @@ -229,7 +197,7 @@ class CreateFieldsOnGroupCommand extends Command { $rows = []; $languages = $this->availableLanguages; - //gather entitites and create an array to access them easily + // gather entitites and create an array to access them easily $customizableEntities = []; foreach ($this->customizablesEntities as $entry) { @@ -239,14 +207,14 @@ class CreateFieldsOnGroupCommand extends Command array_walk( $customFieldsGroups, static function (CustomFieldsGroup $customFieldGroup, $key) use ($languages, &$rows, $customizableEntities) { - //set id and entity + // set id and entity $row = [ $customFieldGroup->getId(), $customizableEntities[$customFieldGroup->getEntity()], ]; foreach ($languages as $lang) { - //todo replace with service to find lang when available + // todo replace with service to find lang when available $row[] = $customFieldGroup->getName()[$lang] ?? 'Not available in this language'; } $rows[] = $row; diff --git a/src/Bundle/ChillCustomFieldsBundle/Controller/AdminController.php b/src/Bundle/ChillCustomFieldsBundle/Controller/AdminController.php index 1813dd7b3..eda55bb87 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Controller/AdminController.php +++ b/src/Bundle/ChillCustomFieldsBundle/Controller/AdminController.php @@ -12,6 +12,8 @@ declare(strict_types=1); namespace Chill\CustomFieldsBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; /** * Class AdminController @@ -19,8 +21,11 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; */ class AdminController extends AbstractController { - public function indexAction() + /** + * @Route("/{_locale}/admin/customfield/", name="customfield_section") + */ + public function indexAction(): Response { - return $this->render('ChillCustomFieldsBundle:Admin:layout.html.twig'); + return $this->render('@ChillCustomFields/Admin/layout.html.twig'); } } diff --git a/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php b/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php index 25e4d2359..3bba08b01 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php +++ b/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldController.php @@ -17,6 +17,7 @@ use Chill\CustomFieldsBundle\Form\CustomFieldType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Annotation\Route; /** * Class CustomFieldController. @@ -25,6 +26,8 @@ class CustomFieldController extends AbstractController { /** * Creates a new CustomField entity. + * + * @Route("/{_locale}/admin/customfield/new", name="customfield_new") */ public function createAction(Request $request) { @@ -32,7 +35,7 @@ class CustomFieldController extends AbstractController $form = $this->createCreateForm($entity, $request->query->get('type', null)); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); @@ -40,16 +43,13 @@ class CustomFieldController extends AbstractController $this->addFlash('success', $this->get('translator') ->trans('The custom field has been created')); - return $this->redirect($this->generateUrl( - 'customfieldsgroup_show', - ['id' => $entity->getCustomFieldsGroup()->getId()] - )); + return $this->redirectToRoute('customfieldsgroup_show', ['id' => $entity->getCustomFieldsGroup()->getId()]); } $this->addFlash('error', $this->get('translator') ->trans('The custom field form contains errors')); - return $this->render('ChillCustomFieldsBundle:CustomField:new.html.twig', [ + return $this->render('@ChillCustomFields/CustomField/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -58,9 +58,9 @@ class CustomFieldController extends AbstractController /** * Displays a form to edit an existing CustomField entity. * - * @param mixed $id + * @Route("/{_locale}/admin/customfield/edit", name="customfield_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -72,7 +72,7 @@ class CustomFieldController extends AbstractController $editForm = $this->createEditForm($entity, $entity->getType()); - return $this->render('ChillCustomFieldsBundle:CustomField:edit.html.twig', [ + return $this->render('@ChillCustomFields/CustomField/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -80,12 +80,14 @@ class CustomFieldController extends AbstractController /** * Displays a form to create a new CustomField entity. + * + * @Route("/{_locale}/admin/customfield/new", name="customfield_new") */ public function newAction(Request $request) { $entity = new CustomField(); - //add the custom field group if defined in URL + // add the custom field group if defined in URL $cfGroupId = $request->query->get('customFieldsGroup', null); if (null !== $cfGroupId) { @@ -94,47 +96,25 @@ class CustomFieldController extends AbstractController ->find($cfGroupId); if (!$cfGroup) { - throw $this->createNotFoundException('CustomFieldsGroup with id ' - . $cfGroupId . ' is not found !'); + throw $this->createNotFoundException('CustomFieldsGroup with id '.$cfGroupId.' is not found !'); } $entity->setCustomFieldsGroup($cfGroup); } $form = $this->createCreateForm($entity, $request->query->get('type')); - return $this->render('ChillCustomFieldsBundle:CustomField:new.html.twig', [ + return $this->render('@ChillCustomFields/CustomField/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); } - /** - * Finds and displays a CustomField entity. - * - * @deprecated is not used since there is no link to show action - * - * @param mixed $id - */ - public function showAction($id) - { - $em = $this->getDoctrine()->getManager(); - - $entity = $em->getRepository(CustomField::class)->find($id); - - if (!$entity) { - throw $this->createNotFoundException('Unable to find CustomField entity.'); - } - - return $this->render('ChillCustomFieldsBundle:CustomField:show.html.twig', [ - 'entity' => $entity, ]); - } - /** * Edits an existing CustomField entity. * - * @param mixed $id + * @Route("/{_locale}/admin/customfield/update", name="customfield_update") */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -147,19 +127,19 @@ class CustomFieldController extends AbstractController $editForm = $this->createEditForm($entity, $entity->getType()); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); $this->addFlash('success', $this->get('translator') ->trans('The custom field has been updated')); - return $this->redirect($this->generateUrl('customfield_edit', ['id' => $id])); + return $this->redirectToRoute('customfield_edit', ['id' => $id]); } $this->addFlash('error', $this->get('translator') ->trans('The custom field form contains errors')); - return $this->render('ChillCustomFieldsBundle:CustomField:edit.html.twig', [ + return $this->render('@ChillCustomFields/CustomField/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -168,13 +148,9 @@ class CustomFieldController extends AbstractController /** * Creates a form to create a CustomField entity. * - * @param CustomField $entity The entity - * @param string - * @param mixed $type - * * @return \Symfony\Component\Form\Form The form */ - private function createCreateForm(CustomField $entity, $type) + private function createCreateForm(CustomField $entity, mixed $type) { $form = $this->createForm(CustomFieldType::class, $entity, [ 'action' => $this->generateUrl( @@ -195,11 +171,10 @@ class CustomFieldController extends AbstractController * Creates a form to edit a CustomField entity. * * @param CustomField $entity The entity - * @param mixed $type * * @return \Symfony\Component\Form\Form The form */ - private function createEditForm(CustomField $entity, $type) + private function createEditForm(CustomField $entity, mixed $type) { $form = $this->createForm(CustomFieldType::class, $entity, [ 'action' => $this->generateUrl('customfield_update', ['id' => $entity->getId()]), diff --git a/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php b/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php index 4f180549a..829ca5c55 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php +++ b/src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php @@ -25,37 +25,23 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Annotation\Route; use Symfony\Contracts\Translation\TranslatorInterface; -use function in_array; /** * Class CustomFieldsGroupController. */ class CustomFieldsGroupController extends AbstractController { - /** - * @var CustomFieldProvider - */ - private $customfieldProvider; - - /** - * @var TranslatorInterface - */ - private $translator; - /** * CustomFieldsGroupController constructor. */ - public function __construct( - CustomFieldProvider $customFieldProvider, - TranslatorInterface $translator - ) { - $this->customfieldProvider = $customFieldProvider; - $this->translator = $translator; - } + public function __construct(private readonly CustomFieldProvider $customFieldProvider, private readonly TranslatorInterface $translator) {} /** * Creates a new CustomFieldsGroup entity. + * + * @Route("/{_locale}/admin/customfieldsgroup/create", name="customfieldsgroup_create") */ public function createAction(Request $request) { @@ -63,7 +49,7 @@ class CustomFieldsGroupController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); @@ -71,13 +57,13 @@ class CustomFieldsGroupController extends AbstractController $this->addFlash('success', $this->translator ->trans('The custom fields group has been created')); - return $this->redirect($this->generateUrl('customfieldsgroup_show', ['id' => $entity->getId()])); + return $this->redirectToRoute('customfieldsgroup_show', ['id' => $entity->getId()]); } $this->addFlash('error', $this->translator ->trans('The custom fields group form contains errors')); - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:new.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -86,9 +72,9 @@ class CustomFieldsGroupController extends AbstractController /** * Displays a form to edit an existing CustomFieldsGroup entity. * - * @param mixed $id + * @Route("/{_locale}/admin/customfieldsgroup/{id}/edit", name="customfieldsgroup_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -100,7 +86,7 @@ class CustomFieldsGroupController extends AbstractController $editForm = $this->createEditForm($entity); - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -108,6 +94,8 @@ class CustomFieldsGroupController extends AbstractController /** * Lists all CustomFieldsGroup entities. + * + * @Route("/{_locale}/admin/customfieldsgroup/", name="customfieldsgroup") */ public function indexAction() { @@ -119,12 +107,12 @@ class CustomFieldsGroupController extends AbstractController $makeDefaultFormViews = []; foreach ($cfGroups as $group) { - if (!in_array($group->getId(), $defaultGroups, true)) { + if (!\in_array($group->getId(), $defaultGroups, true)) { $makeDefaultFormViews[$group->getId()] = $this->createMakeDefaultForm($group)->createView(); } } - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:index.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/index.html.twig', [ 'entities' => $cfGroups, 'default_groups' => $defaultGroups, 'make_default_forms' => $makeDefaultFormViews, @@ -133,6 +121,8 @@ class CustomFieldsGroupController extends AbstractController /** * Set the CustomField Group with id $cFGroupId as default. + * + * @Route("/{_locale}/admin/customfieldsgroup/makedefault", name="customfieldsgroup_makedefault") */ public function makeDefaultAction(Request $request) { @@ -146,9 +136,7 @@ class CustomFieldsGroupController extends AbstractController $cFGroup = $em->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class)->findOneById($cFGroupId); if (!$cFGroup) { - throw $this - ->createNotFoundException('customFieldsGroup not found with ' - . "id {$cFGroupId}"); + throw $this->createNotFoundException('customFieldsGroup not found with '."id {$cFGroupId}"); } $cFDefaultGroup = $em->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup::class) @@ -173,18 +161,20 @@ class CustomFieldsGroupController extends AbstractController $this->addFlash('success', $this->translator ->trans('The default custom fields group has been changed')); - return $this->redirect($this->generateUrl('customfieldsgroup')); + return $this->redirectToRoute('customfieldsgroup'); } /** * Displays a form to create a new CustomFieldsGroup entity. + * + * @Route("/{_locale}/admin/customfieldsgroup/new", name="customfieldsgroup_new") */ public function newAction() { $entity = new CustomFieldsGroup(); $form = $this->createCreateForm($entity); - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:new.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -217,20 +207,20 @@ class CustomFieldsGroupController extends AbstractController $this->get('twig.loader') ->addPath( - __DIR__ . '/../Tests/Fixtures/App/app/Resources/views/', + __DIR__.'/../Tests/Fixtures/App/app/Resources/views/', $namespace = 'test' ); if ($form->isSubmitted()) { if ($form->get('submit_render')->isClicked()) { - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:render_for_test.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/render_for_test.html.twig', [ 'fields' => $form->getData(), 'customFieldsGroup' => $entity, ]); } - //dump($form->getData()); - //dump(json_enccode($form->getData())); + // dump($form->getData()); + // dump(json_enccode($form->getData())); } return $this @@ -242,9 +232,9 @@ class CustomFieldsGroupController extends AbstractController /** * Finds and displays a CustomFieldsGroup entity. * - * @param mixed $id + * @Route("/{_locale}/admin/customfieldsgroup/{id}/show", name="customfieldsgroup/show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -256,7 +246,7 @@ class CustomFieldsGroupController extends AbstractController $options = $this->getOptionsAvailable($entity->getEntity()); - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:show.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/show.html.twig', [ 'entity' => $entity, 'create_field_form' => $this->createCreateFieldForm($entity)->createView(), 'options' => $options, @@ -266,9 +256,9 @@ class CustomFieldsGroupController extends AbstractController /** * Edits an existing CustomFieldsGroup entity. * - * @param mixed $id + * @Route("/{_locale}/admin/customfieldsgroup/{id}/update", name="customfieldsgroup/update") */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -281,19 +271,19 @@ class CustomFieldsGroupController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); $this->addFlash('success', $this->translator ->trans('The custom fields group has been updated')); - return $this->redirect($this->generateUrl('customfieldsgroup_edit', ['id' => $id])); + return $this->redirectToRoute('customfieldsgroup_edit', ['id' => $id]); } $this->addFlash('error', $this->translator ->trans('The custom fields group form contains errors')); - return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', [ + return $this->render('@ChillCustomFields/CustomFieldsGroup/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -303,8 +293,7 @@ class CustomFieldsGroupController extends AbstractController { $fieldChoices = []; - foreach ($this->customfieldProvider->getAllFields() - as $key => $customType) { + foreach ($this->customFieldProvider->getAllFields() as $key => $customType) { $fieldChoices[$key] = $customType->getName(); } @@ -370,11 +359,9 @@ class CustomFieldsGroupController extends AbstractController /** * create a form to make the group default. * - * @param CustomFieldsGroup $group - * * @return \Symfony\Component\Form\Form */ - private function createMakeDefaultForm(?CustomFieldsGroup $group = null) + private function createMakeDefaultForm(CustomFieldsGroup $group = null) { return $this->createFormBuilder($group, [ 'method' => 'POST', @@ -396,8 +383,8 @@ class CustomFieldsGroupController extends AbstractController $em = $this->getDoctrine()->getManager(); $customFieldsGroupIds = $em->createQuery('SELECT g.id FROM ' - . 'ChillCustomFieldsBundle:CustomFieldsDefaultGroup d ' - . 'JOIN d.customFieldsGroup g') + .'ChillCustomFieldsBundle:CustomFieldsDefaultGroup d ' + .'JOIN d.customFieldsGroup g') ->getResult(Query::HYDRATE_SCALAR); $result = []; @@ -418,7 +405,7 @@ class CustomFieldsGroupController extends AbstractController private function getOptionsAvailable($entity) { $options = $this->getParameter('chill_custom_fields.' - . 'customizables_entities'); + .'customizables_entities'); foreach ($options as $key => $definition) { if ($definition['class'] === $entity) { diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php index 781b2b233..8fd91f27d 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldChoice.php @@ -18,54 +18,32 @@ use Chill\CustomFieldsBundle\Form\Type\ChoicesType; use Chill\CustomFieldsBundle\Form\Type\ChoiceWithOtherType; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Chill\MainBundle\Templating\TranslatableStringHelper; -use LogicException; -use Symfony\Bridge\Twig\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Contracts\Translation\TranslatorInterface; - -use function array_key_exists; -use function count; -use function in_array; -use function is_array; -use function LogicException; +use Twig\Environment; class CustomFieldChoice extends AbstractCustomField { - public const ALLOW_OTHER = 'other'; + final public const ALLOW_OTHER = 'other'; - public const CHOICES = 'choices'; + final public const CHOICES = 'choices'; - public const EXPANDED = 'expanded'; + final public const EXPANDED = 'expanded'; - public const MULTIPLE = 'multiple'; + final public const MULTIPLE = 'multiple'; - public const OTHER_VALUE_LABEL = 'otherValueLabel'; - - private $defaultLocales; - - /** - * @var TwigEngine - */ - private $templating; - - /** - * @var TranslatableStringHelper Helper that find the string in current locale from an array of translation - */ - private $translatableStringHelper; + final public const OTHER_VALUE_LABEL = 'otherValueLabel'; /** * CustomFieldChoice constructor. */ public function __construct( - TranslatorInterface $translator, - TwigEngine $templating, - TranslatableStringHelper $translatableStringHelper - ) { - $this->defaultLocales = $translator->getFallbackLocales(); - $this->templating = $templating; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly Environment $templating, + /** + * @var TranslatableStringHelper Helper that find the string in current locale from an array of translation + */ + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function allowOtherChoice(CustomField $cf) { @@ -74,7 +52,7 @@ class CustomFieldChoice extends AbstractCustomField public function buildForm(FormBuilderInterface $builder, CustomField $customField) { - //prepare choices + // prepare choices $choices = []; $customFieldOptions = $customField->getOptions(); @@ -84,7 +62,7 @@ class CustomFieldChoice extends AbstractCustomField } } - //prepare $options + // prepare $options $options = [ 'multiple' => $customFieldOptions[self::MULTIPLE], 'choices' => array_combine(array_values($choices), array_keys($choices)), @@ -92,11 +70,11 @@ class CustomFieldChoice extends AbstractCustomField 'label' => $this->translatableStringHelper->localize($customField->getName()), ]; - //if allow_other = true + // if allow_other = true if (true === $customFieldOptions[self::ALLOW_OTHER]) { $otherValueLabel = null; - if (array_key_exists(self::OTHER_VALUE_LABEL, $customFieldOptions)) { + if (\array_key_exists(self::OTHER_VALUE_LABEL, $customFieldOptions)) { $otherValueLabel = $this->translatableStringHelper->localize( $customFieldOptions[self::OTHER_VALUE_LABEL] ); @@ -112,8 +90,8 @@ class CustomFieldChoice extends AbstractCustomField ) ->addModelTransformer(new CustomFieldDataTransformer($this, $customField)) ); - } else { //if allow_other = false - //we add the 'expanded' to options + } else { // if allow_other = false + // we add the 'expanded' to options $options['expanded'] = $customFieldOptions[self::EXPANDED]; $builder->add( @@ -177,7 +155,7 @@ class CustomFieldChoice extends AbstractCustomField return $serialized; } - public function extractOtherValue(CustomField $cf, ?array $data = null) + public function extractOtherValue(CustomField $cf, array $data = null) { return $data['_other']; } @@ -198,7 +176,7 @@ class CustomFieldChoice extends AbstractCustomField if ($this->allowOtherChoice($cf)) { $labels = $cf->getOptions()[self::OTHER_VALUE_LABEL]; - if (!is_array($labels) || count($labels) === 0) { + if (!\is_array($labels) || 0 === \count($labels)) { $labels['back'] = 'other value'; } $choices['_other'] = $this->translatableStringHelper @@ -223,12 +201,12 @@ class CustomFieldChoice extends AbstractCustomField * * Used in list exports. * - * @param string $choiceSlug the slug of the choice we want to know if it was checked - * @param array|string $data the data of the field + * @param string $choiceSlug the slug of the choice we want to know if it was checked + * @param array|string $data the data of the field * * @return bool */ - public function isChecked(CustomField $cf, $choiceSlug, $data) + public function isChecked(CustomField $cf, $choiceSlug, array|string $data) { if (null === $data) { return false; @@ -236,10 +214,10 @@ class CustomFieldChoice extends AbstractCustomField if ($cf->getOptions()[self::MULTIPLE]) { if ($cf->getOptions()[self::ALLOW_OTHER]) { - return in_array($choiceSlug, $this->deserialize($data, $cf)['_choices'], true); + return \in_array($choiceSlug, $this->deserialize($data, $cf)['_choices'], true); } - return in_array($choiceSlug, $this->deserialize($data, $cf), true); + return \in_array($choiceSlug, $this->deserialize($data, $cf), true); } if ($cf->getOptions()[self::ALLOW_OTHER]) { @@ -256,9 +234,9 @@ class CustomFieldChoice extends AbstractCustomField } // if multiple choice OR multiple/single choice with other - if (is_array($value)) { + if (\is_array($value)) { // if allow other - if (array_key_exists('_choices', $value)) { + if (\array_key_exists('_choices', $value)) { if (null === $value['_choices']) { return true; } @@ -266,7 +244,7 @@ class CustomFieldChoice extends AbstractCustomField return empty($value['_choices']); } // we do not have 'allow other' - if (count($value) === 1) { + if (1 === \count($value)) { return empty($value[0]); } @@ -275,7 +253,7 @@ class CustomFieldChoice extends AbstractCustomField return empty($value); - throw LogicException('This case is not expected.'); + throw \LogicException('This case is not expected.'); } public function isMultiple(CustomField $cf) @@ -286,23 +264,20 @@ class CustomFieldChoice extends AbstractCustomField /** * @internal this function is able to receive data whichever is the value of "other", "multiple" * - * @param mixed $value - * @param mixed $documentType - * * @return string html representation */ public function render($value, CustomField $customField, $documentType = 'html') { - //extract the data. They are under a _choice key if they are stored with allow_other + // extract the data. They are under a _choice key if they are stored with allow_other $data = $value['_choices'] ?? $value; - $selected = (is_array($data)) ? $data : [$data]; + $selected = (\is_array($data)) ? $data : [$data]; $choices = $customField->getOptions()[self::CHOICES]; - if (in_array('_other', $selected, true)) { + if (\in_array('_other', $selected, true)) { $choices[] = ['name' => $value['_other'], 'slug' => '_other']; } - $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:choice.html.twig'; + $template = '@ChillCustomFields/CustomFieldsRendering/choice.html.twig'; if ('csv' === $documentType) { $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:choice.csv.twig'; @@ -316,7 +291,6 @@ class CustomFieldChoice extends AbstractCustomField 'selected' => $selected, 'multiple' => $customField->getOptions()[self::MULTIPLE], 'expanded' => $customField->getOptions()[self::EXPANDED], - 'locales' => $this->defaultLocales, ] ); } @@ -330,15 +304,14 @@ class CustomFieldChoice extends AbstractCustomField * deserialized the data from the database to a multiple * field. * - * @param mixed $serialized * @param bool $allowOther */ - private function deserializeToMultiple($serialized, $allowOther) + private function deserializeToMultiple(mixed $serialized, $allowOther) { $value = $this->guessValue($serialized); // set in an array : we want a multiple - $fixedValue = is_array($value) ? $value : [$value]; + $fixedValue = \is_array($value) ? $value : [$value]; if ($allowOther) { return $this->deserializeWithAllowOther($serialized, $fixedValue); @@ -352,9 +325,9 @@ class CustomFieldChoice extends AbstractCustomField $value = $this->guessValue($serialized); // set in a single value. We must have a single string - $fixedValue = is_array($value) ? + $fixedValue = \is_array($value) ? // check if the array has an element, if not replace by empty string - count($value) > 0 ? end($value) : '' + \count($value) > 0 ? end($value) : '' : $value; @@ -380,29 +353,24 @@ class CustomFieldChoice extends AbstractCustomField * * If the value had an 'allow_other' = true option, the returned value * **is not** the content of the _other field, but the `_other` string. - * - * @param array|string $value - * - * @throws LogicException if the case is not covered by this - * - * @return mixed */ - private function guessValue($value) + private function guessValue(null|array|string $value) { if (null === $value) { return null; } - if (!is_array($value)) { + if (!\is_array($value)) { return $value; } // we have a field with "allow other" - if (array_key_exists('_choices', $value)) { + if (\array_key_exists('_choices', $value)) { return $value['_choices']; } + // we have a field with "multiple" return $value; - throw LogicException('This case is not expected.'); + throw \LogicException('This case is not expected.'); } } diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php index 218bd5415..a535f805e 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldDate.php @@ -15,14 +15,12 @@ use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Templating\TranslatableStringHelper; -use DateTime; -use Exception; -use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Twig\Environment; /** * Create a custom date number. @@ -33,32 +31,21 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; */ class CustomFieldDate extends AbstractCustomField { - public const DATE_FORMAT = DateTime::RFC3339; + final public const DATE_FORMAT = \DateTime::RFC3339; - public const FORMAT = 'format'; + final public const FORMAT = 'format'; - public const MAX = 'max'; + final public const MAX = 'max'; /** * key for the minimal value of the field. */ - public const MIN = 'min'; + final public const MIN = 'min'; - /** - * @var TwigEngine - */ - private $templating; - - /** - * @var TranslatableStringHelper - */ - private $translatableStringHelper; - - public function __construct(TwigEngine $templating, TranslatableStringHelper $translatableStringHelper) - { - $this->templating = $templating; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly Environment $templating, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function buildForm(FormBuilderInterface $builder, CustomField $customField) { @@ -81,8 +68,8 @@ class CustomFieldDate extends AbstractCustomField { $validatorFunction = static function ($value, ExecutionContextInterface $context) { try { - $date = new DateTime($value); - } catch (Exception $e) { + $date = new \DateTime($value); + } catch (\Exception) { $context->buildViolation('The expression "%expression%" is invalid', [ '%expression%' => $value, ]) @@ -117,7 +104,7 @@ class CustomFieldDate extends AbstractCustomField return null; } - return DateTime::createFromFormat(self::DATE_FORMAT, $serialized); + return \DateTime::createFromFormat(self::DATE_FORMAT, $serialized); } public function getName() @@ -139,7 +126,7 @@ class CustomFieldDate extends AbstractCustomField default: $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:date.' - . $documentType . '.twig'; + .$documentType.'.twig'; return $this->templating ->render($template, [ @@ -175,7 +162,7 @@ class CustomFieldDate extends AbstractCustomField // add required $fieldOptions['required'] = false; - //add label + // add label $fieldOptions['label'] = $this->translatableStringHelper->localize($customField->getName()); // add constraints if required @@ -186,8 +173,8 @@ class CustomFieldDate extends AbstractCustomField return; } - $value = DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); - $after = new DateTime($options[self::MIN]); + $value = \DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); + $after = new \DateTime($options[self::MIN]); if ($value < $after) { $context @@ -207,8 +194,8 @@ class CustomFieldDate extends AbstractCustomField return; } - $value = DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); - $before = new DateTime($options[self::MAX]); + $value = \DateTime::createFromFormat(self::DATE_FORMAT, $timestamp); + $before = new \DateTime($options[self::MAX]); if ($value > $before) { $context diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php index 43902a7e3..ff89c04d2 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldInterface.php @@ -21,7 +21,7 @@ interface CustomFieldInterface * user. * * @param \Chill\CustomFieldsBundle\CustomField\FormBuilderInterface $builder - * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField + * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField * * @return \Symfony\Component\Form\FormTypeInterface the form type */ @@ -42,7 +42,6 @@ interface CustomFieldInterface * value which may be used in the process. * * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField - * @param mixed $serialized */ public function deserialize($serialized, CustomField $customField); @@ -58,9 +57,8 @@ interface CustomFieldInterface /** * Return a repsentation of the value of the CustomField. * - * @param mixed $value the raw value, **not deserialized** (= as stored in the db) + * @param mixed $value the raw value, **not deserialized** (= as stored in the db) * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField - * @param mixed $documentType * * @return string an html representation of the value */ @@ -69,7 +67,6 @@ interface CustomFieldInterface /** * Transform the value into a format that can be stored in DB. * - * @param mixed $value * @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField */ public function serialize($value, CustomField $customField); diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php index 75dc7792f..885a02f2d 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldLongChoice.php @@ -17,34 +17,18 @@ use Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionReposi use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer; use Chill\MainBundle\Form\Type\Select2ChoiceType; use Chill\MainBundle\Templating\TranslatableStringHelper; -use LogicException; -use Symfony\Bridge\Twig\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; -use function get_class; -use function gettype; -use function is_object; - class CustomFieldLongChoice extends AbstractCustomField { - public const KEY = 'key'; - - private OptionRepository $optionRepository; - - private TwigEngine $templating; - - private TranslatableStringHelper $translatableStringHelper; + final public const KEY = 'key'; public function __construct( - OptionRepository $optionRepository, - TranslatableStringHelper $translatableStringHelper, - TwigEngine $twigEngine - ) { - $this->optionRepository = $optionRepository; - $this->translatableStringHelper = $translatableStringHelper; - $this->templating = $twigEngine; - } + private readonly OptionRepository $optionRepository, + private readonly TranslatableStringHelper $translatableStringHelper, + private readonly \Twig\Environment $templating, + ) {} public function buildForm(FormBuilderInterface $builder, CustomField $customField) { @@ -54,7 +38,7 @@ class CustomFieldLongChoice extends AbstractCustomField false, true ); - //create a local copy of translatable string helper + // create a local copy of translatable string helper $translatableStringHelper = $this->translatableStringHelper; $builder->add($customField->getSlug(), Select2ChoiceType::class, [ 'choices' => $entries, @@ -81,7 +65,7 @@ class CustomFieldLongChoice extends AbstractCustomField public function buildOptionsForm(FormBuilderInterface $builder) { - //create a selector between different keys + // create a selector between different keys $keys = $this->optionRepository->getKeys(); $choices = []; @@ -113,7 +97,7 @@ class CustomFieldLongChoice extends AbstractCustomField { $option = $this->deserialize($value, $customField); $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:choice_long.' - . $documentType . '.twig'; + .$documentType.'.twig'; return $this->templating ->render($template, [ @@ -128,9 +112,7 @@ class CustomFieldLongChoice extends AbstractCustomField } if (!$value instanceof Option) { - throw new LogicException('the value should be an instance of ' - . 'Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option, ' - . is_object($value) ? get_class($value) : gettype($value) . ' given'); + throw new \LogicException('the value should be an instance of Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option, '.\is_object($value) ? $value::class : \gettype($value).' given'); } // we place the id in array, to allow in the future multiple select diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php index 82b35f9f5..979d96540 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldNumber.php @@ -13,13 +13,13 @@ namespace Chill\CustomFieldsBundle\CustomFields; use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; use Symfony\Component\Validator\Constraints\LessThanOrEqual; +use Twig\Environment; /** * Create a custom field number. @@ -28,41 +28,30 @@ use Symfony\Component\Validator\Constraints\LessThanOrEqual; */ class CustomFieldNumber extends AbstractCustomField { - public const MAX = 'max'; + final public const MAX = 'max'; /** * key for the minimal value of the field. */ - public const MIN = 'min'; + final public const MIN = 'min'; - public const POST_TEXT = 'post_text'; + final public const POST_TEXT = 'post_text'; - public const SCALE = 'scale'; + final public const SCALE = 'scale'; - /** - * @var TwigEngine - */ - private $templating; - - /** - * @var TranslatableStringHelper - */ - private $translatableStringHelper; - - public function __construct(TwigEngine $templating, TranslatableStringHelper $translatableStringHelper) - { - $this->templating = $templating; - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct( + private readonly Environment $templating, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function buildForm(FormBuilderInterface $builder, CustomField $customField) { $options = $customField->getOptions(); - //select the type depending to the SCALE + // select the type depending to the SCALE $type = (0 === $options[self::SCALE] || null === $options[self::SCALE]) ? IntegerType::class : NumberType::class; - //'integer' : 'number'; + // 'integer' : 'number'; $fieldOptions = $this->prepareFieldOptions($customField, $type); @@ -107,7 +96,7 @@ class CustomFieldNumber extends AbstractCustomField public function render($value, CustomField $customField, $documentType = 'html') { $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:number.' - . $documentType . '.twig'; + .$documentType.'.twig'; $options = $customField->getOptions(); return $this->templating @@ -142,7 +131,7 @@ class CustomFieldNumber extends AbstractCustomField // add required $fieldOptions['required'] = false; - //add label + // add label $fieldOptions['label'] = $this->translatableStringHelper->localize($customField->getName()); // add constraints if required diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php index 0a6efc2bc..f95048e21 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldText.php @@ -13,43 +13,23 @@ namespace Chill\CustomFieldsBundle\CustomFields; use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -use function array_key_exists; +use Twig\Environment; class CustomFieldText extends AbstractCustomField { - public const MAX_LENGTH = 'maxLength'; + final public const MAX_LENGTH = 'maxLength'; - public const MULTIPLE_CF_INLINE = 'multipleCFInline'; - - private $requestStack; - - /** - * @var TwigEngine - */ - private $templating; - - /** - * @var TranslatableStringHelper Helper that find the string in current locale from an array of translation - */ - private $translatableStringHelper; + final public const MULTIPLE_CF_INLINE = 'multipleCFInline'; public function __construct( - RequestStack $requestStack, - TwigEngine $templating, - TranslatableStringHelper $translatableStringHelper - ) { - $this->requestStack = $requestStack; - $this->templating = $templating; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly Environment $templating, + private readonly TranslatableStringHelper $translatableStringHelper + ) {} /** * Create a form according to the maxLength option. @@ -67,7 +47,7 @@ class CustomFieldText extends AbstractCustomField $attrArray = []; if ( - array_key_exists(self::MULTIPLE_CF_INLINE, $options) + \array_key_exists(self::MULTIPLE_CF_INLINE, $options) && $options[self::MULTIPLE_CF_INLINE] ) { $attrArray['class'] = 'multiple-cf-inline'; @@ -106,7 +86,7 @@ class CustomFieldText extends AbstractCustomField public function render($value, CustomField $customField, $documentType = 'html') { - $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:text.html.twig'; + $template = '@ChillCustomFields/CustomFieldsRendering/text.html.twig'; if ('csv' === $documentType) { $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:text.csv.twig'; diff --git a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php index b22b84029..302e04350 100644 --- a/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php +++ b/src/Bundle/ChillCustomFieldsBundle/CustomFields/CustomFieldTitle.php @@ -14,40 +14,25 @@ namespace Chill\CustomFieldsBundle\CustomFields; use Chill\CustomFieldsBundle\Entity\CustomField; use Chill\CustomFieldsBundle\Form\Type\CustomFieldsTitleType; use Chill\MainBundle\Templating\TranslatableStringHelper; -use Symfony\Bundle\TwigBundle\TwigEngine; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\HttpFoundation\RequestStack; +use Twig\Environment; class CustomFieldTitle extends AbstractCustomField { - public const TYPE = 'type'; + final public const TYPE = 'type'; - public const TYPE_SUBTITLE = 'subtitle'; + final public const TYPE_SUBTITLE = 'subtitle'; - public const TYPE_TITLE = 'title'; - - private $requestStack; - - /** - * @var TwigEngine - */ - private $templating; - - /** - * @var TranslatableStringHelper Helper that find the string in current locale from an array of translation - */ - private $translatableStringHelper; + final public const TYPE_TITLE = 'title'; public function __construct( - RequestStack $requestStack, - TwigEngine $templating, - TranslatableStringHelper $translatableStringHelper - ) { - $this->requestStack = $requestStack; - $this->templating = $templating; - $this->translatableStringHelper = $translatableStringHelper; - } + private readonly Environment $templating, + /** + * @var TranslatableStringHelper Helper that find the string in current locale from an array of translation + */ + private readonly TranslatableStringHelper $translatableStringHelper + ) {} public function buildForm(FormBuilderInterface $builder, CustomField $customField) { @@ -95,7 +80,7 @@ class CustomFieldTitle extends AbstractCustomField { return $this->templating ->render( - 'ChillCustomFieldsBundle:CustomFieldsRendering:title.html.twig', + '@ChillCustomFields/CustomFieldsRendering/title.html.twig', [ 'title' => $customField->getName(), 'type' => $customField->getOptions()[self::TYPE], diff --git a/src/Bundle/ChillCustomFieldsBundle/DataFixtures/ORM/LoadOption.php b/src/Bundle/ChillCustomFieldsBundle/DataFixtures/ORM/LoadOption.php index 5b2598ab7..f95991b7c 100644 --- a/src/Bundle/ChillCustomFieldsBundle/DataFixtures/ORM/LoadOption.php +++ b/src/Bundle/ChillCustomFieldsBundle/DataFixtures/ORM/LoadOption.php @@ -37,7 +37,7 @@ class LoadOption extends AbstractFixture implements OrderedFixtureInterface */ public $fakerNl; - private $counter = 0; + private int $counter = 0; public function __construct() { @@ -73,7 +73,7 @@ class LoadOption extends AbstractFixture implements OrderedFixtureInterface ->setText($text) ->setParent($parent) ->setActive(true) - ->setInternalKey($parent->getKey() . '-' . $this->counter); + ->setInternalKey($parent->getKey().'-'.$this->counter); } private function loadingCompanies(ObjectManager $manager) @@ -103,7 +103,7 @@ class LoadOption extends AbstractFixture implements OrderedFixtureInterface ->setKey('company'); $manager->persist($parent); - //Load children + // Load children $expected_nb_children = random_int(10, 50); for ($i = 0; $i < $expected_nb_children; ++$i) { @@ -143,7 +143,7 @@ class LoadOption extends AbstractFixture implements OrderedFixtureInterface ->setKey('word'); $manager->persist($parent); - //Load children + // Load children $expected_nb_children = random_int(10, 50); for ($i = 0; $i < $expected_nb_children; ++$i) { diff --git a/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/ChillCustomFieldsExtension.php b/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/ChillCustomFieldsExtension.php index a90f770a4..724fd01ca 100644 --- a/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/ChillCustomFieldsExtension.php +++ b/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/ChillCustomFieldsExtension.php @@ -29,15 +29,15 @@ class ChillCustomFieldsExtension extends Extension implements PrependExtensionIn $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/fixtures.yaml'); $loader->load('services/controller.yaml'); $loader->load('services/command.yaml'); $loader->load('services/menu.yaml'); - //add at least a blank array at 'customizable_entities' options - //$customizable_entities = (isset($config['customizables_entities']) + // add at least a blank array at 'customizable_entities' options + // $customizable_entities = (isset($config['customizables_entities']) // && $config['customizables_entities'] !== FALSE) // ? $config['customizables_entities'] : array(); @@ -59,12 +59,12 @@ class ChillCustomFieldsExtension extends Extension implements PrependExtensionIn // add form layout to twig resources $twigConfig = [ 'form_themes' => [ - 'ChillCustomFieldsBundle:Form:fields.html.twig', + '@ChillCustomFields/Form/fields.html.twig', ], ]; $container->prependExtensionConfig('twig', $twigConfig); - //add routes for custom bundle + // add routes for custom bundle $container->prependExtensionConfig('chill_main', [ 'routing' => [ 'resources' => [ diff --git a/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/CustomFieldCompilerPass.php b/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/CustomFieldCompilerPass.php index 0cf1a67eb..6e68a248a 100644 --- a/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/CustomFieldCompilerPass.php +++ b/src/Bundle/ChillCustomFieldsBundle/DependencyInjection/CustomFieldCompilerPass.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\CustomFieldsBundle\DependencyInjection; -use LogicException; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -21,8 +20,7 @@ class CustomFieldCompilerPass implements CompilerPassInterface public function process(ContainerBuilder $container) { if (!$container->hasDefinition('chill.custom_field.provider')) { - throw new LogicException('service chill.custom_field.provider ' - . 'is not defined.'); + throw new \LogicException('service chill.custom_field.provider is not defined.'); } $definition = $container->getDefinition( diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php index d9f43ed3b..b75d23e5e 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php +++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php @@ -17,39 +17,37 @@ use Doctrine\ORM\Mapping as ORM; * CustomField. * * @ORM\Entity + * * @ORM\Table(name="customfield") + * * @ORM\HasLifecycleCallbacks */ class CustomField { - public const ONE_TO_MANY = 2; + final public const ONE_TO_MANY = 2; - public const ONE_TO_ONE = 1; + final public const ONE_TO_ONE = 1; /** - * @var bool - * * @ORM\Column(type="boolean") */ - private $active = true; + private bool $active = true; /** - * @var CustomFieldsGroup - * * @ORM\ManyToOne( * targetEntity="Chill\CustomFieldsBundle\Entity\CustomFieldsGroup", * inversedBy="customFields") */ - private $customFieldGroup; + private ?\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup $customFieldGroup = null; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** * @var array @@ -59,39 +57,29 @@ class CustomField private $name; /** - * @var array - * * @ORM\Column(type="json") */ - private $options = []; + private array $options = []; /** - * @var float - * * @ORM\Column(type="float") */ - private $ordering; + private ?float $ordering = null; /** - * @var bool - * * @ORM\Column(type="boolean") */ - private $required = false; + private false $required = false; /** - * @var string - * * @ORM\Column(type="string", length=255) */ - private $slug; + private ?string $slug = null; /** - * @var string - * * @ORM\Column(type="string", length=255) */ - private $type; + private ?string $type = null; /** * Get customFieldGroup. @@ -222,11 +210,9 @@ class CustomField /** * Set customFieldGroup. * - * @param CustomFieldsGroup $customFieldGroup - * * @return CustomField */ - public function setCustomFieldsGroup(?CustomFieldsGroup $customFieldGroup = null) + public function setCustomFieldsGroup(CustomFieldsGroup $customFieldGroup = null) { $this->customFieldGroup = $customFieldGroup; @@ -281,8 +267,6 @@ class CustomField } /** - * @param $slug - * * @return $this */ public function setSlug($slug) diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php index 08233886d..b6f371c8e 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php +++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php @@ -11,67 +11,71 @@ declare(strict_types=1); namespace Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity( * repositoryClass="Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionRepository") + * * @ORM\Table(name="custom_field_long_choice_options") */ class Option { /** - * @var bool * @ORM\Column(type="boolean") */ - private $active = true; + private bool $active = true; /** - * @var Collection + * @var Collection
    {% endblock %} diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php index 0ef1d4d49..5febc7e42 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php @@ -23,33 +23,25 @@ use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security; -use function in_array; - class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const CREATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE'; + final public const CREATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE'; - public const DELETE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE'; + final public const DELETE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE'; - public const SEE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE'; + final public const SEE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE'; - public const SEE_DETAILS = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS'; + final public const SEE_DETAILS = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS'; - public const UPDATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE'; - - protected LoggerInterface $logger; - - protected Security $security; + final public const UPDATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE'; protected VoterHelperInterface $voterHelper; public function __construct( - LoggerInterface $logger, - Security $security, + protected LoggerInterface $logger, + protected Security $security, VoterHelperFactoryInterface $voterHelperFactory ) { - $this->logger = $logger; - $this->security = $security; $this->voterHelper = $voterHelperFactory ->generate(self::class) ->addCheckFor(AccompanyingCourseDocument::class, $this->getRoles()) @@ -102,7 +94,7 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov if ( AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep() - && in_array($attribute, [self::CREATE, self::DELETE, self::UPDATE], true) + && \in_array($attribute, [self::CREATE, self::DELETE, self::UPDATE], true) ) { return false; } diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php index 059a2c7d9..21c08e9fd 100644 --- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php +++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/PersonDocumentVoter.php @@ -25,29 +25,23 @@ use Symfony\Component\Security\Core\Security; class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface { - public const CREATE = 'CHILL_PERSON_DOCUMENT_CREATE'; + final public const CREATE = 'CHILL_PERSON_DOCUMENT_CREATE'; - public const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE'; + final public const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE'; - public const SEE = 'CHILL_PERSON_DOCUMENT_SEE'; + final public const SEE = 'CHILL_PERSON_DOCUMENT_SEE'; - public const SEE_DETAILS = 'CHILL_PERSON_DOCUMENT_SEE_DETAILS'; + final public const SEE_DETAILS = 'CHILL_PERSON_DOCUMENT_SEE_DETAILS'; - public const UPDATE = 'CHILL_PERSON_DOCUMENT_UPDATE'; - - protected LoggerInterface $logger; - - protected Security $security; + final public const UPDATE = 'CHILL_PERSON_DOCUMENT_UPDATE'; protected VoterHelperInterface $voterHelper; public function __construct( - LoggerInterface $logger, - Security $security, + protected LoggerInterface $logger, + protected Security $security, VoterHelperFactoryInterface $voterHelperFactory ) { - $this->logger = $logger; - $this->security = $security; $this->voterHelper = $voterHelperFactory ->generate(self::class) ->addCheckFor(PersonDocument::class, $this->getRoles()) @@ -82,7 +76,7 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera } /** - * @param string $attribute + * @param string $attribute * @param PersonDocument $subject * * @return bool diff --git a/src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php b/src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php index c9829d3ee..2c96f7faa 100644 --- a/src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php +++ b/src/Bundle/ChillDocStoreBundle/Serializer/Normalizer/StoredObjectDenormalizer.php @@ -15,19 +15,12 @@ use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Repository\StoredObjectRepository; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait; -use function array_key_exists; -use function is_array; class StoredObjectDenormalizer implements DenormalizerInterface { use ObjectToPopulateTrait; - private StoredObjectRepository $storedObjectRepository; - - public function __construct(StoredObjectRepository $storedObjectRepository) - { - $this->storedObjectRepository = $storedObjectRepository; - } + public function __construct(private readonly StoredObjectRepository $storedObjectRepository) {} public function denormalize($data, $type, $format = null, array $context = []) { @@ -42,11 +35,11 @@ class StoredObjectDenormalizer implements DenormalizerInterface public function supportsDenormalization($data, $type, $format = null) { - if (false === is_array($data)) { + if (false === \is_array($data)) { return false; } - if (false === array_key_exists('id', $data)) { + if (false === \array_key_exists('id', $data)) { return false; } diff --git a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php index a1ef42ff1..34df98fa2 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php +++ b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php @@ -15,39 +15,21 @@ use Base64Url\Base64Url; use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Exception\StoredObjectManagerException; -use DateTimeImmutable; -use DateTimeInterface; -use DateTimeZone; -use RuntimeException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; - use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\ResponseInterface; -use Throwable; -use function array_key_exists; -use const OPENSSL_RAW_DATA; final class StoredObjectManager implements StoredObjectManagerInterface { private const ALGORITHM = 'AES-256-CBC'; - private HttpClientInterface $client; - private array $inMemory = []; - private TempUrlGeneratorInterface $tempUrlGenerator; + public function __construct(private readonly HttpClientInterface $client, private readonly TempUrlGeneratorInterface $tempUrlGenerator) {} - public function __construct( - HttpClientInterface $client, - TempUrlGeneratorInterface $tempUrlGenerator - ) { - $this->client = $client; - $this->tempUrlGenerator = $tempUrlGenerator; - } - - public function getLastModified(StoredObject $document): DateTimeInterface + public function getLastModified(StoredObject $document): \DateTimeInterface { if ($this->hasCache($document)) { $response = $this->getResponseFromCache($document); @@ -79,7 +61,7 @@ final class StoredObjectManager implements StoredObjectManagerInterface try { $data = $response->getContent(); - } catch (Throwable $e) { + } catch (\Throwable $e) { throw StoredObjectManagerException::unableToGetResponseContent($e); } @@ -92,7 +74,7 @@ final class StoredObjectManager implements StoredObjectManagerInterface self::ALGORITHM, // TODO: Why using this library and not use base64_decode() ? Base64Url::decode($document->getKeyInfos()['k']), - OPENSSL_RAW_DATA, + \OPENSSL_RAW_DATA, pack('C*', ...$document->getIv()) ); @@ -115,7 +97,7 @@ final class StoredObjectManager implements StoredObjectManagerInterface self::ALGORITHM, // TODO: Why using this library and not use base64_decode() ? Base64Url::decode($document->getKeyInfos()['k']), - OPENSSL_RAW_DATA, + \OPENSSL_RAW_DATA, pack('C*', ...$document->getIv()) ) : $clearContent; @@ -140,24 +122,23 @@ final class StoredObjectManager implements StoredObjectManagerInterface throw StoredObjectManagerException::errorDuringHttpRequest($exception); } - if ($response->getStatusCode() !== Response::HTTP_CREATED) { + if (Response::HTTP_CREATED !== $response->getStatusCode()) { throw StoredObjectManagerException::invalidStatusCode($response->getStatusCode()); } } - private function extractLastModifiedFromResponse(ResponseInterface $response): DateTimeImmutable + private function extractLastModifiedFromResponse(ResponseInterface $response): \DateTimeImmutable { $lastModifiedString = (($response->getHeaders()['last-modified'] ?? [])[0] ?? ''); - $date = DateTimeImmutable::createFromFormat( - DateTimeImmutable::RFC7231, + $date = \DateTimeImmutable::createFromFormat( + \DateTimeImmutable::RFC7231, $lastModifiedString, - new DateTimeZone('GMT') + new \DateTimeZone('GMT') ); if (false === $date) { - throw new RuntimeException('the date from remote storage could not be parsed: ' - . $lastModifiedString); + throw new \RuntimeException('the date from remote storage could not be parsed: '.$lastModifiedString); } return $date; @@ -178,11 +159,11 @@ final class StoredObjectManager implements StoredObjectManagerInterface ) ->url ); - } catch (Throwable $e) { + } catch (\Throwable $e) { throw StoredObjectManagerException::errorDuringHttpRequest($e); } - if ($response->getStatusCode() !== Response::HTTP_OK) { + if (Response::HTTP_OK !== $response->getStatusCode()) { throw StoredObjectManagerException::invalidStatusCode($response->getStatusCode()); } @@ -200,7 +181,7 @@ final class StoredObjectManager implements StoredObjectManagerInterface private function hasCache(StoredObject $document): bool { - return array_key_exists($document->getUuid()->toString(), $this->inMemory); + return \array_key_exists($document->getUuid()->toString(), $this->inMemory); } private function hasKeysAndIv(StoredObject $storedObject): bool diff --git a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php index caafb3937..cee6586ea 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php +++ b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php @@ -12,26 +12,25 @@ declare(strict_types=1); namespace Chill\DocStoreBundle\Service; use Chill\DocStoreBundle\Entity\StoredObject; -use DateTimeInterface; interface StoredObjectManagerInterface { - public function getLastModified(StoredObject $document): DateTimeInterface; + public function getLastModified(StoredObject $document): \DateTimeInterface; /** * Get the content of a StoredObject. * - * @param StoredObject $document The document. + * @param StoredObject $document the document * - * @return string The retrieved content in clear. + * @return string the retrieved content in clear */ public function read(StoredObject $document): string; /** * Set the content of a StoredObject. * - * @param StoredObject $document The document. - * @param $clearContent The content to store in clear. + * @param StoredObject $document the document + * @param $clearContent The content to store in clear */ public function write(StoredObject $document, string $clearContent): void; } diff --git a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php index ec1df1465..5f7a3c7df 100644 --- a/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php +++ b/src/Bundle/ChillDocStoreBundle/Templating/WopiEditTwigExtensionRuntime.php @@ -18,9 +18,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Twig\Environment; use Twig\Extension\RuntimeExtensionInterface; -use function in_array; - -final class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface +final readonly class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface { public const SUPPORTED_MIMES = [ 'image/svg+xml', @@ -122,15 +120,7 @@ final class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface private const TEMPLATE_BUTTON_GROUP = '@ChillDocStore/Button/button_group.html.twig'; - private DiscoveryInterface $discovery; - - private NormalizerInterface $normalizer; - - public function __construct(DiscoveryInterface $discovery, NormalizerInterface $normalizer) - { - $this->discovery = $discovery; - $this->normalizer = $normalizer; - } + public function __construct(private DiscoveryInterface $discovery, private NormalizerInterface $normalizer) {} /** * return true if the document is editable. @@ -140,7 +130,7 @@ final class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface */ public function isEditable(StoredObject $document): bool { - return in_array($document->getType(), self::SUPPORTED_MIMES, true); + return \in_array($document->getType(), self::SUPPORTED_MIMES, true); } /** @@ -150,18 +140,18 @@ final class WopiEditTwigExtensionRuntime implements RuntimeExtensionInterface * @throws \Twig\Error\RuntimeError * @throws \Twig\Error\SyntaxError */ - public function renderButtonGroup(Environment $environment, StoredObject $document, ?string $title = null, bool $canEdit = true, array $options = []): string + 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), + 'options' => [...self::DEFAULT_OPTIONS_TEMPLATE_BUTTON_GROUP, ...$options], ]); } - public function renderEditButton(Environment $environment, StoredObject $document, ?array $options = null): string + public function renderEditButton(Environment $environment, StoredObject $document, array $options = null): string { return $environment->render(self::TEMPLATE, [ 'document' => $document, diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php index f55b889a9..0994e86e0 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/FetchQueryToSqlBuilderTest.php @@ -18,6 +18,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** * @internal + * * @coversNothing */ class FetchQueryToSqlBuilderTest extends KernelTestCase @@ -35,21 +36,21 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase $query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz'], [Types::STRING]); $query->removeJoinClause($index); $query->addWhereClause('b.item = ?', ['baz'], [Types::STRING]); - $index = $query->addWhereClause('b.cancel', [ 'foz'], [Types::STRING]); + $index = $query->addWhereClause('b.cancel', ['foz'], [Types::STRING]); $query->removeWhereClause($index); ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); $filteredSql = - implode(" ", array_filter( - explode(" ", str_replace("\n", "", $sql)), - fn (string $tok) => $tok !== "" + implode(' ', array_filter( + explode(' ', str_replace("\n", '', $sql)), + fn (string $tok) => '' !== $tok )) ; self::assertEquals( "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ". - "a.datecolumn::date AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?", + 'a.datecolumn::date AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?', $filteredSql ); self::assertEquals(['foo', 'bar_baz', 'baz'], $params); @@ -68,15 +69,15 @@ class FetchQueryToSqlBuilderTest extends KernelTestCase ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); $filteredSql = - implode(" ", array_filter( - explode(" ", str_replace("\n", "", $sql)), - fn (string $tok) => $tok !== "" + implode(' ', array_filter( + explode(' ', str_replace("\n", '', $sql)), + fn (string $tok) => '' !== $tok )) ; self::assertEquals( "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ". - "a.datecolumn::date AS doc_date FROM my_table a", + 'a.datecolumn::date AS doc_date FROM my_table a', $filteredSql ); self::assertEquals([], $params); diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php index f59779374..1b22a4d2e 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/ManagerTest.php @@ -19,7 +19,6 @@ use Chill\DocStoreBundle\GenericDoc\Manager; use Chill\DocStoreBundle\GenericDoc\GenericDocForAccompanyingPeriodProviderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; @@ -28,6 +27,7 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** * @internal + * * @coversNothing */ class ManagerTest extends KernelTestCase @@ -52,7 +52,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $period) { - throw new \UnexpectedValueException("period not found"); + throw new \UnexpectedValueException('period not found'); } $manager = new Manager( @@ -73,7 +73,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $person) { - throw new \UnexpectedValueException("person found"); + throw new \UnexpectedValueException('person found'); } $manager = new Manager( @@ -94,7 +94,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $period) { - throw new \UnexpectedValueException("period not found"); + throw new \UnexpectedValueException('period not found'); } $manager = new Manager( @@ -115,7 +115,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $person) { - throw new \UnexpectedValueException("person not found"); + throw new \UnexpectedValueException('person not found'); } $manager = new Manager( @@ -136,7 +136,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $person) { - throw new \UnexpectedValueException("person not found"); + throw new \UnexpectedValueException('person not found'); } $manager = new Manager( @@ -157,7 +157,7 @@ class ManagerTest extends KernelTestCase ->getSingleResult(); if (null === $period) { - throw new \UnexpectedValueException("period not found"); + throw new \UnexpectedValueException('period not found'); } $manager = new Manager( @@ -174,7 +174,7 @@ class ManagerTest extends KernelTestCase final readonly class SimpleGenericDocAccompanyingPeriodProvider implements GenericDocForAccompanyingPeriodProviderInterface { - public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, ?\DateTimeImmutable $startDate = null, ?\DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $query = new FetchQuery( 'accompanying_course_document_dummy', @@ -196,7 +196,7 @@ final readonly class SimpleGenericDocAccompanyingPeriodProvider implements Gener final readonly class SimpleGenericDocPersonProvider implements GenericDocForPersonProviderInterface { - public function buildFetchQueryForPerson(Person $person, ?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null, ?string $origin = null): FetchQueryInterface + public function buildFetchQueryForPerson(Person $person, \DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null, string $origin = null): FetchQueryInterface { $query = new FetchQuery( 'dummy_person_doc', diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php index 79ced9258..edbe59c13 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/AccompanyingCourseDocumentGenericDocProviderTest.php @@ -15,7 +15,6 @@ use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder; use Chill\DocStoreBundle\GenericDoc\Providers\AccompanyingCourseDocumentGenericDocProvider; use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter; use Chill\PersonBundle\Entity\AccompanyingPeriod; -use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -23,6 +22,7 @@ use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ class AccompanyingCourseDocumentGenericDocProviderTest extends KernelTestCase @@ -40,14 +40,14 @@ class AccompanyingCourseDocumentGenericDocProviderTest extends KernelTestCase /** * @dataProvider provideSearchArguments */ - public function testWithoutAnyArgument(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content = null): void + public function testWithoutAnyArgument(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, string $content = null): void { $period = $this->entityManager->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a') ->setMaxResults(1) ->getSingleResult(); if (null === $period) { - throw new \UnexpectedValueException("period not found"); + throw new \UnexpectedValueException('period not found'); } $security = $this->prophesize(Security::class); diff --git a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php index 577357820..6ac8d71eb 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/GenericDoc/Providers/PersonDocumentGenericDocProviderTest.php @@ -15,7 +15,6 @@ use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder; use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider; use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -23,6 +22,7 @@ use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ class PersonDocumentGenericDocProviderTest extends KernelTestCase @@ -42,11 +42,12 @@ class PersonDocumentGenericDocProviderTest extends KernelTestCase /** * @dataProvider provideDataBuildFetchQueryForPerson + * * @throws \Doctrine\DBAL\Exception * @throws \Doctrine\ORM\NoResultException * @throws \Doctrine\ORM\NonUniqueResultException */ - public function testBuildFetchQueryForPerson(?DateTimeImmutable $startDate, ?DateTimeImmutable $endDate, ?string $content): void + public function testBuildFetchQueryForPerson(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void { $security = $this->prophesize(Security::class); $person = $this->entityManager->createQuery('SELECT a FROM '.Person::class.' a') @@ -54,7 +55,7 @@ class PersonDocumentGenericDocProviderTest extends KernelTestCase ->getSingleResult(); if (null === $person) { - throw new \UnexpectedValueException("person found"); + throw new \UnexpectedValueException('person found'); } $provider = new PersonDocumentGenericDocProvider( @@ -67,18 +68,18 @@ class PersonDocumentGenericDocProviderTest extends KernelTestCase ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query); $nb = $this->entityManager->getConnection() - ->fetchOne("SELECT COUNT(*) AS nb FROM (${sql}) AS sq", $params, $types); + ->fetchOne("SELECT COUNT(*) AS nb FROM ({$sql}) AS sq", $params, $types); - self::assertIsInt($nb, "Test that the query is syntactically correct"); + self::assertIsInt($nb, 'Test that the query is syntactically correct'); } public function provideDataBuildFetchQueryForPerson(): iterable { yield [null, null, null]; - yield [new DateTimeImmutable('1 year ago'), null, null]; - yield [null, new DateTimeImmutable('1 year ago'), null]; - yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [new \DateTimeImmutable('1 year ago'), null, null]; + yield [null, new \DateTimeImmutable('1 year ago'), null]; + yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), null]; yield [null, null, 'test']; - yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), 'test']; } } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php index bb372a150..6dfd521a1 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/Repository/PersonDocumentACLAwareRepositoryTest.php @@ -17,13 +17,9 @@ use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Repository\ScopeRepositoryInterface; use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface; -use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; -use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; -use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; -use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; @@ -32,6 +28,7 @@ use Symfony\Component\Security\Core\Security; /** * @internal + * * @coversNothing */ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase @@ -51,11 +48,12 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase /** * @dataProvider provideDataBuildFetchQueryForPerson + * * @throws \Doctrine\DBAL\Exception * @throws \Doctrine\ORM\NoResultException * @throws \Doctrine\ORM\NonUniqueResultException */ - public function testBuildFetchQueryForPerson(?DateTimeImmutable $startDate = null, ?DateTimeImmutable $endDate = null, ?string $content = null): void + public function testBuildFetchQueryForPerson(\DateTimeImmutable $startDate = null, \DateTimeImmutable $endDate = null, string $content = null): void { $centerManager = $this->prophesize(CenterResolverManagerInterface::class); $centerManager->resolveCenters(Argument::type(Person::class)) @@ -72,12 +70,12 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase $this->prophesize(Security::class)->reveal() ); - $person = $this->entityManager->createQuery("SELECT p FROM " . Person::class . " p") + $person = $this->entityManager->createQuery('SELECT p FROM '.Person::class.' p') ->setMaxResults(1) ->getSingleResult(); if (null === $person) { - throw new \RuntimeException("person not exists in database"); + throw new \RuntimeException('person not exists in database'); } $query = $repository->buildFetchQueryForPerson($person, $startDate, $endDate, $content); @@ -86,7 +84,7 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase $nb = $this->entityManager->getConnection() ->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); - self::assertIsInt($nb, "test that the query could be executed"); + self::assertIsInt($nb, 'test that the query could be executed'); } /** @@ -94,9 +92,9 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase */ public function testBuildFetchQueryForAccompanyingPeriod( AccompanyingPeriod $period, - ?\DateTimeImmutable $startDate = null, - ?\DateTimeImmutable $endDate = null, - ?string $content = null + \DateTimeImmutable $startDate = null, + \DateTimeImmutable $endDate = null, + string $content = null ): void { $centerManager = $this->prophesize(CenterResolverManagerInterface::class); $centerManager->resolveCenters(Argument::type(Person::class)) @@ -122,7 +120,7 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase $nb = $this->entityManager->getConnection() ->fetchOne("SELECT COUNT(*) FROM ({$sql}) AS sq", $params, $types); - self::assertIsInt($nb, "test that the query could be executed"); + self::assertIsInt($nb, 'test that the query could be executed'); } public function provideDateForFetchQueryForAccompanyingPeriod(): iterable @@ -130,27 +128,27 @@ class PersonDocumentACLAwareRepositoryTest extends KernelTestCase $this->setUp(); if (null === $period = $this->entityManager->createQuery( - "SELECT p FROM " . AccompanyingPeriod::class . " p WHERE SIZE(p.participations) > 0" + 'SELECT p FROM '.AccompanyingPeriod::class.' p WHERE SIZE(p.participations) > 0' ) ->setMaxResults(1)->getSingleResult()) { - throw new \RuntimeException("no course found"); + throw new \RuntimeException('no course found'); } yield [$period, null, null, null]; - yield [$period, new DateTimeImmutable('1 year ago'), null, null]; - yield [$period, null, new DateTimeImmutable('1 year ago'), null]; - yield [$period, new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [$period, new \DateTimeImmutable('1 year ago'), null, null]; + yield [$period, null, new \DateTimeImmutable('1 year ago'), null]; + yield [$period, new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), null]; yield [$period, null, null, 'test']; - yield [$period, new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + yield [$period, new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), 'test']; } public function provideDataBuildFetchQueryForPerson(): iterable { yield [null, null, null]; - yield [new DateTimeImmutable('1 year ago'), null, null]; - yield [null, new DateTimeImmutable('1 year ago'), null]; - yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), null]; + yield [new \DateTimeImmutable('1 year ago'), null, null]; + yield [null, new \DateTimeImmutable('1 year ago'), null]; + yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), null]; yield [null, null, 'test']; - yield [new DateTimeImmutable('2 years ago'), new DateTimeImmutable('1 year ago'), 'test']; + yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), 'test']; } } diff --git a/src/Bundle/ChillDocStoreBundle/Tests/StoredObjectManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/StoredObjectManagerTest.php index 354a301e8..bf659ba9b 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/StoredObjectManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/StoredObjectManagerTest.php @@ -16,9 +16,7 @@ use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Exception\StoredObjectManagerException; use Chill\DocStoreBundle\Service\StoredObjectManager; use Chill\DocStoreBundle\Service\StoredObjectManagerInterface; -use Generator; use PHPUnit\Framework\TestCase; -use stdClass; use Symfony\Component\HttpClient\Exception\TransportException; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; @@ -32,7 +30,7 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; */ final class StoredObjectManagerTest extends TestCase { - public function getDataProvider(): Generator + public function getDataProvider(): \Generator { /* HAPPY SCENARIO */ @@ -92,7 +90,7 @@ final class StoredObjectManagerTest extends TestCase /** * @dataProvider getDataProvider */ - public function testRead(StoredObject $storedObject, string $encodedContent, string $clearContent, ?string $exceptionClass = null) + public function testRead(StoredObject $storedObject, string $encodedContent, string $clearContent, string $exceptionClass = null) { if (null !== $exceptionClass) { $this->expectException($exceptionClass); @@ -106,7 +104,7 @@ final class StoredObjectManagerTest extends TestCase /** * @dataProvider getDataProvider */ - public function testWrite(StoredObject $storedObject, string $encodedContent, string $clearContent, ?string $exceptionClass = null) + public function testWrite(StoredObject $storedObject, string $encodedContent, string $clearContent, string $exceptionClass = null) { if (null !== $exceptionClass) { $this->expectException($exceptionClass); @@ -144,7 +142,6 @@ final class StoredObjectManagerTest extends TestCase case 'https://example.com/error_during_http_request.txt': throw new TransportException('error_during_http_request.txt'); - case 'https://example.com/invalid_statuscode.txt': return new MockResponse($encodedContent, ['http_code' => 404]); } @@ -166,12 +163,10 @@ final class StoredObjectManagerTest extends TestCase private function getTempUrlGenerator(StoredObject $storedObject): TempUrlGeneratorInterface { - $response = new stdClass(); + $response = new \stdClass(); $response->url = $storedObject->getFilename(); - $tempUrlGenerator = $this - ->getMockBuilder(TempUrlGeneratorInterface::class) - ->getMock(); + $tempUrlGenerator = $this->createMock(TempUrlGeneratorInterface::class); $tempUrlGenerator ->method('generate') diff --git a/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php b/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php index 546234a31..9d1b619f9 100644 --- a/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php +++ b/src/Bundle/ChillDocStoreBundle/Workflow/AccompanyingCourseDocumentWorkflowHandler.php @@ -22,19 +22,16 @@ use Symfony\Contracts\Translation\TranslatorInterface; class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandlerInterface { - private EntityRepository $repository; - - private TranslatorInterface $translator; + private readonly EntityRepository $repository; /** * TODO: injecter le repository directement. */ public function __construct( EntityManagerInterface $em, - TranslatorInterface $translator + private readonly TranslatorInterface $translator ) { $this->repository = $em->getRepository(AccompanyingCourseDocument::class); - $this->translator = $translator; } public function getDeletionRoles(): array @@ -67,7 +64,7 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler } return $this->translator->trans('workflow.Document (n°%doc%)', ['%doc%' => $entityWorkflow->getRelatedEntityId()]) - . ' - ' . $doc->getTitle(); + .' - '.$doc->getTitle(); } public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?AccompanyingCourseDocument @@ -122,7 +119,7 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool { - return $entityWorkflow->getRelatedEntityClass() === AccompanyingCourseDocument::class; + return AccompanyingCourseDocument::class === $entityWorkflow->getRelatedEntityClass(); } public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool diff --git a/src/Bundle/ChillDocStoreBundle/config/routes.yaml b/src/Bundle/ChillDocStoreBundle/config/routes.yaml index 7f04ebadb..c02dc76ab 100644 --- a/src/Bundle/ChillDocStoreBundle/config/routes.yaml +++ b/src/Bundle/ChillDocStoreBundle/config/routes.yaml @@ -1,27 +1,3 @@ app: resource: "@ChillDocStoreBundle/Controller/" type: annotation - -## ADMIN SECTION -chill_docstore_admin: - path: /{_locale}/admin/document - controller: Chill\DocStoreBundle\Controller\AdminController::indexAction - options: - menus: - admin_section: - order: 2200 - label: "Documents configuration menu" - icons: ['calendar'] - -chill_docstore_admin_redirect_to_admin_index: - path: /{_locale}/admin/document_redirect_to_main - controller: Chill\DocStoreBundle\Controller\AdminController::redirectToAdminIndexAction - options: - menus: - admin_docstore: - order: 0 - label: Main admin menu - -chill_docstore_category_admin: - path: /{_locale}/admin/document/category - controller: Chill\DocStoreBundle\Controller\DocumentCategoryController::indexAction \ No newline at end of file diff --git a/src/Bundle/ChillDocStoreBundle/migrations/Version20180605102533.php b/src/Bundle/ChillDocStoreBundle/migrations/Version20180605102533.php index 917e82186..b9a0bf336 100644 --- a/src/Bundle/ChillDocStoreBundle/migrations/Version20180605102533.php +++ b/src/Bundle/ChillDocStoreBundle/migrations/Version20180605102533.php @@ -21,14 +21,14 @@ final class Version20180605102533 extends AbstractMigration { public function down(Schema $schema): void { - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('DROP SCHEMA chill_doc CASCADE'); } public function up(Schema $schema): void { - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('CREATE SCHEMA chill_doc'); $this->addSql('CREATE SEQUENCE chill_doc.person_document_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); diff --git a/src/Bundle/ChillDocStoreBundle/migrations/Version20180606133338.php b/src/Bundle/ChillDocStoreBundle/migrations/Version20180606133338.php index 02ff4c72b..c18778788 100644 --- a/src/Bundle/ChillDocStoreBundle/migrations/Version20180606133338.php +++ b/src/Bundle/ChillDocStoreBundle/migrations/Version20180606133338.php @@ -21,7 +21,7 @@ final class Version20180606133338 extends AbstractMigration { public function down(Schema $schema): void { - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('ALTER TABLE chill_doc.person_document DROP CONSTRAINT FK_41DA53C232D562B'); $this->addSql('DROP SEQUENCE chill_doc.stored_object_id_seq CASCADE'); @@ -32,7 +32,7 @@ final class Version20180606133338 extends AbstractMigration public function up(Schema $schema): void { - $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.'); $this->addSql('CREATE SEQUENCE chill_doc.stored_object_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); $this->addSql('CREATE TABLE chill_doc.stored_object (id INT NOT NULL, filename TEXT NOT NULL, key JSON NOT NULL, iv JSON NOT NULL, creation_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, type TEXT NOT NULL, datas JSON NOT NULL, PRIMARY KEY(id))'); diff --git a/src/Bundle/ChillEventBundle/Controller/AdminController.php b/src/Bundle/ChillEventBundle/Controller/AdminController.php index 88c5aeb9a..3434df9e5 100644 --- a/src/Bundle/ChillEventBundle/Controller/AdminController.php +++ b/src/Bundle/ChillEventBundle/Controller/AdminController.php @@ -27,6 +27,6 @@ class AdminController extends AbstractController */ public function indexAdminAction() { - return $this->render('ChillEventBundle:Admin:index.html.twig'); + return $this->render('@ChillEvent/Admin/index.html.twig'); } } diff --git a/src/Bundle/ChillEventBundle/Controller/EventController.php b/src/Bundle/ChillEventBundle/Controller/EventController.php index 93ce62f43..0abdff8dd 100644 --- a/src/Bundle/ChillEventBundle/Controller/EventController.php +++ b/src/Bundle/ChillEventBundle/Controller/EventController.php @@ -37,11 +37,8 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\StreamedResponse; -use Symfony\Component\Security\Core\Role\Role; use Symfony\Contracts\Translation\TranslatorInterface; -use function count; - /** * Class EventController. */ @@ -90,11 +87,9 @@ class EventController extends AbstractController } /** - * @param $event_id - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/{event_id}/delete", name="chill_event__event_delete", requirements={"event_id"="\d+"}, methods={"GET", "DELETE"}) */ - public function deleteAction($event_id, Request $request) + public function deleteAction($event_id, Request $request): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response { $em = $this->getDoctrine()->getManager(); $event = $em->getRepository(\Chill\EventBundle\Entity\Event::class)->findOneBy([ @@ -110,7 +105,7 @@ class EventController extends AbstractController $form = $this->createDeleteForm($event_id); - if ($request->getMethod() === Request::METHOD_DELETE) { + if (Request::METHOD_DELETE === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -134,7 +129,7 @@ class EventController extends AbstractController } } - return $this->render('ChillEventBundle:Event:confirm_delete.html.twig', [ + return $this->render('@ChillEvent/Event/confirm_delete.html.twig', [ 'event_id' => $event->getId(), 'delete_form' => $form->createView(), ]); @@ -143,9 +138,9 @@ class EventController extends AbstractController /** * Displays a form to edit an existing Event entity. * - * @param $event_id - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/{event_id}/edit", name="chill_event__event_edit") */ public function editAction($event_id) { @@ -159,7 +154,7 @@ class EventController extends AbstractController $editForm = $this->createEditForm($entity); - return $this->render('ChillEventBundle:Event:edit.html.twig', [ + return $this->render('@ChillEvent/Event/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -168,11 +163,11 @@ class EventController extends AbstractController /** * List events subscriptions for a person. * - * @param $person_id + * @return \Symfony\Component\HttpFoundation\Response * * @throws \Doctrine\ORM\NonUniqueResultException * - * @return \Symfony\Component\HttpFoundation\Response + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/{person_id}/list", name="chill_event__list_by_person", methods={"GET"}) */ public function listByPersonAction($person_id) { @@ -188,7 +183,7 @@ class EventController extends AbstractController $reachablesCircles = $this->authorizationHelper->getReachableCircles( $this->getUser(), - new Role(EventVoter::SEE), + EventVoter::SEE, $person->getCenter() ); @@ -207,11 +202,11 @@ class EventController extends AbstractController 'element_class' => Participation::class, 'action' => 'list', ]); - $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $privacyEvent); + $this->eventDispatcher->dispatch($privacyEvent, PrivacyEvent::PERSON_PRIVACY_EVENT); $addEventParticipationByPersonForm = $this->createAddEventParticipationByPersonForm($person); - return $this->render('ChillEventBundle:Event:listByPerson.html.twig', [ + return $this->render('@ChillEvent/Event/listByPerson.html.twig', [ 'participations' => $participations, 'person' => $person, 'paginator' => $paginator, @@ -219,6 +214,9 @@ class EventController extends AbstractController ]); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/most_recent", name="chill_event_list_most_recent", options={null}) + */ public function mostRecentIndexAction() { return $this->redirectToRoute('chill_main_search', [ @@ -229,9 +227,9 @@ class EventController extends AbstractController /** * Displays a form to create a new Event entity. * - * @param Center $center - * * @return \Symfony\Component\HttpFoundation\Response + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/new", name="chill_event__event_new", methods={"GET", "POST"}) */ public function newAction(?Center $center, Request $request) { @@ -254,10 +252,10 @@ class EventController extends AbstractController $this->addFlash('success', $this->get('translator') ->trans('The event was created')); - return $this->redirect($this->generateUrl('chill_event__event_show', ['event_id' => $entity->getId()])); + return $this->redirectToRoute('chill_event__event_show', ['event_id' => $entity->getId()]); } - return $this->render('ChillEventBundle:Event:new.html.twig', [ + return $this->render('@ChillEvent/Event/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -265,17 +263,19 @@ class EventController extends AbstractController /** * First step of new Event form. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/new/pick-center", name="chill_event__event_new_pickcenter", options={null}) */ public function newPickCenterAction() { - $role = new Role('CHILL_EVENT_CREATE'); + $role = 'CHILL_EVENT_CREATE'; /** * @var Center $centers */ - $centers = $this->authorizationHelper->getReachableCenters($this->getUser(), (string) $role); + $centers = $this->authorizationHelper->getReachableCenters($this->getUser(), $role); - if (count($centers) === 1) { + if (1 === \count($centers)) { return $this->redirectToRoute('chill_event__event_new', [ 'center_id' => $centers[0]->getId(), ]); @@ -300,7 +300,7 @@ class EventController extends AbstractController ]) ->getForm(); - return $this->render('ChillEventBundle:Event:newPickCenter.html.twig', [ + return $this->render('@ChillEvent/Event/newPickCenter.html.twig', [ 'form' => $form->createView(), ]); } @@ -310,9 +310,11 @@ class EventController extends AbstractController * * @ParamConverter("event", options={"id": "event_id"}) * + * @return \Symfony\Component\HttpFoundation\Response + * * @throws \PhpOffice\PhpSpreadsheet\Exception * - * @return \Symfony\Component\HttpFoundation\Response + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/{event_id}/show", name="chill_event__event_show") */ public function showAction(Event $event, Request $request) { @@ -334,7 +336,7 @@ class EventController extends AbstractController return $exportParticipationsList['response']; } - return $this->render('ChillEventBundle:Event:show.html.twig', [ + return $this->render('@ChillEvent/Event/show.html.twig', [ 'event' => $event, 'form_add_participation_by_person' => $addParticipationByPersonForm->createView(), 'form_export' => $exportParticipationsList['form']->createView(), @@ -344,11 +346,9 @@ class EventController extends AbstractController /** * Edits an existing Event entity. * - * @param $event_id - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/event/{event_id}/update", name="chill_event__event_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $event_id) + public function updateAction(Request $request, $event_id): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response { $em = $this->getDoctrine()->getManager(); @@ -367,10 +367,10 @@ class EventController extends AbstractController $this->addFlash('success', $this->get('translator') ->trans('The event was updated')); - return $this->redirect($this->generateUrl('chill_event__event_edit', ['event_id' => $event_id])); + return $this->redirectToRoute('chill_event__event_edit', ['event_id' => $event_id]); } - return $this->render('ChillEventBundle:Event:edit.html.twig', [ + return $this->render('@ChillEvent/Event/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), ]); @@ -398,7 +398,7 @@ class EventController extends AbstractController ); $builder->add('event_id', PickEventType::class, [ - 'role' => new Role('CHILL_EVENT_CREATE'), + 'role' => 'CHILL_EVENT_CREATE', 'centers' => $person->getCenter(), ]); @@ -445,7 +445,7 @@ class EventController extends AbstractController ); $builder->add('person_id', PickPersonType::class, [ - 'role' => new Role('CHILL_EVENT_CREATE'), + 'role' => 'CHILL_EVENT_CREATE', 'centers' => $event->getCenter(), ]); @@ -487,9 +487,9 @@ class EventController extends AbstractController } /** - * @throws \PhpOffice\PhpSpreadsheet\Exception - * * @return Spreadsheet + * + * @throws \PhpOffice\PhpSpreadsheet\Exception */ protected function createExportSpreadsheet(Event $event) { @@ -510,7 +510,7 @@ class EventController extends AbstractController 'A5' => 'Circle', 'B5' => $event->getCircle()->getName()[$trans], 'A6' => 'Moderator', - 'B6' => $event->getModerator() ? $event->getModerator()->getUsernameCanonical() : null, + 'B6' => null !== $event->getModerator() ? $event->getModerator()->getUsernameCanonical() : null, ]; foreach ($headerValues as $k => $value) { @@ -521,14 +521,14 @@ class EventController extends AbstractController $columnLetter = 'A'; foreach ($columnNames as $columnName) { - $sheet->setCellValue($columnLetter . '8', $columnName); + $sheet->setCellValue($columnLetter.'8', $columnName); ++$columnLetter; } $columnValues = []; foreach ($event->getParticipations() as $participation) { - /** @var Participation $participation */ + /* @var Participation $participation */ $columnValues[] = [ $participation->getPerson()->getId(), $participation->getPerson()->getFirstname(), @@ -547,7 +547,7 @@ class EventController extends AbstractController $columnLetter = 'A'; foreach ($columnValue as $value) { - $sheet->setCellValue($columnLetter . $i, $value); + $sheet->setCellValue($columnLetter.$i, $value); ++$columnLetter; } ++$i; @@ -557,9 +557,9 @@ class EventController extends AbstractController } /** - * @throws \PhpOffice\PhpSpreadsheet\Exception - * * @return array + * + * @throws \PhpOffice\PhpSpreadsheet\Exception */ protected function exportParticipationsList(Event $event, Request $request) { @@ -569,7 +569,7 @@ class EventController extends AbstractController if ($form->isSubmitted() && $form->isValid()) { $data = $form->getData(); $format = $data['format']; - $filename = 'export_event' . $event->getId() . '_participations.' . $format; + $filename = 'export_event'.$event->getId().'_participations.'.$format; $spreadsheet = $this->createExportSpreadsheet($event); @@ -598,7 +598,7 @@ class EventController extends AbstractController $response = new StreamedResponse(); $response->headers->set('Content-Type', $contentType); - $response->headers->set('Content-Disposition', 'attachment;filename="' . $filename . '"'); + $response->headers->set('Content-Disposition', 'attachment;filename="'.$filename.'"'); $response->setPrivate(); $response->headers->addCacheControlDirective('no-cache', true); $response->headers->addCacheControlDirective('must-revalidate', true); @@ -624,7 +624,7 @@ class EventController extends AbstractController $form = $this->createForm(EventType::class, $entity, [ 'method' => 'POST', 'center' => $entity->getCenter(), - 'role' => new Role('CHILL_EVENT_CREATE'), + 'role' => 'CHILL_EVENT_CREATE', ]); $form->add('submit', SubmitType::class, ['label' => 'Create']); @@ -633,8 +633,6 @@ class EventController extends AbstractController } /** - * @param $event_id - * * @return \Symfony\Component\Form\FormInterface */ private function createDeleteForm($event_id) @@ -659,7 +657,7 @@ class EventController extends AbstractController 'action' => $this->generateUrl('chill_event__event_update', ['event_id' => $entity->getId()]), 'method' => 'PUT', 'center' => $entity->getCenter(), - 'role' => new Role('CHILL_EVENT_CREATE'), + 'role' => 'CHILL_EVENT_CREATE', ]); $form->remove('center'); diff --git a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php index 2e9a45f6f..b96fb9cb9 100644 --- a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php +++ b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php @@ -24,6 +24,8 @@ class EventTypeController extends AbstractController { /** * Creates a new EventType entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/create", name="chill_eventtype_admin_create", methods={"POST"}) */ public function createAction(Request $request) { @@ -31,18 +33,15 @@ class EventTypeController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl( - 'chill_eventtype_admin', - ['id' => $entity->getId()] - )); + return $this->redirectToRoute('chill_eventtype_admin', ['id' => $entity->getId()]); } - return $this->render('ChillEventBundle:EventType:new.html.twig', [ + return $this->render('@ChillEvent/EventType/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -51,14 +50,14 @@ class EventTypeController extends AbstractController /** * Deletes a EventType entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/{id}/delete", name="chill_eventtype_admin_delete", methods={"POST", "DELETE"}) */ - public function deleteAction(Request $request, $id) + public function deleteAction(Request $request, mixed $id) { $form = $this->createDeleteForm($id); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $entity = $em->getRepository(\Chill\EventBundle\Entity\EventType::class)->find($id); @@ -70,15 +69,15 @@ class EventTypeController extends AbstractController $em->flush(); } - return $this->redirect($this->generateUrl('chill_eventtype_admin')); + return $this->redirectToRoute('chill_eventtype_admin'); } /** * Displays a form to edit an existing EventType entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/{id}/edit", name="chill_eventtype_admin_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -91,7 +90,7 @@ class EventTypeController extends AbstractController $editForm = $this->createEditForm($entity); $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:EventType:edit.html.twig', [ + return $this->render('@ChillEvent/EventType/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -100,6 +99,8 @@ class EventTypeController extends AbstractController /** * Lists all EventType entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/", name="chill_eventtype_admin", options={null}) */ public function indexAction() { @@ -107,20 +108,22 @@ class EventTypeController extends AbstractController $entities = $em->getRepository(\Chill\EventBundle\Entity\EventType::class)->findAll(); - return $this->render('ChillEventBundle:EventType:index.html.twig', [ + return $this->render('@ChillEvent/EventType/index.html.twig', [ 'entities' => $entities, ]); } /** * Displays a form to create a new EventType entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/new", name="chill_eventtype_admin_new") */ public function newAction() { $entity = new EventType(); $form = $this->createCreateForm($entity); - return $this->render('ChillEventBundle:EventType:new.html.twig', [ + return $this->render('@ChillEvent/EventType/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -129,9 +132,9 @@ class EventTypeController extends AbstractController /** * Finds and displays a EventType entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/{id}/show", name="chill_eventtype_admin_show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -143,7 +146,7 @@ class EventTypeController extends AbstractController $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:EventType:show.html.twig', [ + return $this->render('@ChillEvent/EventType/show.html.twig', [ 'entity' => $entity, 'delete_form' => $deleteForm->createView(), ]); @@ -152,9 +155,9 @@ class EventTypeController extends AbstractController /** * Edits an existing EventType entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/event_type/{id}/update", name="chill_eventtype_admin_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -168,16 +171,13 @@ class EventTypeController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); - return $this->redirect($this->generateUrl( - 'chill_eventtype_admin', - ['id' => $id] - )); + return $this->redirectToRoute('chill_eventtype_admin', ['id' => $id]); } - return $this->render('ChillEventBundle:EventType:edit.html.twig', [ + return $this->render('@ChillEvent/EventType/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -210,7 +210,7 @@ class EventTypeController extends AbstractController * * @return \Symfony\Component\Form\Form The form */ - private function createDeleteForm($id) + private function createDeleteForm(mixed $id) { return $this->createFormBuilder() ->setAction($this->generateUrl( diff --git a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php index a2a82c88f..bc98f11ee 100644 --- a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php +++ b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php @@ -11,16 +11,12 @@ declare(strict_types=1); namespace Chill\EventBundle\Controller; -use ArrayIterator; use Chill\EventBundle\Entity\Event; use Chill\EventBundle\Entity\Participation; use Chill\EventBundle\Form\ParticipationType; use Chill\EventBundle\Security\Authorization\ParticipationVoter; use Doctrine\Common\Collections\Collection; -use Doctrine\Common\Collections\ReadableCollection; -use LogicException; use Psr\Log\LoggerInterface; -use RuntimeException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -28,35 +24,25 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use function count; - /** * Class ParticipationController. */ class ParticipationController extends AbstractController { - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - /** * ParticipationController constructor. */ - public function __construct(LoggerInterface $logger) - { - $this->logger = $logger; - } + public function __construct(private readonly LoggerInterface $logger) {} /** - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/create", name="chill_event_participation_create") */ - public function createAction(Request $request) + public function createAction(Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { // test the request is correct try { $this->testRequest($request); - } catch (RuntimeException $ex) { + } catch (\RuntimeException $ex) { $this->logger->warning($ex->getMessage()); return (new Response()) @@ -80,7 +66,7 @@ class ParticipationController extends AbstractController return (new Response()) ->setStatusCode(Response::HTTP_BAD_REQUEST) ->setContent("You must provide either 'person_id' or " - . "'persons_ids' argument in query"); + ."'persons_ids' argument in query"); } /** @@ -166,10 +152,7 @@ class ParticipationController extends AbstractController return $form; } - /** - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse - */ - public function createMultiple(Request $request) + public function createMultiple(Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { $participations = $this->handleRequest($request, new Participation(), true); @@ -203,16 +186,13 @@ class ParticipationController extends AbstractController ]); } - return $this->render('ChillEventBundle:Participation:new.html.twig', [ + return $this->render('@ChillEvent/Participation/new.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, ]); } - /** - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse - */ - public function createSingle(Request $request) + public function createSingle(Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { $participation = $this->handleRequest($request, new Participation(), false); @@ -244,7 +224,7 @@ class ParticipationController extends AbstractController ]); } - return $this->render('ChillEventBundle:Participation:new.html.twig', [ + return $this->render('@ChillEvent/Participation/new.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, ]); @@ -253,9 +233,9 @@ class ParticipationController extends AbstractController /** * @param int $participation_id * - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/{participation_id}/delete", name="chill_event_participation_delete", requirements={"participation_id"="\d+"}, methods={"GET", "DELETE"}) */ - public function deleteAction($participation_id, Request $request) + public function deleteAction($participation_id, Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { $em = $this->getDoctrine()->getManager(); $participation = $em->getRepository(\Chill\EventBundle\Entity\Participation::class)->findOneBy([ @@ -271,7 +251,7 @@ class ParticipationController extends AbstractController $form = $this->createDeleteForm($participation_id); - if ($request->getMethod() === Request::METHOD_DELETE) { + if (Request::METHOD_DELETE === $request->getMethod()) { $form->handleRequest($request); if ($form->isValid()) { @@ -290,7 +270,7 @@ class ParticipationController extends AbstractController } } - return $this->render('ChillEventBundle:Participation:confirm_delete.html.twig', [ + return $this->render('@ChillEvent/Participation/confirm_delete.html.twig', [ 'event_id' => $event->getId(), 'delete_form' => $form->createView(), ]); @@ -299,8 +279,10 @@ class ParticipationController extends AbstractController /** * Show an edit form for the participation with the given id. * - * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the participation is not found + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the participation is not found * @throws \Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException if the user is not allowed to edit the participation + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/{participation_id}/edit", name="chill_event_participation_edit") */ public function editAction(int $participation_id): Response { @@ -321,7 +303,7 @@ class ParticipationController extends AbstractController $form = $this->createEditForm($participation); - return $this->render('ChillEventBundle:Participation:edit.html.twig', [ + return $this->render('@ChillEvent/Participation/edit.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, ]); @@ -332,9 +314,9 @@ class ParticipationController extends AbstractController * * @param int $event_id * - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/{event_id}/edit_multiple", name="chill_event_participation_edit_multiple") */ - public function editMultipleAction($event_id) + public function editMultipleAction($event_id): Response|\Symfony\Component\HttpFoundation\RedirectResponse { $event = $this->getDoctrine()->getRepository(\Chill\EventBundle\Entity\Event::class) ->find($event_id); @@ -345,13 +327,13 @@ class ParticipationController extends AbstractController // check for ACL, on Event level and on Participation Level $this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, 'You are not allowed ' - . 'to see this event'); + .'to see this event'); foreach ($event->getParticipations() as $participation) { $this->denyAccessUnlessGranted( ParticipationVoter::UPDATE, $participation, - 'You are not allowed to update participation with id ' . $participation->getId() + 'You are not allowed to update participation with id '.$participation->getId() ); } @@ -375,7 +357,7 @@ class ParticipationController extends AbstractController $form = $this->createEditFormMultiple($event->getParticipations(), $event); - return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', [ + return $this->render('@ChillEvent/Participation/edit-multiple.html.twig', [ 'event' => $event, 'participations' => $event->getParticipations(), 'form' => $form->createView(), @@ -389,14 +371,14 @@ class ParticipationController extends AbstractController * and decide if it should process a single or multiple participation. Depending * on this, the appropriate layout and form. * - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/new", name="chill_event_participation_new") */ - public function newAction(Request $request) + public function newAction(Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { // test the request is correct try { $this->testRequest($request); - } catch (RuntimeException $ex) { + } catch (\RuntimeException $ex) { $this->logger->warning($ex->getMessage()); return (new Response()) @@ -420,9 +402,12 @@ class ParticipationController extends AbstractController return (new Response()) ->setStatusCode(Response::HTTP_BAD_REQUEST) ->setContent("You must provide either 'person_id' or " - . "'persons_ids' argument in query"); + ."'persons_ids' argument in query"); } + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/{participation_id}/update", name="chill_event_participation_update", methods={"POST"}) + */ public function updateAction(int $participation_id, Request $request): Response { /** @var Participation $participation */ @@ -458,13 +443,16 @@ class ParticipationController extends AbstractController ]); } - return $this->render('ChillEventBundle:Participation:edit.html.twig', [ + return $this->render('@ChillEvent/Participation/edit.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, ]); } - public function updateMultipleAction($event_id, Request $request) + /** + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/event/participation/{event_id}/update_multiple", name="chill_event_participation_update_multiple", methods={"POST"}) + */ + public function updateMultipleAction(mixed $event_id, Request $request) { /** @var \Chill\EventBundle\Entity\Event $event */ $event = $this->getDoctrine()->getRepository(\Chill\EventBundle\Entity\Event::class) @@ -475,13 +463,13 @@ class ParticipationController extends AbstractController } $this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, 'You are not allowed ' - . 'to see this event'); + .'to see this event'); foreach ($event->getParticipations() as $participation) { $this->denyAccessUnlessGranted( ParticipationVoter::UPDATE, $participation, - 'You are not allowed to update participation with id ' . $participation->getId() + 'You are not allowed to update participation with id '.$participation->getId() ); } @@ -493,7 +481,7 @@ class ParticipationController extends AbstractController $this->getDoctrine()->getManager()->flush(); $this->addFlash('success', $this->get('translator')->trans('The participations ' - . 'have been successfully updated.')); + .'have been successfully updated.')); return $this->redirectToRoute( 'chill_event__event_show', @@ -501,7 +489,7 @@ class ParticipationController extends AbstractController ); } - return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', [ + return $this->render('@ChillEvent/Participation/edit-multiple.html.twig', [ 'event' => $event, 'participations' => $event->getParticipations(), 'form' => $form->createView(), @@ -548,21 +536,20 @@ class ParticipationController extends AbstractController * If the request is multiple, the $participation object is cloned. * Limitations: the $participation should not be persisted. * - * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the event/person is not found - * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException if the user does not have access to event/person + * @return Participation|Participation[] return one single participation if $multiple == false * - * @return Participation|Participations[] return one single participation if $multiple == false + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the event/person is not found + * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException if the user does not have access to event/person */ protected function handleRequest( Request $request, Participation $participation, bool $multiple = false - ) { + ): array|\Chill\EventBundle\Entity\Participation { $em = $this->getDoctrine()->getManager(); if ($em->contains($participation)) { - throw new LogicException('The participation object should not be managed by ' - . 'the object manager using the method ' . __METHOD__); + throw new \LogicException('The participation object should not be managed by the object manager using the method '.__METHOD__); } $event_id = $request->query->getInt('event_id', 0); // sf4 check: @@ -573,7 +560,7 @@ class ParticipationController extends AbstractController ->find($event_id); if (null === $event) { - throw $this->createNotFoundException('The event with id ' . $event_id . ' is not found'); + throw $this->createNotFoundException('The event with id '.$event_id.' is not found'); } $this->denyAccessUnlessGranted( @@ -590,19 +577,19 @@ class ParticipationController extends AbstractController $persons_ids = $request->query->has('person_id') ? [$request->query->getInt('person_id', 0)] // sf4 check: // prevent error: `Argument 2 passed to ::getInt() must be of the type int, null given` - : explode(',', $request->query->get('persons_ids')); + : explode(',', (string) $request->query->get('persons_ids')); $participations = []; foreach ($persons_ids as $person_id) { // clone if we have to reuse the $participation - $participation = count($persons_ids) > 1 ? clone $participation : $participation; + $participation = \count($persons_ids) > 1 ? clone $participation : $participation; if (null !== $person_id) { $person = $em->getRepository(\Chill\PersonBundle\Entity\Person::class) ->find($person_id); if (null === $person) { - throw $this->createNotFoundException('The person with id ' . $person_id . ' is not found'); + throw $this->createNotFoundException('The person with id '.$person_id.' is not found'); } $this->denyAccessUnlessGranted( @@ -631,16 +618,14 @@ class ParticipationController extends AbstractController * * If all participations must be ignored, an error is shown and the method redirects * to the event 'show' view with an appropriate flash message. - * - * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse */ - protected function newMultiple(Request $request) + protected function newMultiple(Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse { $participations = $this->handleRequest($request, new Participation(), true); $ignoredParticipations = $newParticipations = []; foreach ($participations as $participation) { - /** @var Participation $participation */ + /* @var Participation $participation */ // check for authorization $this->denyAccessUnlessGranted( ParticipationVoter::CREATE, @@ -649,7 +634,6 @@ class ParticipationController extends AbstractController ); // create a collection of person's id participating to the event - /** @var \Doctrine\Common\Collections\ArrayCollection $peopleParticipating */ $peopleParticipating ??= $participation->getEvent()->getParticipations()->map( static fn (Participation $p) => $p->getPerson()->getId() ); @@ -670,7 +654,7 @@ class ParticipationController extends AbstractController // if we do not have nay participants, redirect to event view $this->addFlash('error', $this->get('translator')->trans( 'None of the requested people may participate ' - . 'the event: they are maybe already participating.' + .'the event: they are maybe already participating.' )); return $this->redirectToRoute('chill_event__event_show', [ @@ -678,12 +662,12 @@ class ParticipationController extends AbstractController ]); } - if (count($newParticipations) > 1) { + if (\count($newParticipations) > 1) { // if we have multiple participations, show a form with multiple participations $form = $this->createCreateFormMultiple($newParticipations); return $this->render( - 'ChillEventBundle:Participation:new-multiple.html.twig', + '@ChillEvent/Participation/new-multiple.html.twig', [ 'form' => $form->createView(), 'participations' => $newParticipations, @@ -696,7 +680,7 @@ class ParticipationController extends AbstractController $form = $this->createCreateForm($participation); return $this->render( - 'ChillEventBundle:Participation:new.html.twig', + '@ChillEvent/Participation/new.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, @@ -725,7 +709,7 @@ class ParticipationController extends AbstractController $form = $this->createCreateForm($participation, $returnPath); - return $this->render('ChillEventBundle:Participation:new.html.twig', [ + return $this->render('@ChillEvent/Participation/new.html.twig', [ 'form' => $form->createView(), 'participation' => $participation, 'ignored_participations' => [], // this is required, see self::newMultiple @@ -739,7 +723,7 @@ class ParticipationController extends AbstractController * - `person_id` and `persons_ids` are **not** both present ; * - `persons_id` is correct (contains only numbers and a ','. * - * @throws RuntimeException if an error is detected + * @throws \RuntimeException if an error is detected */ protected function testRequest(Request $request) { @@ -748,28 +732,24 @@ class ParticipationController extends AbstractController if (true === $single && true === $multiple) { // we are not allowed to have both person_id and persons_ids - throw new RuntimeException("You are not allow to provide both 'person_id' and " - . "'persons_ids' simulaneously"); + throw new \RuntimeException("You are not allow to provide both 'person_id' and 'persons_ids' simulaneously"); } if (true === $multiple) { $persons_ids = $request->query->get('persons_ids'); - if (!preg_match('/^([0-9]{1,},{0,1}){1,}[0-9]{0,}$/', $persons_ids)) { - throw new RuntimeException('The persons_ids value should ' - . "contains int separated by ','"); + if (!preg_match('/^([0-9]{1,},{0,1}){1,}[0-9]{0,}$/', (string) $persons_ids)) { + throw new \RuntimeException('The persons_ids value should '."contains int separated by ','"); } } // check for event_id - this could be removed later - if ($request->query->has('event_id') === false) { - throw new RuntimeException('You must provide an event_id'); + if (false === $request->query->has('event_id')) { + throw new \RuntimeException('You must provide an event_id'); } } /** - * @param $participation_id - * * @return \Symfony\Component\Form\FormInterface */ private function createDeleteForm($participation_id) diff --git a/src/Bundle/ChillEventBundle/Controller/RoleController.php b/src/Bundle/ChillEventBundle/Controller/RoleController.php index 9ffe0d2d0..1b2ad2b25 100644 --- a/src/Bundle/ChillEventBundle/Controller/RoleController.php +++ b/src/Bundle/ChillEventBundle/Controller/RoleController.php @@ -24,6 +24,8 @@ class RoleController extends AbstractController { /** * Creates a new Role entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/create", name="chill_event_admin_role_create", methods={"POST"}) */ public function createAction(Request $request) { @@ -31,18 +33,15 @@ class RoleController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl( - 'chill_event_admin_role', - ['id' => $entity->getId()] - )); + return $this->redirectToRoute('chill_event_admin_role', ['id' => $entity->getId()]); } - return $this->render('ChillEventBundle:Role:new.html.twig', [ + return $this->render('@ChillEvent/Role/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -51,14 +50,14 @@ class RoleController extends AbstractController /** * Deletes a Role entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/{id}/delete", name="chill_event_admin_role_delete", methods={"POST", "DELETE"}) */ - public function deleteAction(Request $request, $id) + public function deleteAction(Request $request, mixed $id) { $form = $this->createDeleteForm($id); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $entity = $em->getRepository(\Chill\EventBundle\Entity\Role::class)->find($id); @@ -70,15 +69,15 @@ class RoleController extends AbstractController $em->flush(); } - return $this->redirect($this->generateUrl('chill_event_admin_role')); + return $this->redirectToRoute('chill_event_admin_role'); } /** * Displays a form to edit an existing Role entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/{id}/edit", name="chill_event_admin_role_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -91,7 +90,7 @@ class RoleController extends AbstractController $editForm = $this->createEditForm($entity); $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:Role:edit.html.twig', [ + return $this->render('@ChillEvent/Role/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -100,6 +99,8 @@ class RoleController extends AbstractController /** * Lists all Role entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/", name="chill_event_admin_role", options={null}) */ public function indexAction() { @@ -107,20 +108,22 @@ class RoleController extends AbstractController $entities = $em->getRepository(\Chill\EventBundle\Entity\Role::class)->findAll(); - return $this->render('ChillEventBundle:Role:index.html.twig', [ + return $this->render('@ChillEvent/Role/index.html.twig', [ 'entities' => $entities, ]); } /** * Displays a form to create a new Role entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/new", name="chill_event_admin_role_new") */ public function newAction() { $entity = new Role(); $form = $this->createCreateForm($entity); - return $this->render('ChillEventBundle:Role:new.html.twig', [ + return $this->render('@ChillEvent/Role/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -129,9 +132,9 @@ class RoleController extends AbstractController /** * Finds and displays a Role entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/{id}/show", name="chill_event_admin_role_show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -143,7 +146,7 @@ class RoleController extends AbstractController $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:Role:show.html.twig', [ + return $this->render('@ChillEvent/Role/show.html.twig', [ 'entity' => $entity, 'delete_form' => $deleteForm->createView(), ]); @@ -152,9 +155,9 @@ class RoleController extends AbstractController /** * Edits an existing Role entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/role/{id}/update", name="chill_event_admin_role_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -168,16 +171,13 @@ class RoleController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); - return $this->redirect($this->generateUrl( - 'chill_event_admin_role', - ['id' => $id] - )); + return $this->redirectToRoute('chill_event_admin_role', ['id' => $id]); } - return $this->render('ChillEventBundle:Role:edit.html.twig', [ + return $this->render('@ChillEvent/Role/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -210,7 +210,7 @@ class RoleController extends AbstractController * * @return \Symfony\Component\Form\Form The form */ - private function createDeleteForm($id) + private function createDeleteForm(mixed $id) { return $this->createFormBuilder() ->setAction($this->generateUrl('chill_event_admin_role_delete', ['id' => $id])) diff --git a/src/Bundle/ChillEventBundle/Controller/StatusController.php b/src/Bundle/ChillEventBundle/Controller/StatusController.php index 2b8d97ee6..90bb7c1f2 100644 --- a/src/Bundle/ChillEventBundle/Controller/StatusController.php +++ b/src/Bundle/ChillEventBundle/Controller/StatusController.php @@ -24,6 +24,8 @@ class StatusController extends AbstractController { /** * Creates a new Status entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/create", name="chill_event_admin_status_create", methods={"POST"}) */ public function createAction(Request $request) { @@ -31,15 +33,15 @@ class StatusController extends AbstractController $form = $this->createCreateForm($entity); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl('chill_event_admin_status', ['id' => $entity->getId()])); + return $this->redirectToRoute('chill_event_admin_status', ['id' => $entity->getId()]); } - return $this->render('ChillEventBundle:Status:new.html.twig', [ + return $this->render('@ChillEvent/Status/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -48,14 +50,14 @@ class StatusController extends AbstractController /** * Deletes a Status entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/{id}/delete", name="chill_event_admin_status_delete", methods={"POST", "DELETE"}) */ - public function deleteAction(Request $request, $id) + public function deleteAction(Request $request, mixed $id) { $form = $this->createDeleteForm($id); $form->handleRequest($request); - if ($form->isValid()) { + if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $entity = $em->getRepository(\Chill\EventBundle\Entity\Status::class)->find($id); @@ -67,15 +69,15 @@ class StatusController extends AbstractController $em->flush(); } - return $this->redirect($this->generateUrl('chill_event_admin_status')); + return $this->redirectToRoute('chill_event_admin_status'); } /** * Displays a form to edit an existing Status entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/{id}/edit", name="chill_event_admin_status_edit") */ - public function editAction($id) + public function editAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -88,7 +90,7 @@ class StatusController extends AbstractController $editForm = $this->createEditForm($entity); $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:Status:edit.html.twig', [ + return $this->render('@ChillEvent/Status/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -97,6 +99,8 @@ class StatusController extends AbstractController /** * Lists all Status entities. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/", name="chill_event_admin_status", options={null}) */ public function indexAction() { @@ -104,20 +108,22 @@ class StatusController extends AbstractController $entities = $em->getRepository(\Chill\EventBundle\Entity\Status::class)->findAll(); - return $this->render('ChillEventBundle:Status:index.html.twig', [ + return $this->render('@ChillEvent/Status/index.html.twig', [ 'entities' => $entities, ]); } /** * Displays a form to create a new Status entity. + * + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/new", name="chill_event_admin_status_new") */ public function newAction() { $entity = new Status(); $form = $this->createCreateForm($entity); - return $this->render('ChillEventBundle:Status:new.html.twig', [ + return $this->render('@ChillEvent/Status/new.html.twig', [ 'entity' => $entity, 'form' => $form->createView(), ]); @@ -126,9 +132,9 @@ class StatusController extends AbstractController /** * Finds and displays a Status entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/{id}/show", name="chill_event_admin_status_show") */ - public function showAction($id) + public function showAction(mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -140,7 +146,7 @@ class StatusController extends AbstractController $deleteForm = $this->createDeleteForm($id); - return $this->render('ChillEventBundle:Status:show.html.twig', [ + return $this->render('@ChillEvent/Status/show.html.twig', [ 'entity' => $entity, 'delete_form' => $deleteForm->createView(), ]); @@ -149,9 +155,9 @@ class StatusController extends AbstractController /** * Edits an existing Status entity. * - * @param mixed $id + * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/admin/event/status/{id}/update", name="chill_event_admin_status_update", methods={"POST", "PUT"}) */ - public function updateAction(Request $request, $id) + public function updateAction(Request $request, mixed $id) { $em = $this->getDoctrine()->getManager(); @@ -165,13 +171,13 @@ class StatusController extends AbstractController $editForm = $this->createEditForm($entity); $editForm->handleRequest($request); - if ($editForm->isValid()) { + if ($editForm->isSubmitted() && $editForm->isValid()) { $em->flush(); - return $this->redirect($this->generateUrl('chill_event_admin_status', ['id' => $id])); + return $this->redirectToRoute('chill_event_admin_status', ['id' => $id]); } - return $this->render('ChillEventBundle:Status:edit.html.twig', [ + return $this->render('@ChillEvent/Status/edit.html.twig', [ 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -204,7 +210,7 @@ class StatusController extends AbstractController * * @return \Symfony\Component\Form\Form The form */ - private function createDeleteForm($id) + private function createDeleteForm(mixed $id) { return $this->createFormBuilder() ->setAction($this->generateUrl('chill_event_admin_status_delete', ['id' => $id])) diff --git a/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadRolesACL.php b/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadRolesACL.php index 26a3144bf..87e676730 100644 --- a/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadRolesACL.php +++ b/src/Bundle/ChillEventBundle/DataFixtures/ORM/LoadRolesACL.php @@ -18,8 +18,6 @@ use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Persistence\ObjectManager; -use function in_array; - /** * Add roles to existing groups. */ @@ -37,10 +35,10 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface foreach (LoadScopes::$references as $scopeRef) { $scope = $this->getReference($scopeRef); - //create permission group + // create permission group switch ($permissionsGroup->getName()) { case 'social': - if ($scope->getName()['en'] === 'administrative') { + if ('administrative' === $scope->getName()['en']) { break 2; // we do not want any power on administrative } @@ -48,7 +46,7 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface case 'administrative': case 'direction': - if (in_array($scope->getName()['en'], ['administrative', 'social'], true)) { + if (\in_array($scope->getName()['en'], ['administrative', 'social'], true)) { break 2; // we do not want any power on social or administrative } @@ -57,10 +55,10 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface printf( 'Adding CHILL_EVENT_UPDATE & CHILL_EVENT_CREATE ' - . '& CHILL_EVENT_PARTICIPATION_UPDATE & CHILL_EVENT_PARTICIPATION_CREATE ' - . '& CHILL_EVENT_SEE & CHILL_EVENT_SEE_DETAILS ' - . 'to %s ' - . "permission group, scope '%s' \n", + .'& CHILL_EVENT_PARTICIPATION_UPDATE & CHILL_EVENT_PARTICIPATION_CREATE ' + .'& CHILL_EVENT_SEE & CHILL_EVENT_SEE_DETAILS ' + .'to %s ' + ."permission group, scope '%s' \n", $permissionsGroup->getName(), $scope->getName()['en'] ); diff --git a/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php b/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php index c3d723652..07c431f2f 100644 --- a/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php +++ b/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php @@ -30,7 +30,7 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config')); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/authorization.yaml'); $loader->load('services/controller.yaml'); @@ -70,7 +70,7 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface */ protected function prependRoute(ContainerBuilder $container) { - //add routes for custom bundle + // add routes for custom bundle $container->prependExtensionConfig('chill_main', [ 'routing' => [ 'resources' => [ diff --git a/src/Bundle/ChillEventBundle/Entity/Event.php b/src/Bundle/ChillEventBundle/Entity/Event.php index cc762e979..5ecc97afd 100644 --- a/src/Bundle/ChillEventBundle/Entity/Event.php +++ b/src/Bundle/ChillEventBundle/Entity/Event.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\EventBundle\Entity; -use ArrayIterator; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; @@ -21,69 +20,65 @@ use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use Traversable; /** * Class Event. * * @ORM\Entity(repositoryClass="Chill\EventBundle\Repository\EventRepository") + * * @ORM\Table(name="chill_event_event") + * * @ORM\HasLifecycleCallbacks */ class Event implements HasCenterInterface, HasScopeInterface { /** - * @var Center * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Center") */ - private $center; + private ?\Chill\MainBundle\Entity\Center $center = null; /** - * @var Scope * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope") */ - private $circle; + private ?\Chill\MainBundle\Entity\Scope $circle = null; /** - * @var DateTime * @ORM\Column(type="datetime") */ - private $date; + private ?\DateTime $date; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** - * @var User * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") */ - private $moderator; + private ?\Chill\MainBundle\Entity\User $moderator = null; /** - * @var string * @ORM\Column(type="string", length=150) */ - private $name; + private ?string $name = null; /** - * @var Participation + * @var Collection + * * @ORM\OneToMany( * targetEntity="Chill\EventBundle\Entity\Participation", * mappedBy="event") */ - private $participations; + private Collection $participations; /** - * @var EventType * @ORM\ManyToOne(targetEntity="Chill\EventBundle\Entity\EventType") */ - private $type; + private ?\Chill\EventBundle\Entity\EventType $type = null; /** * Event constructor. @@ -124,7 +119,7 @@ class Event implements HasCenterInterface, HasScopeInterface /** * Get date. * - * @return DateTime + * @return \DateTime */ public function getDate() { @@ -141,10 +136,7 @@ class Event implements HasCenterInterface, HasScopeInterface return $this->id; } - /** - * @return int - */ - public function getModerator() + public function getModerator(): null|User { return $this->moderator; } @@ -160,25 +152,23 @@ class Event implements HasCenterInterface, HasScopeInterface } /** - * @return Collection + * @return Collection */ - public function getParticipations() + public function getParticipations(): Collection { return new ArrayCollection(iterator_to_array($this->getParticipationsOrdered())); } /** * Sort Collection of Participations. - * - * @return ArrayIterator|Traversable */ - public function getParticipationsOrdered() + public function getParticipationsOrdered(): \ArrayIterator|\Traversable { - $iterator = $this->participations->getIterator(); + $iterator = iterator_to_array($this->participations->getIterator()); - $iterator->uasort(static fn ($first, $second) => strnatcasecmp($first->getPerson()->getFirstName(), $second->getPerson()->getFirstName())); + uasort($iterator, static fn ($first, $second) => strnatcasecmp((string) $first->getPerson()->getFirstName(), (string) $second->getPerson()->getFirstName())); - return $iterator; + return new \ArrayIterator($iterator); } /** @@ -232,19 +222,14 @@ class Event implements HasCenterInterface, HasScopeInterface * * @return Event */ - public function setDate(DateTime $date) + public function setDate(\DateTime $date) { $this->date = $date; return $this; } - /** - * @param int $moderator - * - * @return Event - */ - public function setModerator($moderator) + public function setModerator(User $moderator): self { $this->moderator = $moderator; diff --git a/src/Bundle/ChillEventBundle/Entity/EventType.php b/src/Bundle/ChillEventBundle/Entity/EventType.php index e661a9839..5eef8dc42 100644 --- a/src/Bundle/ChillEventBundle/Entity/EventType.php +++ b/src/Bundle/ChillEventBundle/Entity/EventType.php @@ -19,47 +19,51 @@ use Doctrine\ORM\Mapping as ORM; * Class EventType. * * @ORM\Entity + * * @ORM\Table(name="chill_event_event_type") + * * @ORM\HasLifecycleCallbacks */ class EventType { /** - * @var bool - * @ORM\Column(type="boolean") + * @ORM\Column(type="boolean", nullable=false) */ - private $active; + private bool $active = true; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** * @var array + * * @ORM\Column(type="json") */ private $name; /** - * @var Collection + * @var Collection + * * @ORM\OneToMany( * targetEntity="Chill\EventBundle\Entity\Role", * mappedBy="type") */ - private $roles; + private Collection $roles; /** - * @var Collection + * @var Collection + * * @ORM\OneToMany( * targetEntity="Chill\EventBundle\Entity\Status", * mappedBy="type") */ - private $statuses; + private Collection $statuses; /** * Constructor. diff --git a/src/Bundle/ChillEventBundle/Entity/Participation.php b/src/Bundle/ChillEventBundle/Entity/Participation.php index 38c849535..8dda85c99 100644 --- a/src/Bundle/ChillEventBundle/Entity/Participation.php +++ b/src/Bundle/ChillEventBundle/Entity/Participation.php @@ -11,7 +11,6 @@ declare(strict_types=1); namespace Chill\EventBundle\Entity; -use ArrayAccess; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; @@ -19,70 +18,63 @@ use Chill\MainBundle\Entity\Scope; use Chill\PersonBundle\Entity\Person; use DateTime; use Doctrine\ORM\Mapping as ORM; -use RuntimeException; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use function in_array; - /** * Class Participation. * * @ORM\Entity( * repositoryClass="Chill\EventBundle\Repository\ParticipationRepository") + * * @ORM\Table(name="chill_event_participation") + * * @ORM\HasLifecycleCallbacks */ -class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterface +class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterface { /** - * @var Event * @ORM\ManyToOne( * targetEntity="Chill\EventBundle\Entity\Event", * inversedBy="participations") */ - private $event; + private ?\Chill\EventBundle\Entity\Event $event = null; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** - * @var DateTime * @ORM\Column(type="datetime") */ - private $lastUpdate; + private ?\DateTime $lastUpdate = null; /** - * @var Person * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person") */ - private $person; + private ?\Chill\PersonBundle\Entity\Person $person = null; /** - * @var Role * @ORM\ManyToOne(targetEntity="Chill\EventBundle\Entity\Role") */ - private $role; + private ?\Chill\EventBundle\Entity\Role $role = null; /** - * @var Status * @ORM\ManyToOne(targetEntity="Chill\EventBundle\Entity\Status") */ - private $status; + private ?\Chill\EventBundle\Entity\Status $status = null; /** * @return Center */ public function getCenter() { - if ($this->getEvent() === null) { - throw new RuntimeException('The event is not linked with this instance. ' - . 'You should initialize the event with a valid center before.'); + if (null === $this->getEvent()) { + throw new \RuntimeException('The event is not linked with this instance. You should initialize the event with a valid center before.'); } return $this->getEvent()->getCenter(); @@ -90,10 +82,8 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Get event. - * - * @return Event */ - public function getEvent() + public function getEvent(): null|Event { return $this->event; } @@ -111,7 +101,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Get lastUpdate. * - * @return DateTime + * @return \DateTime */ public function getLastUpdate() { @@ -130,10 +120,8 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Get role. - * - * @return Role */ - public function getRole() + public function getRole(): null|Role { return $this->role; } @@ -143,9 +131,8 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac */ public function getScope() { - if ($this->getEvent() === null) { - throw new RuntimeException('The event is not linked with this instance. ' - . 'You should initialize the event with a valid center before.'); + if (null === $this->getEvent()) { + throw new \RuntimeException('The event is not linked with this instance. You should initialize the event with a valid center before.'); } return $this->getEvent()->getCircle(); @@ -153,10 +140,8 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Get status. - * - * @return Status */ - public function getStatus() + public function getStatus(): null|Status { return $this->status; } @@ -169,7 +154,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac */ public function isConsistent(ExecutionContextInterface $context) { - if ($this->getEvent() === null || $this->getRole() === null || $this->getStatus() === null) { + if (null === $this->getEvent() || null === $this->getRole() || null === $this->getStatus()) { return; } @@ -192,46 +177,28 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac } } - /** - * @param mixed $offset - * - * @return bool - */ - public function offsetExists($offset): bool + public function offsetExists(mixed $offset): bool { - return in_array($offset, [ + return \in_array($offset, [ 'person', 'role', 'status', 'event', ], true); } /** - * @param mixed $offset - * * @return Event|Person|Role|Status */ - public function offsetGet($offset): mixed + public function offsetGet(mixed $offset): mixed { - switch ($offset) { - case 'person': - return $this->getPerson(); - case 'role': - return $this->getRole(); - case 'status': - return $this->getStatus(); - case 'event': - return $this->getEvent(); - default: - throw new \LogicException("this offset does not exists : " . $offset); - } + return match ($offset) { + 'person' => $this->getPerson(), + 'role' => $this->getRole(), + 'status' => $this->getStatus(), + 'event' => $this->getEvent(), + default => throw new \LogicException('this offset does not exists : '.$offset), + }; } - /** - * @param mixed $offset - * @param mixed $value - * - * @return void - */ - public function offsetSet($offset, $value): void + public function offsetSet(mixed $offset, mixed $value): void { switch ($offset) { case 'person': @@ -256,10 +223,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac } } - /** - * @param mixed $offset - */ - public function offsetUnset($offset): void + public function offsetUnset(mixed $offset): void { $this->offsetSet($offset, null); } @@ -267,11 +231,9 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Set event. * - * @param Event $event - * * @return Participation */ - public function setEvent(?Event $event = null) + public function setEvent(Event $event = null) { if ($this->event !== $event) { $this->update(); @@ -285,11 +247,9 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Set person. * - * @param Person $person - * * @return Participation */ - public function setPerson(?Person $person = null) + public function setPerson(Person $person = null) { if ($person !== $this->person) { $this->update(); @@ -303,11 +263,9 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Set role. * - * @param Role $role - * * @return Participation */ - public function setRole(?Role $role = null) + public function setRole(Role $role = null) { if ($role !== $this->role) { $this->update(); @@ -320,11 +278,9 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac /** * Set status. * - * @param Status $status - * * @return Participation */ - public function setStatus(?Status $status = null) + public function setStatus(Status $status = null) { if ($this->status !== $status) { $this->update(); @@ -342,7 +298,7 @@ class Participation implements ArrayAccess, HasCenterInterface, HasScopeInterfac */ protected function update() { - $this->lastUpdate = new DateTime('now'); + $this->lastUpdate = new \DateTime('now'); return $this; } diff --git a/src/Bundle/ChillEventBundle/Entity/Role.php b/src/Bundle/ChillEventBundle/Entity/Role.php index b508cda43..3d2264d2f 100644 --- a/src/Bundle/ChillEventBundle/Entity/Role.php +++ b/src/Bundle/ChillEventBundle/Entity/Role.php @@ -17,39 +17,40 @@ use Doctrine\ORM\Mapping as ORM; * Class Role. * * @ORM\Entity + * * @ORM\Table(name="chill_event_role") + * * @ORM\HasLifecycleCallbacks */ class Role { /** - * @var bool - * @ORM\Column(type="boolean") + * @ORM\Column(type="boolean", nullable=false) */ - private $active; + private bool $active = true; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** * @var array + * * @ORM\Column(type="json") */ private $name; /** - * @var EventType * @ORM\ManyToOne( * targetEntity="Chill\EventBundle\Entity\EventType", * inversedBy="roles") */ - private $type; + private ?\Chill\EventBundle\Entity\EventType $type = null; /** * Get active. @@ -122,11 +123,9 @@ class Role /** * Set type. * - * @param EventType $type - * * @return Role */ - public function setType(?EventType $type = null) + public function setType(EventType $type = null) { $this->type = $type; diff --git a/src/Bundle/ChillEventBundle/Entity/Status.php b/src/Bundle/ChillEventBundle/Entity/Status.php index c0955fd41..22fe8e3ed 100644 --- a/src/Bundle/ChillEventBundle/Entity/Status.php +++ b/src/Bundle/ChillEventBundle/Entity/Status.php @@ -17,39 +17,40 @@ use Doctrine\ORM\Mapping as ORM; * Class Status. * * @ORM\Entity + * * @ORM\Table(name="chill_event_status") + * * @ORM\HasLifecycleCallbacks */ class Status { /** - * @var bool - * @ORM\Column(type="boolean") + * @ORM\Column(type="boolean", nullable=false) */ - private $active; + private bool $active = true; /** - * @var int - * * @ORM\Id + * * @ORM\Column(name="id", type="integer") + * * @ORM\GeneratedValue(strategy="AUTO") */ - private $id; + private ?int $id = null; /** * @var array + * * @ORM\Column(type="json") */ private $name; /** - * @var EventType * @ORM\ManyToOne( * targetEntity="Chill\EventBundle\Entity\EventType", * inversedBy="statuses") */ - private $type; + private ?\Chill\EventBundle\Entity\EventType $type = null; /** * Get active. @@ -122,11 +123,9 @@ class Status /** * Set type. * - * @param EventType $type - * * @return Status */ - public function setType(?EventType $type = null) + public function setType(EventType $type = null) { $this->type = $type; diff --git a/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php b/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php index 962799dbc..7507550c2 100644 --- a/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php +++ b/src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php @@ -13,14 +13,9 @@ namespace Chill\EventBundle\Form\ChoiceLoader; use Chill\EventBundle\Entity\Event; use Doctrine\ORM\EntityRepository; -use RuntimeException; use Symfony\Component\Form\ChoiceList\ChoiceListInterface; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; -use function call_user_func; -use function count; -use function in_array; - /** * Class EventChoiceLoader. */ @@ -46,7 +41,7 @@ class EventChoiceLoader implements ChoiceLoaderInterface */ public function __construct( EntityRepository $eventRepository, - ?array $centers = null + array $centers = null ) { $this->eventRepository = $eventRepository; @@ -62,7 +57,7 @@ class EventChoiceLoader implements ChoiceLoaderInterface { return new \Symfony\Component\Form\ChoiceList\ArrayChoiceList( $this->lazyLoadedEvents, - static fn (Event $p) => call_user_func($value, $p) + static fn (Event $p) => \call_user_func($value, $p) ); } @@ -84,9 +79,9 @@ class EventChoiceLoader implements ChoiceLoaderInterface if ( $this->hasCenterFilter() - && !in_array($event->getCenter(), $this->centers, true) + && !\in_array($event->getCenter(), $this->centers, true) ) { - throw new RuntimeException('chosen an event not in correct center'); + throw new \RuntimeException('chosen an event not in correct center'); } $choices[] = $event; @@ -111,7 +106,7 @@ class EventChoiceLoader implements ChoiceLoaderInterface continue; } - $id = call_user_func($value, $choice); + $id = \call_user_func($value, $choice); $values[] = $id; $this->lazyLoadedEvents[$id] = $choice; } @@ -124,6 +119,6 @@ class EventChoiceLoader implements ChoiceLoaderInterface */ protected function hasCenterFilter() { - return count($this->centers) > 0; + return \count($this->centers) > 0; } } diff --git a/src/Bundle/ChillEventBundle/Form/EventType.php b/src/Bundle/ChillEventBundle/Form/EventType.php index a72b90494..a06999d2b 100644 --- a/src/Bundle/ChillEventBundle/Form/EventType.php +++ b/src/Bundle/ChillEventBundle/Form/EventType.php @@ -19,7 +19,6 @@ use Chill\MainBundle\Form\Type\UserPickerType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Security\Core\Role\Role; class EventType extends AbstractType { @@ -59,13 +58,13 @@ class EventType extends AbstractType $resolver ->setRequired(['center', 'role']) ->setAllowedTypes('center', Center::class) - ->setAllowedTypes('role', Role::class); + ->setAllowedTypes('role', 'string'); } /** * @return string */ - public function getName() + public function getBlockPrefix() { return 'chill_eventbundle_event'; } diff --git a/src/Bundle/ChillEventBundle/Form/EventTypeType.php b/src/Bundle/ChillEventBundle/Form/EventTypeType.php index bab13c374..4b09daef0 100644 --- a/src/Bundle/ChillEventBundle/Form/EventTypeType.php +++ b/src/Bundle/ChillEventBundle/Form/EventTypeType.php @@ -14,7 +14,6 @@ namespace Chill\EventBundle\Form; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; class EventTypeType extends AbstractType { @@ -28,12 +27,12 @@ class EventTypeType extends AbstractType /** * @return string */ - public function getName() + public function getBlockPrefix() { return 'chill_eventbundle_eventtype'; } - public function setDefaultOptions(OptionsResolverInterface $resolver) + public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => \Chill\EventBundle\Entity\EventType::class, diff --git a/src/Bundle/ChillEventBundle/Form/ParticipationType.php b/src/Bundle/ChillEventBundle/Form/ParticipationType.php index 998dc91a3..af1854954 100644 --- a/src/Bundle/ChillEventBundle/Form/ParticipationType.php +++ b/src/Bundle/ChillEventBundle/Form/ParticipationType.php @@ -15,7 +15,7 @@ use Chill\EventBundle\Entity\EventType; use Chill\EventBundle\Entity\Status; use Chill\EventBundle\Form\Type\PickRoleType; use Chill\EventBundle\Form\Type\PickStatusType; -use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -25,17 +25,9 @@ use Symfony\Component\OptionsResolver\OptionsResolver; * * If the `event` option is defined, the role will be restricted */ -class ParticipationType extends AbstractType +final class ParticipationType extends AbstractType { - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; - - public function __construct(TranslatableStringHelper $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {} public function buildForm(FormBuilderInterface $builder, array $options) { diff --git a/src/Bundle/ChillEventBundle/Form/RoleType.php b/src/Bundle/ChillEventBundle/Form/RoleType.php index 519e814cf..8b9f27be2 100644 --- a/src/Bundle/ChillEventBundle/Form/RoleType.php +++ b/src/Bundle/ChillEventBundle/Form/RoleType.php @@ -13,23 +13,14 @@ namespace Chill\EventBundle\Form; use Chill\EventBundle\Entity\EventType; use Chill\MainBundle\Form\Type\TranslatableStringFormType; -use Chill\MainBundle\Templating\TranslatableStringHelper; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; -class RoleType extends AbstractType +final class RoleType extends AbstractType { - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; - - public function __construct(TranslatableStringHelper $translatableStringHelper) - { - $this->translatableStringHelper = $translatableStringHelper; - } + public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -45,12 +36,12 @@ class RoleType extends AbstractType /** * @return string */ - public function getName() + public function getBlockPrefix() { return 'chill_eventbundle_role'; } - public function setDefaultOptions(OptionsResolverInterface $resolver) + public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => \Chill\EventBundle\Entity\Role::class, diff --git a/src/Bundle/ChillEventBundle/Form/StatusType.php b/src/Bundle/ChillEventBundle/Form/StatusType.php index 5801f3264..7e8c8c1b9 100644 --- a/src/Bundle/ChillEventBundle/Form/StatusType.php +++ b/src/Bundle/ChillEventBundle/Form/StatusType.php @@ -15,7 +15,6 @@ use Chill\EventBundle\Form\Type\PickEventTypeType; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; class StatusType extends AbstractType { @@ -30,12 +29,12 @@ class StatusType extends AbstractType /** * @return string */ - public function getName() + public function getBlockPrefix() { return 'chill_eventbundle_status'; } - public function setDefaultOptions(OptionsResolverInterface $resolver) + public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver) { $resolver->setDefaults([ '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 05436b3e8..2b85a60c8 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickEventType.php @@ -18,67 +18,32 @@ use Chill\EventBundle\Search\EventSearch; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\GroupCenter; use Chill\MainBundle\Entity\User; -use Chill\MainBundle\Security\Authorization\AuthorizationHelper; -use RuntimeException; +use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Finder\Exception\AccessDeniedException; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Role\Role; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; -use function in_array; -use function is_array; - /** * Class PickEventType. */ -class PickEventType extends AbstractType +final class PickEventType extends AbstractType { - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; - - /** - * @var EventRepository - */ - protected $eventRepository; - - /** - * @var TranslatorInterface - */ - protected $translator; - - /** - * @var UrlGeneratorInterface - */ - protected $urlGenerator; - - /** - * @var User - */ - protected $user; - /** * PickEventType constructor. */ public function __construct( - EventRepository $eventRepository, - TokenStorageInterface $tokenStorage, - AuthorizationHelper $authorizationHelper, - UrlGeneratorInterface $urlGenerator, - TranslatorInterface $translator - ) { - $this->eventRepository = $eventRepository; - $this->user = $tokenStorage->getToken()->getUser(); - $this->authorizationHelper = $authorizationHelper; - $this->urlGenerator = $urlGenerator; - $this->translator = $translator; - } + private readonly EventRepository $eventRepository, + private readonly AuthorizationHelperInterface $authorizationHelper, + private readonly UrlGeneratorInterface $urlGenerator, + private readonly TranslatorInterface $translator, + private readonly Security $security + ) {} public function buildView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options) { @@ -103,13 +68,13 @@ class PickEventType extends AbstractType ->setDefault('centers', null); $resolver ->setDefined('role') - ->addAllowedTypes('role', [Role::class, 'null']) + ->addAllowedTypes('role', ['string', 'null']) ->setDefault('role', null); // add the default options $resolver->setDefaults([ 'class' => Event::class, - 'choice_label' => static fn (Event $e) => $e->getDate()->format('d/m/Y, H:i') . ' → ' . + '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', @@ -123,10 +88,7 @@ class PickEventType extends AbstractType ]); } - /** - * @return string|null - */ - public function getParent() + public function getParent(): ?string { return EntityType::class; } @@ -136,15 +98,21 @@ class PickEventType extends AbstractType */ protected function filterCenters(Options $options) { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + return []; + } + // option role if (null === $options['role']) { $centers = array_map( static fn (GroupCenter $g) => $g->getCenter(), - $this->user->getGroupCenters()->toArray() + $user->getGroupCenters()->toArray() ); } else { $centers = $this->authorizationHelper->getReachableCenters( - $this->user, + $user, (string) $options['role']->getRole() ); } @@ -155,18 +123,17 @@ class PickEventType extends AbstractType $selectedCenters = $centers; } else { $selectedCenters = []; - $optionsCenters = is_array($options['centers']) ? + $optionsCenters = \is_array($options['centers']) ? $options['centers'] : [$options['centers']]; foreach ($optionsCenters as $c) { // check that every member of the array is a center if (!$c instanceof Center) { - throw new RuntimeException('Every member of the "centers" ' - . 'option must be an instance of ' . Center::class); + throw new \RuntimeException('Every member of the "centers" option must be an instance of '.Center::class); } if ( - !in_array($c->getId(), array_map( + !\in_array($c->getId(), array_map( static fn (Center $c) => $c->getId(), $centers ), true) diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php b/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php index 8fd8ff7d7..c8d69c119 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickRoleType.php @@ -13,8 +13,8 @@ namespace Chill\EventBundle\Form\Type; use Chill\EventBundle\Entity\EventType; use Chill\EventBundle\Entity\Role; -use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\EntityRepository; +use Chill\EventBundle\Repository\RoleRepository; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -26,32 +26,13 @@ use Symfony\Contracts\Translation\TranslatorInterface; /** * Allow to pick a choice amongst different choices. */ -class PickRoleType extends AbstractType +final class PickRoleType extends AbstractType { - /** - * @var EntityRepository - */ - protected $roleRepository; - - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; - - /** - * @var TranslatorInterface - */ - protected $translator; - public function __construct( - TranslatableStringHelper $translatableStringHelper, - TranslatorInterface $translator, - EntityRepository $roleRepository - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->translator = $translator; - $this->roleRepository = $roleRepository; - } + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly TranslatorInterface $translator, + private readonly RoleRepository $roleRepository + ) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -76,7 +57,7 @@ class PickRoleType extends AbstractType $form = $event->getForm(); $name = $form->getName(); $config = $form->getConfig(); - $type = $config->getType()->getName(); + $type = $config->getType()->getBlockPrefix(); $options = $config->getOptions(); $form->getParent()->add($name, $type, array_replace($options, [ @@ -113,9 +94,9 @@ class PickRoleType extends AbstractType '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') . ')'), + 'choice_label' => static fn (Role $r) => $translatableStringHelper->localize($r->getName()). + (true === $r->getActive() ? '' : + ' ('.$translator->trans('unactive').')'), ]); } diff --git a/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php b/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php index dcc3ba205..3f4ab3624 100644 --- a/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php +++ b/src/Bundle/ChillEventBundle/Form/Type/PickStatusType.php @@ -13,8 +13,8 @@ namespace Chill\EventBundle\Form\Type; use Chill\EventBundle\Entity\EventType; use Chill\EventBundle\Entity\Status; -use Chill\MainBundle\Templating\TranslatableStringHelper; -use Doctrine\ORM\EntityRepository; +use Chill\EventBundle\Repository\StatusRepository; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -31,32 +31,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; * - event_type : restricts to a certain event type. Default null (= all event types) * - active_only: restricts to active type only. Default true */ -class PickStatusType extends AbstractType +final class PickStatusType extends AbstractType { - /** - * @var EntityRepository - */ - protected $statusRepository; - - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; - - /** - * @var TranslatorInterface - */ - protected $translator; - - public function __construct( - TranslatableStringHelper $translatableStringHelper, - TranslatorInterface $translator, - EntityRepository $statusRepository - ) { - $this->translatableStringHelper = $translatableStringHelper; - $this->translator = $translator; - $this->statusRepository = $statusRepository; - } + public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, protected TranslatorInterface $translator, protected StatusRepository $statusRepository) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -79,7 +56,7 @@ class PickStatusType extends AbstractType $form = $event->getForm(); $name = $form->getName(); $config = $form->getConfig(); - $type = $config->getType()->getName(); + $type = $config->getType()->getBlockPrefix(); $options = $config->getOptions(); $form->getParent()->add($name, $type, array_replace($options, [ 'group_by' => fn (Status $s) => $this->translatableStringHelper->localize($s->getType()->getName()), @@ -114,9 +91,9 @@ class PickStatusType extends AbstractType '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') . ')'), + 'choice_label' => static fn (Status $s) => $translatableStringHelper->localize($s->getName()). + (true === $s->getActive() ? '' : + ' ('.$translator->trans('unactive').')'), ]); } diff --git a/src/Bundle/ChillEventBundle/Repository/EventRepository.php b/src/Bundle/ChillEventBundle/Repository/EventRepository.php index c696709db..7406748b4 100644 --- a/src/Bundle/ChillEventBundle/Repository/EventRepository.php +++ b/src/Bundle/ChillEventBundle/Repository/EventRepository.php @@ -11,9 +11,17 @@ declare(strict_types=1); namespace Chill\EventBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Chill\EventBundle\Entity\Event; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; /** * Class EventRepository. */ -class EventRepository extends EntityRepository {} +class EventRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Event::class); + } +} diff --git a/src/Bundle/ChillEventBundle/Repository/ParticipationRepository.php b/src/Bundle/ChillEventBundle/Repository/ParticipationRepository.php index cc4bd6f51..7c0c13edf 100644 --- a/src/Bundle/ChillEventBundle/Repository/ParticipationRepository.php +++ b/src/Bundle/ChillEventBundle/Repository/ParticipationRepository.php @@ -11,23 +11,26 @@ declare(strict_types=1); namespace Chill\EventBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Chill\EventBundle\Entity\Participation; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; /** * Class ParticipationRepository. */ -class ParticipationRepository extends EntityRepository +class ParticipationRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Participation::class); + } + /** * Count number of participations per person. * - * @param $person_id - * * @throws \Doctrine\ORM\NonUniqueResultException - * - * @return mixed */ - public function countByPerson($person_id) + public function countByPerson($person_id): int { return $this->createQueryBuilder('p') ->select('COUNT (p.id)') @@ -39,13 +42,6 @@ class ParticipationRepository extends EntityRepository /** * Return paginated participations for a person and in reachables circles. - * - * @param $person_id - * @param $reachablesCircles - * @param $first - * @param $max - * - * @return mixed */ public function findByPersonInCircle($person_id, $reachablesCircles, $first, $max) { diff --git a/src/Bundle/ChillEventBundle/Repository/RoleRepository.php b/src/Bundle/ChillEventBundle/Repository/RoleRepository.php new file mode 100644 index 000000000..fa0524a6d --- /dev/null +++ b/src/Bundle/ChillEventBundle/Repository/RoleRepository.php @@ -0,0 +1,24 @@ +{{ 'Event search'|trans }} -

    {% transchoice total with { '%pattern%' : pattern } %}%total% events match the search %pattern%{% endtranschoice %}

    +

    + {{ 'total events match the search'|trans({'total' : total}) }} : + + {{ pattern }} + +