Pārlūkot izejas kodu

Merge branch 'feature/V8-4179' into develop and resolve phpstan warnings

Conflicts:
	src/Repository/Access/AccessRepository.php
	src/Service/ApiLegacy/ApiLegacyRequestService.php
	src/Service/OnChange/Organization/OnSubdomainChange.php
	src/State/Processor/EntityProcessor.php
	src/State/Provider/Core/DownloadRequestProvider.php
Olivier Massot 2 gadi atpakaļ
vecāks
revīzija
e2dd7949de
100 mainītis faili ar 671 papildinājumiem un 514 dzēšanām
  1. 4 1
      .gitignore
  2. 8 0
      .gitlab-ci.yml
  3. 14 2
      composer.json
  4. 0 5
      phpstan.neon
  5. 12 0
      phpstan.neon.dist
  6. 2 2
      public/index.php
  7. 18 0
      readme.md
  8. 8 0
      src/ApiResources/Enum/Enum.php
  9. 1 1
      src/ApiResources/Export/ExportRequest.php
  10. 1 1
      src/ApiResources/Export/ExportRequestInterface.php
  11. 1 0
      src/ApiResources/Export/LicenceCmf/LicenceCmfOrganizationER.php
  12. 17 1
      src/ApiResources/Profile/AccessProfile.php
  13. 17 0
      src/ApiResources/Profile/OrganizationProfile.php
  14. 8 0
      src/Attribute/ActivityYearConstraintAware.php
  15. 5 0
      src/Attribute/BillingSettingDefaultValue.php
  16. 8 0
      src/Attribute/DateTimeConstraintAware.php
  17. 3 0
      src/Attribute/OrganizationDefaultValue.php
  18. 4 1
      src/Commands/AddSubdomainCommand.php
  19. 4 2
      src/Commands/CronCommand.php
  20. 1 1
      src/Commands/DolibarrSyncCommand.php
  21. 3 3
      src/Commands/PostUpgrade/V0_2/PostUpgradeCommand.php
  22. 19 0
      src/Doctrine/AbstractExtension.php
  23. 2 2
      src/Doctrine/Access/AccessExtensionInterface.php
  24. 17 0
      src/Doctrine/Access/CurrentAccessExtension.php
  25. 1 1
      src/Doctrine/Access/Extensions/DateTimeConstraintExtension.php
  26. 1 2
      src/Doctrine/Access/Extensions/StudentsExtension.php
  27. 28 6
      src/Entity/Access/Access.php
  28. 2 1
      src/Entity/Access/AccessFamily.php
  29. 0 113
      src/Entity/Access/AccessFictionalIntangible.php
  30. 17 1
      src/Entity/Access/PersonalizedList.php
  31. 2 1
      src/Entity/Billing/AccessIntangible.php
  32. 1 1
      src/Entity/Billing/BergerLevrault.php
  33. 5 0
      src/Entity/Billing/BillAccessDetail.php
  34. 2 1
      src/Entity/Billing/BillAccounting.php
  35. 1 1
      src/Entity/Billing/BillPayment.php
  36. 4 4
      src/Entity/Billing/ResidenceArea.php
  37. 0 36
      src/Entity/Billing/SddBank.php
  38. 0 36
      src/Entity/Billing/SddRegie.php
  39. 2 2
      src/Entity/Booking/Work.php
  40. 1 1
      src/Entity/Core/ContactPoint.php
  41. 1 1
      src/Entity/Core/Notification.php
  42. 1 1
      src/Entity/Education/Cycle.php
  43. 1 1
      src/Entity/Education/Education.php
  44. 1 1
      src/Entity/Education/EducationNotationConfig.php
  45. 1 1
      src/Entity/Education/EducationTiming.php
  46. 3 3
      src/Entity/Message/AbstractMessage.php
  47. 23 1
      src/Entity/Message/ReportSms.php
  48. 1 1
      src/Entity/Network/Network.php
  49. 2 84
      src/Entity/Organization/Organization.php
  50. 1 1
      src/Entity/Organization/OrganizationAddressPostal.php
  51. 2 2
      src/Entity/Organization/OrganizationLicence.php
  52. 1 2
      src/Entity/Organization/Parameters.php
  53. 45 11
      src/Entity/Organization/Settings.php
  54. 11 1
      src/Entity/Person/Person.php
  55. 1 1
      src/Entity/Person/PersonAddressPostal.php
  56. 1 1
      src/Entity/Place/Room.php
  57. 12 8
      src/Entity/Public/FederationStructure.php
  58. 3 2
      src/Entity/Public/PublicEvent.php
  59. 6 1
      src/Enum/Access/FunctionEnum.php
  60. 21 9
      src/EventListener/DoctrineFilter/DoctrineFilterListener.php
  61. 1 1
      src/EventSubscriber/ApiResourcesValidatorSubscriber.php
  62. 4 3
      src/EventSubscriber/ElasticaPostTransformSubscriber.php
  63. 18 15
      src/Filter/DoctrineFilter/AbstractTimeFilter.php
  64. 6 4
      src/Filter/DoctrineFilter/ActivityYearFilter.php
  65. 1 1
      src/Filter/DoctrineFilter/DateTimeFilter.php
  66. 12 2
      src/Filter/Person/FullNameFilter.php
  67. 15 5
      src/Filter/Utils/DistanceFilter.php
  68. 12 2
      src/Filter/Utils/FindInSetFilter.php
  69. 12 2
      src/Filter/Utils/InFilter.php
  70. 1 1
      src/Message/Command/Parameters/AverageChange.php
  71. 1 1
      src/Message/Handler/ExportHandler.php
  72. 1 1
      src/Message/Handler/MailerHandler.php
  73. 1 1
      src/Message/Handler/Parameters/AverageChangeHandler.php
  74. 1 1
      src/Message/Handler/Typo3/Typo3DeleteCommandHandler.php
  75. 1 1
      src/Message/Handler/Typo3/Typo3UndeleteCommandHandler.php
  76. 1 1
      src/Message/Handler/Typo3/Typo3UpdateCommandHandler.php
  77. 5 1
      src/OpenApi/OpenApiFactory.php
  78. 18 8
      src/Repository/Access/AccessRepository.php
  79. 5 4
      src/Repository/Booking/CourseRepository.php
  80. 2 2
      src/Repository/Core/ContactPointRepository.php
  81. 1 1
      src/Repository/Network/NetworkOrganizationRepository.php
  82. 1 1
      src/Repository/Organization/OrganizationAddressPostalRepository.php
  83. 1 1
      src/Security/Voter/BankAccountVoter.php
  84. 1 1
      src/Security/Voter/ContactPointVoter.php
  85. 1 1
      src/Security/Voter/CotisationVoter.php
  86. 2 1
      src/Security/Voter/ModuleVoter.php
  87. 3 1
      src/Security/Voter/SwitchUserVoter.php
  88. 9 1
      src/Serializer/AccessContextBuilder.php
  89. 35 2
      src/Serializer/DefaultNormalizer.php
  90. 5 5
      src/Service/Access/Utils.php
  91. 17 6
      src/Service/ApiLegacy/ApiLegacyRequestService.php
  92. 19 0
      src/Service/ApiResourceBuilder/Dolibarr/DolibarrAccountBuilder.php
  93. 16 16
      src/Service/Constraint/AbstractTimeConstraintUtils.php
  94. 12 12
      src/Service/Constraint/ActivityYearConstraint.php
  95. 15 15
      src/Service/Constraint/DateTimeConstraint.php
  96. 0 1
      src/Service/Cotisation/Utils.php
  97. 5 5
      src/Service/Cron/Job/CleanTempFiles.php
  98. 1 2
      src/Service/Cron/UI/ConsoleUI.php
  99. 7 3
      src/Service/Dolibarr/DolibarrApiService.php
  100. 20 20
      src/Service/Dolibarr/DolibarrSyncService.php

+ 4 - 1
.gitignore

@@ -33,8 +33,11 @@ symfony.lock
 
 /coverage/
 
-
 ###> phpunit/phpunit ###
 /phpunit.xml
 .phpunit.result.cache
 ###< phpunit/phpunit ###
+
+###> phpstan ###
+.phpstan.neon
+###< phpstan ###

+ 8 - 0
.gitlab-ci.yml

@@ -14,6 +14,14 @@ before_script:
   - bash tests/ci_docker_install.sh > /dev/null
   - php -v
 
+static_analysis:
+  script:
+    - php --version && php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format gitlab > phpstan.json
+  artifacts:
+    when: always
+    reports:
+      codequality: phpstan.json
+
 unit:
   stage: test
 

+ 14 - 2
composer.json

@@ -67,15 +67,21 @@
     },
     "require-dev": {
         "cyclonedx/cyclonedx-php-composer": "^3.4",
+        "dg/bypass-finals": "^1.4",
         "hautelook/alice-bundle": "^2.11",
+        "phpstan/extension-installer": "^1.2",
         "phpstan/phpstan": "^1.9",
+        "phpstan/phpstan-doctrine": "^1.3",
+        "phpstan/phpstan-phpunit": "^1.3",
+        "phpstan/phpstan-symfony": "^1.2",
         "phpunit/phpunit": "^9.6",
         "rector/rector": "^0.15.13",
         "symfony/debug-bundle": "6.2.*",
         "symfony/maker-bundle": "^1.21",
         "symfony/phpunit-bridge": "^6.2",
         "symfony/stopwatch": "6.2.*",
-        "symfony/web-profiler-bundle": "6.2.*"
+        "symfony/web-profiler-bundle": "6.2.*",
+        "timeweb/phpstan-enum": "^3.1"
     },
     "config": {
         "optimize-autoloader": true,
@@ -85,7 +91,8 @@
         "sort-packages": true,
         "allow-plugins": {
             "cyclonedx/cyclonedx-php-composer": true,
-            "symfony/flex": true
+            "symfony/flex": true,
+            "phpstan/extension-installer": true
         }
     },
     "autoload": {
@@ -126,6 +133,11 @@
         "symfony": {
             "allow-contrib": false,
             "require": "6.2.*"
+        },
+        "phpstan": {
+            "includes": [
+                "extension.neon"
+            ]
         }
     }
 }

+ 0 - 5
phpstan.neon

@@ -1,5 +0,0 @@
-# https://phpstan.org/config-reference
-parameters:
-	level: 5
-	paths:
-		- src

+ 12 - 0
phpstan.neon.dist

@@ -0,0 +1,12 @@
+# https://phpstan.org/config-reference
+parameters:
+	level: 6
+	treatPhpDocTypesAsCertain: false
+	checkGenericClassInNonGenericObjectType: false
+
+# on ignore les erreurs qui proviennent d'un importe d'un attribut PhpStorm
+# on ignore les erreurs qui imposent d'indiquer le type d'un iterable dans la phpDoc (cf: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type)
+	ignoreErrors :
+	    - '#Attribute class JetBrains\\PhpStorm\\[a-zA-Z]+ does not exist.#'
+	paths:
+		- src

+ 2 - 2
public/index.php

@@ -24,7 +24,7 @@ if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
 }
 
 // If the header is set
-//if (isset($_SERVER['HTTP_BLACKFIRETRIGGER'])) {
+if (isset($_SERVER['HTTP_BLACKFIRETRIGGER'])) {
     $config = new \Blackfire\ClientConfiguration();
     $config->setClientId($_ENV['BLACKFIRE_CLIENT_ID']);
     $config->setClientToken($_ENV['BLACKFIRE_CLIENT_TOKEN']);
@@ -33,7 +33,7 @@ if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
     $blackfire = new \Blackfire\Client($config);
     // then start the probe
     $probe = $blackfire->createProbe();
-//}
+}
 
 $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
 $request = Request::createFromGlobals();

+ 18 - 0
readme.md

@@ -29,3 +29,21 @@ Pour exécuter une analyse du code :
 
 > Voir : https://phpstan.org/user-guide/getting-started
 
+# PHPStan
+
+Le fichier comportant la configuration pour chacun est phpstan.neon.dist
+Le fichier phpstan.neon n'est pas versionné et surcharge les valeurs du .dist
+
+## Principales commandes 
+
+Pour lancer l'analyse
+
+    vendor/bin/phpstan analyse
+
+Pour vider le cache (utiles entre chaque analyse si les modifications ne sont pas prises en compte)
+
+    vendor/bin/phpstan clear-result-cache
+
+> Voir : https://phpstan.org/
+
+

+ 8 - 0
src/ApiResources/Enum/Enum.php

@@ -25,6 +25,7 @@ class Enum implements ApiResourcesInterface
     #[ApiProperty(identifier: true)]
     private string $name;
 
+    /** @var list<string> $items */
     private array $items = [];
 
     public function __construct()
@@ -42,12 +43,19 @@ class Enum implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @param list<string> $items
+     * @return $this
+     */
     public function setItems(array $items): self
     {
         $this->items = $items;
         return $this;
     }
 
+    /**
+     * @return list<string>
+     */
     public function getItems(): array
     {
         return $this->items;

+ 1 - 1
src/ApiResources/Export/ExportRequest.php

@@ -3,7 +3,7 @@ declare(strict_types=1);
 
 namespace App\ApiResources\Export;
 
-use ApiPlatform\Core\Annotation\ApiProperty;
+use ApiPlatform\Metadata\ApiProperty;
 use Symfony\Component\Validator\Constraints as Assert;
 use App\Enum\Export\ExportFormatEnum;
 

+ 1 - 1
src/ApiResources/Export/ExportRequestInterface.php

@@ -2,7 +2,7 @@
 
 namespace App\ApiResources\Export;
 
-class ExportRequestInterface
+interface ExportRequestInterface
 {
 
 }

+ 1 - 0
src/ApiResources/Export/LicenceCmf/LicenceCmfOrganizationER.php

@@ -10,6 +10,7 @@ use ApiPlatform\Metadata\Put;
 use ApiPlatform\Metadata\Get;
 use ApiPlatform\Metadata\ApiResource;
 use App\ApiResources\Export\ExportRequest;
+use App\ApiResources\Export\ExportRequestInterface;
 use App\State\Processor\Export\LicenceCmf\ExportRequestProcessor;
 use Symfony\Component\Validator\Constraints as Assert;
 

+ 17 - 1
src/ApiResources/Profile/AccessProfile.php

@@ -24,7 +24,7 @@ use Doctrine\Common\Collections\Collection;
         new Get(
             uriTemplate: '/my_profile/{id}',
             defaults: ['id' => 0],
-            normalizationContext: ['groups' => ['access_profile_read:output']],
+            normalizationContext: ['groups' => ['access_profile_read']],
             provider: AccessProfileProvider::class
         )
     ]
@@ -53,12 +53,14 @@ class AccessProfile implements ApiResourcesInterface
     #[Groups('access_profile_read')]
     private ?int $avatarId = null;
 
+    /** @var list<string> $roles */
     #[Groups('access_profile_read')]
     private ?array $roles = [];
 
     #[Groups('access_profile_read')]
     private ?int $activityYear = null;
 
+    /** @var bool[] $historical */
     #[Groups('access_profile_read')]
     private ?array $historical = [];
 
@@ -175,12 +177,19 @@ class AccessProfile implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @return list<string>
+     */
     public function getRoles(): array
     {
         $roles = $this->roles;
         return array_unique($roles);
     }
 
+    /**
+     * @param list<string> $roles
+     * @return $this
+     */
     public function setRoles(array $roles): self
     {
         $this->roles = $roles;
@@ -269,11 +278,18 @@ class AccessProfile implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @return bool[]
+     */
     public function getHistorical(): array
     {
         return $this->historical;
     }
 
+    /**
+     * @param bool[] $historical
+     * @return $this
+     */
     public function setHistorical(array $historical): self
     {
         $this->historical = $historical;

+ 17 - 0
src/ApiResources/Profile/OrganizationProfile.php

@@ -7,6 +7,7 @@ use ApiPlatform\Metadata\ApiResource;
 use ApiPlatform\Metadata\ApiProperty;
 use ApiPlatform\Metadata\Get;
 use App\ApiResources\ApiResourcesInterface;
+use App\Entity\Organization\Organization;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 /**
@@ -32,18 +33,21 @@ class OrganizationProfile implements ApiResourcesInterface
     #[Groups('access_profile_read')]
     private ?string $legalStatus = null;
 
+    /** @var list<string> $networks  */
     #[Groups('access_profile_read')]
     private array $networks = [];
 
     #[Groups('access_profile_read')]
     private ?string $website = null;
 
+    /** @var list<string>|null $modules  */
     #[Groups('access_profile_read')]
     private ?array $modules = [];
 
     #[Groups('access_profile_read')]
     private bool $hasChildren = false;
 
+    /** @var list<Organization>|null  */
     #[Groups('access_profile_read')]
     private ?array $parents = [];
 
@@ -100,6 +104,9 @@ class OrganizationProfile implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @return list<string>
+     */
     public function getNetworks(): array
     {
         return $this->networks;
@@ -122,12 +129,19 @@ class OrganizationProfile implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @return list<string>
+     */
     public function getModules(): array
     {
         $modules = $this->modules;
         return array_unique($modules);
     }
 
+    /**
+     * @param list<string> $modules
+     * @return $this
+     */
     public function setModules(array $modules): self
     {
         $this->modules = $modules;
@@ -145,6 +159,9 @@ class OrganizationProfile implements ApiResourcesInterface
         return $this;
     }
 
+    /**
+     * @return list<Organization>
+     */
     public function getParents(): array
     {
         return $this->parents;

+ 8 - 0
src/Attribute/ActivityYearConstraintAware.php

@@ -11,4 +11,12 @@ final class ActivityYearConstraintAware
 {
     public string $startYearFieldName;
     public string $endYearFieldName;
+
+    public function __construct(
+         string $startYearFieldName,
+         string $endYearFieldName
+    ){
+        $this->startYearFieldName = $startYearFieldName;
+        $this->endYearFieldName = $endYearFieldName;
+    }
 }

+ 5 - 0
src/Attribute/BillingSettingDefaultValue.php

@@ -10,4 +10,9 @@ namespace App\Attribute;
 final class BillingSettingDefaultValue
 {
     public string $fieldName;
+
+    public function __construct(string $fieldName)
+    {
+        $this->fieldName = $fieldName;
+    }
 }

+ 8 - 0
src/Attribute/DateTimeConstraintAware.php

@@ -11,4 +11,12 @@ final class DateTimeConstraintAware
 {
     public string $startDateFieldName;
     public string $endDateFieldName;
+
+    public function __construct(
+        string $startDateFieldName,
+        string $endDateFieldName
+    ){
+        $this->startDateFieldName = $startDateFieldName;
+        $this->endDateFieldName = $endDateFieldName;
+    }
 }

+ 3 - 0
src/Attribute/OrganizationDefaultValue.php

@@ -10,4 +10,7 @@ namespace App\Attribute;
 final class OrganizationDefaultValue
 {
     public string $fieldName;
+    public function __construct(string $fieldName){
+        $this->fieldName = $fieldName;
+    }
 }

+ 4 - 1
src/Commands/AddSubdomainCommand.php

@@ -24,7 +24,10 @@ class AddSubdomainCommand extends Command
         parent::__construct();
     }
 
-    protected function configure()
+    /**
+     * @return void
+     */
+    protected function configure(): void
     {
         $this->addArgument('organization-id', InputArgument::REQUIRED, 'Id of the organization');
         $this->addArgument('subdomain', InputArgument::REQUIRED, 'The new active subdomain');

+ 4 - 2
src/Commands/CronCommand.php

@@ -2,7 +2,7 @@
 
 namespace App\Commands;
 
-use App\Service\Cron\CronJobInterface;
+use App\Service\Cron\CronjobInterface;
 use App\Service\Cron\UI\ConsoleUI;
 use App\Service\ServiceIterator\CronjobIterator;
 use Psr\Log\LoggerInterface;
@@ -11,7 +11,6 @@ use Symfony\Component\Console\Attribute\AsCommand;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Command\LockableTrait;
 use Symfony\Component\Console\Helper\FormatterHelper;
-use Symfony\Component\Console\Helper\ProgressBar;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
@@ -98,6 +97,8 @@ class CronCommand extends Command
     final protected function execute(InputInterface $input, OutputInterface $output): int
     {
         $this->output = $output;
+
+        /** @var FormatterHelper $formatter */
         $formatter = $this->getHelper('formatter');
 
         $action = $input->getArgument('action');
@@ -172,6 +173,7 @@ class CronCommand extends Command
      */
     private function runJob(CronjobInterface $job, bool $preview = false): int
     {
+        /** @var FormatterHelper $formatter */
         $formatter = $this->getHelper('formatter');
 
         if (!$this->lock($job->name())) {

+ 1 - 1
src/Commands/DolibarrSyncCommand.php

@@ -30,7 +30,7 @@ class DolibarrSyncCommand extends Command
         parent::__construct();
     }
 
-    protected function configure()
+    protected function configure(): void
     {
         $this->addOption(
             'preview',

+ 3 - 3
src/Commands/PostUpgrade/V0_2/PostUpgradeCommand.php

@@ -39,7 +39,7 @@ class PostUpgradeCommand extends Command
         return Command::SUCCESS;
     }
 
-    private function getOpentalentConnexion() {
+    private function getOpentalentConnexion(): PDO {
         $dbUrl = $_ENV['DATABASE_URL'];
         $matches = [];
         preg_match(
@@ -154,7 +154,7 @@ class PostUpgradeCommand extends Command
         }
     }
 
-    private function genEventsUuid() {
+    private function genEventsUuid(): void {
         $opentalentCnn = $this->getOpentalentConnexion();
 
         $opentalentCnn->beginTransaction();
@@ -178,7 +178,7 @@ class PostUpgradeCommand extends Command
         }
     }
 
-    private function updateFilesStatuses() {
+    private function updateFilesStatuses():void  {
         $opentalentCnn = $this->getOpentalentConnexion();
 
         $opentalentCnn->beginTransaction();

+ 19 - 0
src/Doctrine/AbstractExtension.php

@@ -15,11 +15,30 @@ use Exception;
  */
 abstract class AbstractExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 {
+    /**
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     * @throws Exception
+     */
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
     {
         $this->addWhere($queryBuilder, $resourceClass);
     }
 
+    /**
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param list<int> $identifiers
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     * @throws Exception
+     */
     public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, Operation $operation = null, array $context = []): void
     {
         $this->addWhere($queryBuilder, $resourceClass);

+ 2 - 2
src/Doctrine/Access/AccessExtensionInterface.php

@@ -6,6 +6,6 @@ namespace App\Doctrine\Access;
 use Doctrine\ORM\QueryBuilder;
 
 interface AccessExtensionInterface{
-    public function support(string $name);
-    public function addWhere(QueryBuilder $queryBuilder);
+    public function support(string $name): bool;
+    public function addWhere(QueryBuilder $queryBuilder): void;
 }

+ 17 - 0
src/Doctrine/Access/CurrentAccessExtension.php

@@ -24,11 +24,28 @@ final class CurrentAccessExtension  implements QueryCollectionExtensionInterface
     )
     { }
 
+    /**
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
     {
         $this->addWhere($queryBuilder, $resourceClass, $operation?->getName());
     }
 
+    /**
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param list<int> $identifiers
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, Operation $operation = null, array $context = []): void
     {
         $this->addWhere($queryBuilder, $resourceClass, $operation?->getName());

+ 1 - 1
src/Doctrine/Access/Extensions/DateTimeConstraintExtension.php

@@ -21,7 +21,7 @@ class DateTimeConstraintExtension implements AccessExtensionInterface {
             );
     }
 
-    public function addWhere(QueryBuilder $queryBuilder)
+    public function addWhere(QueryBuilder $queryBuilder): void
     {
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $queryBuilder->innerJoin(sprintf('%s.organizationFunction', $rootAlias), 'organization_function');

+ 1 - 2
src/Doctrine/Access/Extensions/StudentsExtension.php

@@ -13,8 +13,7 @@ class StudentsExtension implements AccessExtensionInterface {
         return $name === 'cget_students';
     }
 
-    public function addWhere(QueryBuilder $queryBuilder)
+    public function addWhere(QueryBuilder $queryBuilder): void
     {
-        dd('ok');
     }
 }

+ 28 - 6
src/Entity/Access/Access.php

@@ -8,6 +8,7 @@ use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
 use ApiPlatform\Metadata\ApiFilter;
 use App\Entity\AccessWish\AccessWish;
 use App\Entity\Billing\AccessBilling;
+use App\Entity\Billing\AccessFictionalIntangible;
 use App\Entity\Billing\Bill;
 use App\Entity\Billing\BillCredit;
 use App\Entity\Billing\BillLine;
@@ -55,6 +56,7 @@ use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use JetBrains\PhpStorm\Pure;
+use Symfony\Component\Security\Core\Role\Role;
 use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
 use Symfony\Component\Security\Core\User\UserInterface;
 use Symfony\Component\Serializer\Annotation\Groups;
@@ -97,25 +99,22 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\JoinColumn(nullable: false)]
     private Organization $organization;
 
+    /** @var mixed[]|null  */
     #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
     private ?array $roles = [];
 
+    /** @var mixed[]|null  */
     #[Groups(['my_access:input'])]
     #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
     private ?array $setting = [];
 
-    #[Groups(['my_access:input'])]
-    private array $historical = [];
-
     #[ORM\OneToOne(mappedBy: 'access', cascade: ['persist'], orphanRemoval: true)]
     private AccessBilling $accessBilling;
 
     #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonActivity::class, cascade: ['persist'], orphanRemoval: true)]
-    #[ApiResource]
     private Collection $personActivity;
 
     #[ORM\OneToMany(mappedBy: 'access', targetEntity: OrganizationFunction::class, cascade: ['persist'], orphanRemoval: true)]
-    #[ApiResource]
     private Collection $organizationFunction;
 
     #[ORM\OneToMany(mappedBy: 'licensee', targetEntity: OrganizationLicence::class, cascade: ['persist'], orphanRemoval: true)]
@@ -407,11 +406,20 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
+    /**
+     * @return array<bool|string>
+     */
     public function getHistorical(): array
     {
         return array_key_exists('historical', $this->setting) && $this->setting['historical'] ? $this->setting['historical'] : ['present' => true];
     }
 
+
+    /**
+     * @param array<bool|string> $historical
+     * @return $this
+     */
+    #[Groups(['my_access:input'])]
     public function setHistorical(array $historical): self
     {
         if (!$historical['past'] && !$historical['present'] && !$historical['future']) {
@@ -421,12 +429,19 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
+    /**
+     * @param mixed[]|null $roles
+     * @return $this
+     */
     public function setRoles(?array $roles): self
     {
         $this->roles = $roles;
         return $this;
     }
 
+    /**
+     * @return mixed[]
+     */
     public function getRoles(): array
     {
         $roles = $this->roles;
@@ -745,16 +760,23 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return null;
     }
 
-    public function eraseCredentials()
+    public function eraseCredentials(): void
     {
         // TODO: Implement eraseCredentials() method.
     }
 
+    /**
+     * @return mixed[]|null
+     */
     public function getSetting(): ?array
     {
         return $this->setting;
     }
 
+    /**
+     * @param mixed[]|null $setting
+     * @return $this
+     */
     public function setSetting(?array $setting): self
     {
         $this->setting = $setting;

+ 2 - 1
src/Entity/Access/AccessFamily.php

@@ -6,6 +6,7 @@ namespace App\Entity\Access;
 use ApiPlatform\Metadata\Get;
 use ApiPlatform\Metadata\ApiResource;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Entity\Billing\AccessFictionalIntangible;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -33,7 +34,7 @@ class AccessFamily
     private Collection $accesses;
 
     #[ORM\OneToMany(mappedBy: 'accessFamily', targetEntity: AccessFictionalIntangible::class, cascade: ['persist'], orphanRemoval: true)]
-    private $accessFictionalIntangibles;
+    private Collection $accessFictionalIntangibles;
 
     public function __construct()
     {

+ 0 - 113
src/Entity/Access/AccessFictionalIntangible.php

@@ -1,113 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Entity\Access;
-
-use App\Entity\Billing\BillingIntangibleExcludeDate;
-use App\Entity\Product\FictionalIntangible;
-//use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
-use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\ORM\Mapping as ORM;
-use Doctrine\Common\Collections\Collection;
-
-/**
- * Classe ... qui ...
- */
-//#[Auditable]
-#[ORM\Entity]
-class AccessFictionalIntangible
-{
-    #[ORM\Id]
-    #[ORM\Column]
-    #[ORM\GeneratedValue]
-    private ?int $id = null;
-
-    #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessFictionalIntangibles')]
-    private Access $access;
-
-    #[ORM\ManyToOne(cascade: ['persist'], inversedBy: 'accessFictionalIntangibles')]
-    private AccessFamily $accessFamily;
-
-    #[ORM\ManyToOne]
-    #[ORM\JoinColumn(nullable: false)]
-    private FictionalIntangible $fictionalIntangible;
-
-    #[ORM\OneToMany(mappedBy: 'accessFictionalIntangible', targetEntity: BillingIntangibleExcludeDate::class, cascade: ['persist'], orphanRemoval: true)]
-    private Collection $billingIntangibleExcludeDates;
-
-    public function __construct()
-    {
-        $this->billingIntangibleExcludeDates = new ArrayCollection();
-    }
-
-    public function getId(): ?int
-    {
-        return $this->id;
-    }
-
-    public function getAccess(): ?Access
-    {
-        return $this->access;
-    }
-
-    public function setAccess(?Access $access): self
-    {
-        $this->access = $access;
-
-        return $this;
-    }
-
-    public function getAccessFamily(): ?AccessFamily
-    {
-        return $this->accessFamily;
-    }
-
-    public function setAccessFamily(?AccessFamily $accessFamily): self
-    {
-        $this->accessFamily = $accessFamily;
-
-        return $this;
-    }
-
-    public function getFictionalIntangible(): ?FictionalIntangible
-    {
-        return $this->fictionalIntangible;
-    }
-
-    public function setFictionalIntangible(?FictionalIntangible $fictionalIntangible): self
-    {
-        $this->fictionalIntangible = $fictionalIntangible;
-
-        return $this;
-    }
-
-    /**
-     * @return Collection<int, BillingIntangibleExcludeDate>
-     */
-    public function getBillingIntangibleExcludeDates(): Collection
-    {
-        return $this->billingIntangibleExcludeDates;
-    }
-
-    public function addBillingIntangibleExcludeDate(BillingIntangibleExcludeDate $billingIntangibleExcludeDate): self
-    {
-        if (!$this->billingIntangibleExcludeDates->contains($billingIntangibleExcludeDate)) {
-            $this->billingIntangibleExcludeDates[] = $billingIntangibleExcludeDate;
-            $billingIntangibleExcludeDate->setAccessFictionalIntangible($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBillingIntangibleExcludeDate(BillingIntangibleExcludeDate $billingIntangibleExcludeDate): self
-    {
-        if ($this->billingIntangibleExcludeDates->removeElement($billingIntangibleExcludeDate)) {
-            // set the owning side to null (unless already changed)
-            if ($billingIntangibleExcludeDate->getAccessFictionalIntangible() === $this) {
-                $billingIntangibleExcludeDate->setAccessFictionalIntangible(null);
-            }
-        }
-
-        return $this;
-    }
-}

+ 17 - 1
src/Entity/Access/PersonalizedList.php

@@ -43,6 +43,7 @@ class PersonalizedList
     #[Groups(['lists:output'])]
     private ?string $label = null;
 
+    /** @var mixed[]|null  */
     #[ORM\Column(length: 4294967295, nullable: true)]
     private ?array $filters = null;
 
@@ -50,6 +51,7 @@ class PersonalizedList
     #[Groups(['lists:output'])]
     private string $entity;
 
+    /** @var mixed[]  */
     #[ORM\Column(length: 4294967295, nullable: true)]
     private array $columns;
 
@@ -67,29 +69,43 @@ class PersonalizedList
         return $this->id;
     }
 
+    /**
+     * @param mixed[] $filters
+     * @return $this
+     */
     public function setFilters(array $filters): self
     {
         $this->filters = $filters;
         return $this;
     }
 
+    /**
+     * @return mixed[]|null
+     */
     public function getFilters(): ?array
     {
         return $this->filters;
     }
 
+    /**
+     * @param mixed[] $columns
+     * @return $this
+     */
     public function setColumns(array $columns): self
     {
         $this->columns = $columns;
         return $this;
     }
 
+    /**
+     * @return mixed[]|null
+     */
     public function getColumns(): ?array
     {
         return $this->columns;
     }
 
-    public function setAccess(Access $access): self
+    public function setAccess(?Access $access): self
     {
         $this->access = $access;
         return $this;

+ 2 - 1
src/Entity/Billing/AccessIntangible.php

@@ -6,6 +6,7 @@ namespace App\Entity\Billing;
 use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Repository\Billing\AccessIntangibleRepository;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\Collection;
@@ -15,7 +16,7 @@ use Doctrine\Common\Collections\Collection;
  */
 #[ApiResource]
 //#[Auditable]
-#[ORM\Entity(repositoryClass: AccessIntangible::class)]
+#[ORM\Entity(repositoryClass: AccessIntangibleRepository::class)]
 class AccessIntangible extends AbstractBillingIntangible
 {
     #[ORM\ManyToOne(inversedBy: 'accessIntangibles')]

+ 1 - 1
src/Entity/Billing/BergerLevrault.php

@@ -20,7 +20,7 @@ class BergerLevrault
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'bergerLevrault', targetEntity: 'Bill', cascade: ['persist'], orphanRemoval: true)]
+    #[ORM\OneToMany(mappedBy: 'bergerLevrault', targetEntity: Bill::class, cascade: ['persist'], orphanRemoval: true)]
     private Collection $bills;
 
     public function __construct()

+ 5 - 0
src/Entity/Billing/BillAccessDetail.php

@@ -16,4 +16,9 @@ class BillAccessDetail
     #[ORM\Column]
     #[ORM\GeneratedValue]
     private ?int $id = null;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
 }

+ 2 - 1
src/Entity/Billing/BillAccounting.php

@@ -75,7 +75,7 @@ class BillAccounting
     #[ORM\JoinTable(name: 'tag_billAccounting')]
     #[ORM\JoinColumn(name: 'billAccounting_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    protected $tags;
+    protected Collection $tags;
 
     public function __construct()
     {
@@ -209,6 +209,7 @@ class BillAccounting
     {
         if (!$this->billingIntangibleExcludeDates->contains($billingIntangibleExcludeDate)) {
             $this->billingIntangibleExcludeDates[] = $billingIntangibleExcludeDate;
+            /** @phpstan-ignore-next-line */
             $billingIntangibleExcludeDate->setBill($this);
         }
         return $this;

+ 1 - 1
src/Entity/Billing/BillPayment.php

@@ -40,7 +40,7 @@ class BillPayment
     #[ORM\JoinTable(name: 'tag_billPayment')]
     #[ORM\JoinColumn(name: 'billPayment_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    private $tags;
+    private Collection $tags;
 
     public function __construct()
     {

+ 4 - 4
src/Entity/Billing/ResidenceArea.php

@@ -48,7 +48,7 @@ class ResidenceArea
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\ManyToOne(targetEntity: 'BillingSetting', inversedBy: 'residenceAreas')]
+    #[ORM\ManyToOne(targetEntity: BillingSetting::class, inversedBy: 'residenceAreas')]
     #[ORM\JoinColumn(nullable: false)]
     private BillingSetting $billingSetting;
 
@@ -77,18 +77,18 @@ class ResidenceArea
         return $this->label;
     }
 
-    public function setLabel(string $label)
+    public function setLabel(string $label): self
     {
         $this->label = $label;
         return $this;
     }
 
-    public function getBillingSetting(): BillingSetting
+    public function getBillingSetting(): ?BillingSetting
     {
         return $this->billingSetting;
     }
 
-    public function setBillingSetting(BillingSetting $billingSetting): self
+    public function setBillingSetting(?BillingSetting $billingSetting): self
     {
         $this->billingSetting = $billingSetting;
         return $this;

+ 0 - 36
src/Entity/Billing/SddBank.php

@@ -4,8 +4,6 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
-use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
@@ -20,46 +18,12 @@ class SddBank
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'sddBank',targetEntity: Bill::class,  orphanRemoval: true)]
-    private Collection $bills;
-
     public function __construct()
     {
-        $this->bills = new ArrayCollection();
     }
 
     public function getId(): ?int
     {
         return $this->id;
     }
-
-    /**
-     * @return Collection<int, Bill>
-     */
-    public function getBills(): Collection
-    {
-        return $this->bills;
-    }
-
-    public function addBill(Bill $bill): self
-    {
-        if (!$this->bills->contains($bill)) {
-            $this->bills[] = $bill;
-            $bill->setSddBank($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBill(Bill $bill): self
-    {
-        if ($this->bills->removeElement($bill)) {
-            // set the owning side to null (unless already changed)
-            if ($bill->getSddBank() === $this) {
-                $bill->setSddBank(null);
-            }
-        }
-
-        return $this;
-    }
 }

+ 0 - 36
src/Entity/Billing/SddRegie.php

@@ -4,8 +4,6 @@ declare(strict_types=1);
 namespace App\Entity\Billing;
 
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
-use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
@@ -20,46 +18,12 @@ class SddRegie
     #[ORM\GeneratedValue]
     private ?int $id = null;
 
-    #[ORM\OneToMany(mappedBy: 'sddRegie',targetEntity: Bill::class,  orphanRemoval: true)]
-    private Collection $bills;
-
     public function __construct()
     {
-        $this->bills = new ArrayCollection();
     }
 
     public function getId(): ?int
     {
         return $this->id;
     }
-
-    /**
-     * @return Collection<int, Bill>
-     */
-    public function getBills(): Collection
-    {
-        return $this->bills;
-    }
-
-    public function addBill(Bill $bill): self
-    {
-        if (!$this->bills->contains($bill)) {
-            $this->bills[] = $bill;
-            $bill->setSddRegie($this);
-        }
-
-        return $this;
-    }
-
-    public function removeBill(Bill $bill): self
-    {
-        if ($this->bills->removeElement($bill)) {
-            // set the owning side to null (unless already changed)
-            if ($bill->getSddRegie() === $this) {
-                $bill->setSddRegie(null);
-            }
-        }
-
-        return $this;
-    }
 }

+ 2 - 2
src/Entity/Booking/Work.php

@@ -25,10 +25,10 @@ class Work
     private Course $course;
 
     #[ORM\OneToMany(mappedBy: 'work',targetEntity: WorkByUser::class,  cascade: ['persist'], orphanRemoval: true)]
-    private $workByUsers;
+    private Collection $workByUsers;
 
     #[ORM\OneToMany(mappedBy: 'work',targetEntity: File::class,  orphanRemoval: true)]
-    private $files;
+    private Collection $files;
 
     public function __construct()
     {

+ 1 - 1
src/Entity/Core/ContactPoint.php

@@ -96,7 +96,7 @@ class ContactPoint
     #[ORM\JoinTable(name: 'place_contactpoint')]
     #[ORM\JoinColumn(name: 'contactPoint_id', referencedColumnName: 'id', unique: true)]
     #[ORM\InverseJoinColumn(name: 'place_id', referencedColumnName: 'id')]
-    private $place;
+    private Collection $place;
 
     #[Pure]
     public function __construct()

+ 1 - 1
src/Entity/Core/Notification.php

@@ -204,7 +204,7 @@ class Notification
         return $this->link;
     }
 
-    public function getAvailabilityDate(): ?string
+    public function getAvailabilityDate(): ?\DateTimeInterface
     {
         return $this->availabilityDate;
     }

+ 1 - 1
src/Entity/Education/Cycle.php

@@ -73,7 +73,7 @@ class Cycle
         return $this->id;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
         return $this;

+ 1 - 1
src/Entity/Education/Education.php

@@ -60,7 +60,7 @@ class Education
     #[ORM\JoinTable(name: 'tag_education')]
     #[ORM\JoinColumn(name: 'education_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
-    private $tags;
+    private Collection $tags;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]

+ 1 - 1
src/Entity/Education/EducationNotationConfig.php

@@ -85,7 +85,7 @@ class EducationNotationConfig
         return $this->id;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
         return $this;

+ 1 - 1
src/Entity/Education/EducationTiming.php

@@ -73,7 +73,7 @@ class EducationTiming
         return $this->id;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
         return $this;

+ 3 - 3
src/Entity/Message/AbstractMessage.php

@@ -23,7 +23,7 @@ abstract class AbstractMessage
     protected ?int $id = null;
 
     #[ORM\Column(type: 'string', unique: true)]
-    protected $uuid = null;
+    protected ?UuidInterface $uuid = null;
 
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(nullable: true)]
@@ -86,7 +86,7 @@ abstract class AbstractMessage
         return html_entity_decode($this->text);
     }
 
-    public function setStatus(string $status)
+    public function setStatus(string $status): self
     {
         $this->status = $status;
 
@@ -99,7 +99,7 @@ abstract class AbstractMessage
     }
 
 
-    public function setDateSent(\DateTimeInterface $dateSent)
+    public function setDateSent(\DateTimeInterface $dateSent): self
     {
         $this->dateSent = $dateSent;
 

+ 23 - 1
src/Entity/Message/ReportSms.php

@@ -27,7 +27,7 @@ class ReportSms extends AbstractReport
     private string $mobile;
 
     #[ORM\Column(nullable: true)]
-    private $smsId;
+    private ?string $smsId;
 
     public function getId(): ?int
     {
@@ -45,4 +45,26 @@ class ReportSms extends AbstractReport
 
         return $this;
     }
+
+    public function setMobile(string $mobile): self
+    {
+        $this->mobile = $mobile;
+        return $this;
+    }
+
+    public function getMobile(): string
+    {
+        return $this->mobile;
+    }
+
+    public function setSmsId(string $smsId): self
+    {
+        $this->smsId = $smsId;
+        return $this;
+    }
+
+    public function getSmsId(): ?string
+    {
+        return $this->smsId;
+    }
 }

+ 1 - 1
src/Entity/Network/Network.php

@@ -54,7 +54,7 @@ class Network
         $this->organizations = new ArrayCollection();
     }
 
-    public function setId($id): self
+    public function setId(int $id): self
     {
         $this->id = $id;
         return $this;

+ 2 - 84
src/Entity/Organization/Organization.php

@@ -92,7 +92,6 @@ class Organization
     private Collection $accesses;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: NetworkOrganization::class, orphanRemoval: true)]
-    #[ApiResource]
     private Collection $networkOrganizations;
 
     #[ORM\OneToMany(mappedBy: 'parent', targetEntity: NetworkOrganization::class, orphanRemoval: true)]
@@ -106,7 +105,6 @@ class Organization
     private Parameters $parameters;
 
     #[ORM\OneToOne(mappedBy: 'organization', cascade: ['persist', 'remove'], orphanRemoval: true)]
-    #[ApiResource]
     private BillingSetting $billingSetting;
 
     #[ORM\Column(type: 'text', nullable: true)]
@@ -224,31 +222,26 @@ class Organization
     private ?File $image = null;
 
     #[ORM\ManyToMany(targetEntity: TypeOfPractice::class, mappedBy: 'organizations')]
-    #[ApiResource]
     private Collection $typeOfPractices;
 
     #[ORM\Column(nullable: true)]
     private ?string $otherPractice = null;
 
     #[ORM\ManyToMany(targetEntity: ContactPoint::class, mappedBy: 'organization')]
-    #[ApiResource]
     private Collection $contactPoints;
 
     #[ORM\ManyToMany(targetEntity: BankAccount::class, inversedBy: 'organization')]
     #[ORM\JoinColumn(name: 'organization_id', referencedColumnName: 'id', unique: true)]
     #[ORM\InverseJoinColumn(name: 'bankAccount_id', referencedColumnName: 'id')]
-    #[ApiResource]
     private Collection $bankAccounts;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: OrganizationAddressPostal::class, orphanRemoval: true)]
-    #[ApiResource]
     private Collection $organizationAddressPostals;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: OrganizationLicence::class, orphanRemoval: true)]
     private Collection $organizationLicences;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: OrganizationArticle::class, orphanRemoval: true)]
-    #[ApiResource]
     private Collection $organizationArticles;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: Cycle::class, orphanRemoval: true)]
@@ -258,7 +251,6 @@ class Organization
     private Collection $educationTimings;
 
     #[ORM\OneToMany(mappedBy: 'organization', targetEntity: Subdomain::class)]
-    #[ApiResource]
     private Collection $subdomains;
 
     #[ORM\ManyToOne(inversedBy: 'organizationContacts')]
@@ -507,7 +499,7 @@ class Organization
     /**
      * @return File
      */
-    public function getLogo(): File
+    public function getLogo(): ?File
     {
         return $this->logo;
     }
@@ -515,7 +507,7 @@ class Organization
     /**
      * @param File $logo
      */
-    public function setLogo(File $logo): void
+    public function setLogo(?File $logo): void
     {
         $this->logo = $logo;
     }
@@ -1148,20 +1140,6 @@ class Organization
         return $this->subdomains;
     }
 
-    public function addSubdomain($subdomain): self
-    {
-        $subdomain->setOrganization($this);
-        $this->subdomains[] = $subdomain;
-        return $this;
-    }
-
-    public function removeSubdomain($subdomain): self
-    {
-        $subdomain->setOrganization(null);
-        $this->subdomains->removeElement($subdomain);
-        return $this;
-    }
-
     public function addAccess(Access $access): self
     {
         if (!$this->accesses->contains($access)) {
@@ -1481,26 +1459,6 @@ class Organization
         return $this->emails;
     }
 
-    public function addEmail(Email $email): self
-    {
-        if (!$this->emails->contains($email)) {
-            $this->emails[] = $email;
-            $email->setAuthor($this);
-        }
-        return $this;
-    }
-
-    public function removeEmail(Email $email): self
-    {
-        if ($this->emails->removeElement($email)) {
-            // set the owning side to null (unless already changed)
-            if ($email->getAuthor() === $this) {
-                $email->setAuthor(null);
-            }
-        }
-        return $this;
-    }
-
     /**
      * @return Collection<int, Mail>
      */
@@ -1509,26 +1467,6 @@ class Organization
         return $this->mails;
     }
 
-    public function addMail(Mail $mail): self
-    {
-        if (!$this->mails->contains($mail)) {
-            $this->mails[] = $mail;
-            $mail->setAuthor($this);
-        }
-        return $this;
-    }
-
-    public function removeMail(Mail $mail): self
-    {
-        if ($this->mails->removeElement($mail)) {
-            // set the owning side to null (unless already changed)
-            if ($mail->getAuthor() === $this) {
-                $mail->setAuthor(null);
-            }
-        }
-        return $this;
-    }
-
     /**
      * @return Collection<int, Sms>
      */
@@ -1537,26 +1475,6 @@ class Organization
         return $this->sms;
     }
 
-    public function addSms(Sms $sms): self
-    {
-        if (!$this->sms->contains($sms)) {
-            $this->sms[] = $sms;
-            $sms->setAuthor($this);
-        }
-        return $this;
-    }
-
-    public function removeSms(Sms $sms): self
-    {
-        if ($this->sms->removeElement($sms)) {
-            // set the owning side to null (unless already changed)
-            if ($sms->getAuthor() === $this) {
-                $sms->setAuthor(null);
-            }
-        }
-        return $this;
-    }
-
     /**
      * @return Collection<int, Activity>
      */

+ 1 - 1
src/Entity/Organization/OrganizationAddressPostal.php

@@ -76,7 +76,7 @@ class OrganizationAddressPostal
         return $this->organization;
     }
 
-    public function setOrganization(Organization $organization): self
+    public function setOrganization(?Organization $organization): self
     {
         $this->organization = $organization;
         return $this;

+ 2 - 2
src/Entity/Organization/OrganizationLicence.php

@@ -45,7 +45,7 @@ class OrganizationLicence
     {
         return $this->organization;
     }
-    public function setOrganization(Organization $organization) : self
+    public function setOrganization(?Organization $organization) : self
     {
         $this->organization = $organization;
         return $this;
@@ -54,7 +54,7 @@ class OrganizationLicence
     {
         return $this->licensee;
     }
-    public function setLicensee(Access $licensee) : self
+    public function setLicensee(?Access $licensee) : self
     {
         $this->licensee = $licensee;
         return $this;

+ 1 - 2
src/Entity/Organization/Parameters.php

@@ -86,7 +86,6 @@ class Parameters
     private bool $desactivateOpentalentSiteWeb = false;
 
     #[ORM\OneToMany(mappedBy: 'publicationDirector', targetEntity: Access::class)]
-    #[ApiResource]
     private Collection $publicationDirectors;
 
     #[ORM\Column(length: 255, nullable: true)]
@@ -233,7 +232,7 @@ class Parameters
         return $this->average;
     }
 
-    public function setAverage(int $average)
+    public function setAverage(int $average): self
     {
         $this->average = $average;
         return $this;

+ 45 - 11
src/Entity/Organization/Settings.php

@@ -13,9 +13,11 @@ use ApiPlatform\Metadata\ApiResource;
 use ApiPlatform\Metadata\ApiProperty;
 use ApiPlatform\Metadata\ApiFilter;
 use App\Repository\Organization\SettingsRepository;
+
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
+
 /**
  * Caractéristiques d'une Organization (produits, options...etc)
  */
@@ -28,63 +30,95 @@ class Settings
     #[ORM\Column]
     #[ORM\GeneratedValue]
     private ?int $id = null;
+
     #[ORM\OneToOne(inversedBy: 'settings', cascade: ['persist', 'remove'])]
     #[ORM\JoinColumn(nullable: false)]
     private ?Organization $organization = null;
+
     #[ORM\Column(length: 255)]
     #[Assert\Choice(callback: ['\\App\\Enum\\Organization\\SettingsProductEnum', 'toArray'], message: 'invalid-product')]
     private string $product;
+
+    /** @var mixed[]|null  */
     #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
     private ?array $modules = [];
+
+    /** @var mixed[]|null  */
     #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
     private ?array $actions = [];
+
     #[ORM\Column(length: 255, options: ['default' => 'FRANCE'])]
     private string $country;
-    public function getId() : ?int
+
+    public function getId(): ?int
     {
         return $this->id;
     }
-    public function getOrganization() : ?Organization
+
+    public function getOrganization(): ?Organization
     {
         return $this->organization;
     }
-    public function setOrganization(Organization $organization) : self
+
+    public function setOrganization(Organization $organization): self
     {
         $this->organization = $organization;
         return $this;
     }
-    public function getProduct() : string
+
+    public function getProduct(): string
     {
         return $this->product;
     }
-    public function setProduct(string $product) : self
+
+    public function setProduct(string $product): self
     {
         $this->product = $product;
         return $this;
     }
-    public function getModules() : ?array
+
+    /**
+     * @return mixed[]|null
+     */
+    public function getModules(): ?array
     {
         return $this->modules;
     }
-    public function setModules(?array $modules) : self
+
+    /**
+     * @param mixed[]|null $modules
+     * @return $this
+     */
+    public function setModules(?array $modules): self
     {
         $this->modules = $modules;
         return $this;
     }
-    public function getActions() : ?array
+
+    /**
+     * @return mixed[]|null
+     */
+    public function getActions(): ?array
     {
         return $this->actions;
     }
-    public function setActions(?array $actions) : self
+
+    /**
+     * @param mixed[]|null $actions
+     * @return $this
+     */
+    public function setActions(?array $actions): self
     {
         $this->actions = $actions;
         return $this;
     }
-    public function getCountry() : string
+
+    public function getCountry(): string
     {
         return $this->country;
     }
-    public function setCountry(string $country) : self
+
+    public function setCountry(string $country): self
     {
         $this->country = $country;
         return $this;

+ 11 - 1
src/Entity/Person/Person.php

@@ -45,7 +45,9 @@ class Person implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\Column(length: 180, unique: true, nullable: true)]
     private ?string $username = null;
 
+    /** @var string[]  */
     private array $roles = [];
+
     #[ORM\Column(nullable: true)]
     private ?string $password = null;
 
@@ -68,6 +70,7 @@ class Person implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\OneToMany(mappedBy: 'person', targetEntity: PersonAddressPostal::class, orphanRemoval: true)]
     #[Groups("access_address")]
     private Collection $personAddressPostal;
+
     #[ORM\Column(nullable: true)]
     #[Assert\Choice(callback: ['\\App\\Enum\\Person\\GenderEnum', 'toArray'], message: 'invalid-gender')]
     private ?string $gender = null;
@@ -144,6 +147,9 @@ class Person implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
     }
 
+    /**
+     * @return string[]
+     */
     public function getRoles(): array
     {
         $roles = $this->roles;
@@ -152,6 +158,10 @@ class Person implements UserInterface, PasswordAuthenticatedUserInterface
         return array_unique($roles);
     }
 
+    /**
+     * @param string[] $roles
+     * @return $this
+     */
     public function setRoles(array $roles): self
     {
         $this->roles = $roles;
@@ -175,7 +185,7 @@ class Person implements UserInterface, PasswordAuthenticatedUserInterface
         // not needed when using the "bcrypt" algorithm in security.yaml
     }
 
-    public function eraseCredentials()
+    public function eraseCredentials(): void
     {
         // If you store any temporary, sensitive data on the user, clear it here
         // $this->plainPassword = null;

+ 1 - 1
src/Entity/Person/PersonAddressPostal.php

@@ -56,7 +56,7 @@ class PersonAddressPostal
         return $this->person;
     }
 
-    public function setPerson(Person $person): self
+    public function setPerson(?Person $person): self
     {
         $this->person = $person;
         return $this;

+ 1 - 1
src/Entity/Place/Room.php

@@ -37,7 +37,7 @@ class Room
     private ?int $id = null;
 
     #[ORM\ManyToOne(targetEntity: Place::class, inversedBy: 'rooms')]
-    private $place;
+    private Place $place;
 
     #[ORM\ManyToMany(targetEntity: ContactPoint::class)]
     private Collection $contactpoint;

+ 12 - 8
src/Entity/Public/FederationStructure.php

@@ -69,6 +69,7 @@ class FederationStructure
     #[Groups(["federation_structure_item_get", "federation_structure_collection_get"])]
     private ?string $website;
 
+    /** @var mixed[] */
     #[ORM\Column(type: 'json')]
     #[Groups(["federation_structure_item_get", "federation_structure_collection_get"])]
     private array $addresses;
@@ -101,10 +102,12 @@ class FederationStructure
     #[Groups(["federation_structure_item_get"])]
     private ?string $youtube;
 
+    /** @var mixed[]|null  */
     #[ORM\Column(type: 'json')]
     #[Groups(["federation_structure_item_get"])]
     private ?array $articles;
 
+    /** @var list<string>|null  */
     #[ORM\Column(type: 'simple_array')]
     #[Groups(["federation_structure_item_get", "federation_structure_collection_get"])]
     private ?array $practices;
@@ -117,6 +120,7 @@ class FederationStructure
     #[Groups(["federation_structure_item_get", "federation_structure_collection_get"])]
     private ?string $parentName;
 
+    /** @var list<string>  */
     #[ORM\Column(type: 'simple_array')]
     #[Groups(["federation_structure_item_get", "federation_structure_collection_get"])]
     private array $parents;
@@ -248,7 +252,7 @@ class FederationStructure
     }
 
     /**
-     * @return array
+     * @return mixed[]
      */
     public function getAddresses(): array
     {
@@ -256,7 +260,7 @@ class FederationStructure
     }
 
     /**
-     * @param array $addresses
+     * @param mixed[] $addresses
      * @return FederationStructure
      */
     public function setAddresses(array $addresses): FederationStructure
@@ -388,7 +392,7 @@ class FederationStructure
     }
 
     /**
-     * @return array|null
+     * @return mixed[]|null
      */
     public function getArticles(): ?array
     {
@@ -396,7 +400,7 @@ class FederationStructure
     }
 
     /**
-     * @param array|null $articles
+     * @param mixed[]|null $articles
      * @return FederationStructure
      */
     public function setArticles(?array $articles): FederationStructure
@@ -406,7 +410,7 @@ class FederationStructure
     }
 
     /**
-     * @return array|null
+     * @return list<string>|null
      */
     public function getPractices(): ?array
     {
@@ -414,7 +418,7 @@ class FederationStructure
     }
 
     /**
-     * @param array|null $practices
+     * @param list<string>|null $practices
      * @return FederationStructure
      */
     public function setPractices(?array $practices): FederationStructure
@@ -460,7 +464,7 @@ class FederationStructure
     }
 
     /**
-     * @return array
+     * @return list<string>
      */
     public function getParents(): array
     {
@@ -468,7 +472,7 @@ class FederationStructure
     }
 
     /**
-     * @param array $parents
+     * @param list<string> $parents
      * @return FederationStructure
      */
     public function setParents(array $parents): FederationStructure

+ 3 - 2
src/Entity/Public/PublicEvent.php

@@ -97,6 +97,7 @@ class PublicEvent
     #[ORM\Column]
     private ?string $thumbnailUrl;
 
+    /** @var list<string>|null  */
     #[ORM\Column(type: 'simple_array')]
     private ?array $categories;
 
@@ -448,7 +449,7 @@ class PublicEvent
     }
 
     /**
-     * @return array|null
+     * @return list<string>|null
      */
     public function getCategories(): ?array
     {
@@ -456,7 +457,7 @@ class PublicEvent
     }
 
     /**
-     * @param array|null $categories
+     * @param list<string>|null $categories
      * @return PublicEvent
      */
     public function setCategories(?array $categories): PublicEvent

+ 6 - 1
src/Enum/Access/FunctionEnum.php

@@ -68,7 +68,10 @@ class FunctionEnum extends Enum
 
     private const OTHER = 'OTHER';
 
-    public static function getOrganizationStaffAndBoardOfDirectorsMission(){
+    /**
+     * @return list<string>
+     */
+    public static function getOrganizationStaffAndBoardOfDirectorsMission(): array {
         return [
             self::ACTIVE_MEMBER_OF_THE_CA,
             self::HONORARY_PRESIDENT,
@@ -113,6 +116,8 @@ class FunctionEnum extends Enum
      * Office missions
      *
      * Used by the DolibarrSyncService
+     *
+     * @return list<string>
      */
     public static function getOfficeMissions(): array
     {

+ 21 - 9
src/EventListener/DoctrineFilter/DoctrineFilterListener.php

@@ -3,12 +3,16 @@ declare(strict_types=1);
 
 namespace App\EventListener\DoctrineFilter;
 
+use App\Entity\Access\Access;
+use App\Filter\DoctrineFilter\ActivityYearFilter;
+use App\Filter\DoctrineFilter\DateTimeFilter;
 use App\Service\Constraint\ActivityYearConstraint;
 use App\Service\Constraint\DateTimeConstraint;
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\HttpKernel\Event\RequestEvent;
 use Symfony\Bundle\SecurityBundle\Security;
+use Symfony\Component\Security\Core\User\UserInterface;
 
 /**
  * Classe DoctrineFilterListener qui permet d'assurer l'injection de dépendance pour le SQL Filter
@@ -25,20 +29,28 @@ class DoctrineFilterListener
     {
     }
 
-    public function onKernelRequest(RequestEvent $event)
+    public function onKernelRequest(RequestEvent $event): void
     {
         if (!$event->isMainRequest()) {
             // don't do anything if it's not the main request
             return;
         }
-        $dateTimeFilter = $this->entityManager->getFilters()->getFilter('date_time_filter');
-        $dateTimeFilter->setParameter('accessId', $this->security->getUser()?->getId() ?? null);
-        $dateTimeFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
-        $dateTimeFilter->setDateTimeConstraint($this->dateTimeConstraint);
 
-        $activityYearFilter = $this->entityManager->getFilters()->getFilter('activity_year_filter');
-        $activityYearFilter->setParameter('accessId', $this->security->getUser()?->getId() ?? null);
-        $activityYearFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
-        $activityYearFilter->setActivityYearConstraint($this->activityYearConstraint);
+        /** @var Access $access */
+        $access = $this->security->getUser();
+
+        if($access){
+            /** @var DateTimeFilter $dateTimeFilter */
+            $dateTimeFilter = $this->entityManager->getFilters()->getFilter('date_time_filter');
+            $dateTimeFilter->setParameter('accessId', $access->getId());
+            $dateTimeFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
+            $dateTimeFilter->setDateTimeConstraint($this->dateTimeConstraint);
+
+            /** @var ActivityYearFilter $activityYearFilter */
+            $activityYearFilter = $this->entityManager->getFilters()->getFilter('activity_year_filter');
+            $activityYearFilter->setParameter('accessId', $access->getId());
+            $activityYearFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
+            $activityYearFilter->setActivityYearConstraint($this->activityYearConstraint);
+        }
     }
 }

+ 1 - 1
src/EventSubscriber/ApiResourcesValidatorSubscriber.php

@@ -22,7 +22,7 @@ final class ApiResourcesValidatorSubscriber implements EventSubscriberInterface
 
     /**
      * ne se déclenche qu'après le post validate d'api platform
-     * @return array[]
+     * @return array<string, array<int, int|string>>
      */
     public static function getSubscribedEvents(): array
     {

+ 4 - 3
src/EventSubscriber/ElasticaPostTransformSubscriber.php

@@ -24,6 +24,7 @@ final class ElasticaPostTransformSubscriber implements EventSubscriberInterface
 
     /**
      * ne se déclenche qu'après le post validate d'api platform
+     * @return string[]
      */
     public static function getSubscribedEvents(): array
     {
@@ -37,7 +38,7 @@ final class ElasticaPostTransformSubscriber implements EventSubscriberInterface
      * Evénement se passant avant l'update d'un index ES
      * @param TransformEvent $event
      */
-    public function doPreTransform(TransformEvent $event)
+    public function doPreTransform(TransformEvent $event): void
     {
 
     }
@@ -46,7 +47,7 @@ final class ElasticaPostTransformSubscriber implements EventSubscriberInterface
      * Evénement se passant après l'update d'un index ES
      * @param TransformEvent $event
      */
-    public function doPostTransform(TransformEvent $event)
+    public function doPostTransform(TransformEvent $event): void
     {
         $document = $event->getDocument();
         $object = $event->getObject();
@@ -61,7 +62,7 @@ final class ElasticaPostTransformSubscriber implements EventSubscriberInterface
      * @param $document
      * @param $object
      */
-    private function educationNotationTransform($document, EducationNotation $educationNotation){
+    private function educationNotationTransform(mixed $document, EducationNotation $educationNotation): void{
         $document->set('note_origine', $this->educationNotationUtils->getNotationOriginal($educationNotation));
         $document->set('note_recalcul', $this->educationNotationUtils->getNotationTransformed($educationNotation));
     }

+ 18 - 15
src/Filter/DoctrineFilter/AbstractTimeFilter.php

@@ -15,9 +15,9 @@ abstract class AbstractTimeFilter extends SQLFilter
 {
     /**
      * Fonction permettant de construire la requête SQL correspondante aux contraintes
-     * @param array $constraints
+     * @param array<string, array<string, int[]>> $constraints
      * @param string $targetTableAlias
-     * @param array $fields
+     * @param array<string, mixed> $fields
      * @return string
      */
     protected function constructQuery(array $constraints, string $targetTableAlias, array $fields): string
@@ -28,14 +28,17 @@ abstract class AbstractTimeFilter extends SQLFilter
             foreach ($constraint as $date => $conditions){
                 foreach ($conditions as $condition){
                     $arithmetic = $this->getArithmeticValue($condition);
-                    if(!is_null($arithmetic))
+                    if(!is_null($arithmetic)) {
                         $queryConditionsOR[] = sprintf("%s.%s %s '%s'", $targetTableAlias, $fields[$key], $arithmetic, $date);
-                    else
+                    }
+                    else {
                         $queryConditionsOR[] = sprintf("%s.%s IS NULL", $targetTableAlias, $fields[$key]);
+                    }
                 }
             }
-            if(!empty($queryConditionsOR))
+            if(!empty($queryConditionsOR)) {
                 $queryConditionsAND[] = sprintf("(%s)", join(' OR ', $queryConditionsOR));
+            }
         }
 
         return implode(" AND ", $queryConditionsAND);
@@ -43,19 +46,19 @@ abstract class AbstractTimeFilter extends SQLFilter
 
     /**
      * Fonction retournant la valeur arithmétique correspondant à la condition de la contrainte
-     * @param $condition
+     * @param int $condition
      * @return string|null
      * @see DateTimeFilterTest::testGetArithmeticValue()
      */
-    protected function getArithmeticValue($condition): ?string
+    protected function getArithmeticValue(int $condition): ?string
     {
-        switch ($condition){
-            case DateTimeConstraint::INF : return '<';
-            case DateTimeConstraint::EQUAL :  return '=';
-            case DateTimeConstraint::SUP :  return '>';
-            case DateTimeConstraint::INF + DateTimeConstraint::EQUAL : return '<=';
-            case DateTimeConstraint::SUP + DateTimeConstraint::EQUAL  : return '>=';
-        }
-        return null;
+        return match ($condition) {
+            DateTimeConstraint::INF => '<',
+            DateTimeConstraint::EQUAL => '=',
+            DateTimeConstraint::SUP => '>',
+            DateTimeConstraint::INF + DateTimeConstraint::EQUAL => '<=',
+            DateTimeConstraint::SUP + DateTimeConstraint::EQUAL => '>=',
+            default => null,
+        };
     }
 }

+ 6 - 4
src/Filter/DoctrineFilter/ActivityYearFilter.php

@@ -7,6 +7,7 @@ use App\Attribute\ActivityYearConstraintAware;
 use App\Service\Constraint\ActivityYearConstraint;
 use App\Service\Utils\StringsUtils;
 use Doctrine\ORM\Mapping\ClassMetadata;
+use Exception;
 
 /**
  * Classe DateTimeFilter qui définie la requête SQL devant être ajoutée aux Entités possédant l'annotation DateTimeConstraintAware
@@ -20,15 +21,16 @@ final class ActivityYearFilter extends AbstractTimeFilter
      * @param ClassMetadata $targetEntity
      * @param string $targetTableAlias
      * @return string
-     * @throws \Exception
+     * @throws Exception
      */
     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
     {
         if(!$this->hasParameter('_time_constraint')
-            || !boolval(StringsUtils::unquote($this->getParameter('_time_constraint')))
+            || !(bool) StringsUtils::unquote($this->getParameter('_time_constraint'))
             || !$this->hasParameter('accessId')
-        )
+        ) {
             return '';
+        }
 
         $yearConstraintAware = $targetEntity->getReflectionClass()->getAttributes(ActivityYearConstraintAware::class)[0] ?? null;
         $startFieldName = $yearConstraintAware?->getArguments()['startYearFieldName'] ?? null;
@@ -54,7 +56,7 @@ final class ActivityYearFilter extends AbstractTimeFilter
      * @param ActivityYearConstraint $activityYearConstraint
      *
      */
-    public function setActivityYearConstraint(ActivityYearConstraint $activityYearConstraint){
+    public function setActivityYearConstraint(ActivityYearConstraint $activityYearConstraint): void{
         $this->activityYearConstraint = $activityYearConstraint;
     }
 }

+ 1 - 1
src/Filter/DoctrineFilter/DateTimeFilter.php

@@ -52,7 +52,7 @@ final class DateTimeFilter extends AbstractTimeFilter
      * Permets d'assurer l'injection de dépendance du service DateTimeConstraint
      * @param DateTimeConstraint $dateTimeConstraint
      */
-    public function setDateTimeConstraint(DateTimeConstraint $dateTimeConstraint){
+    public function setDateTimeConstraint(DateTimeConstraint $dateTimeConstraint): void{
         $this->dateTimeConstraint = $dateTimeConstraint;
     }
 }

+ 12 - 2
src/Filter/Person/FullNameFilter.php

@@ -9,8 +9,18 @@ use ApiPlatform\Metadata\Operation;
 use Doctrine\ORM\QueryBuilder;
 
 class FullNameFilter extends AbstractFilter {
+    /**
+     * @param string $property
+     * @param mixed $value
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     protected function filterProperty(string $property,
-                                             $value,
+                                      mixed $value,
                                       QueryBuilder $queryBuilder,
                                       QueryNameGeneratorInterface $queryNameGenerator,
                                       string $resourceClass,
@@ -30,7 +40,7 @@ class FullNameFilter extends AbstractFilter {
     /**
      * API docs
      * @param string $resourceClass
-     * @return array[]
+     * @return array<string, mixed[]>
      */
     public function getDescription(string $resourceClass): array
     {

+ 15 - 5
src/Filter/Utils/DistanceFilter.php

@@ -26,13 +26,13 @@ final class DistanceFilter extends AbstractFilter
 {
     /**
      * API docs
-     * @param string|ResourceInterface $resource
-     * @return array[]
+     * @param string $resourceClass
+     * @return array<string, mixed[]>
      */
     #[ArrayShape(['search' => "array"])]
-    public function getDescription(string|ResourceInterface $resource): array
+    public function getDescription(string $resourceClass): array
     {
-        if (!property_exists($resource, 'latitude') || !property_exists($resource, 'longitude')) {
+        if (!property_exists($resourceClass, 'latitude') || !property_exists($resourceClass, 'longitude')) {
             throw new \RuntimeException('DistanceFilter can only used with resources having both latitude and longitude properties');
         }
         return [
@@ -52,8 +52,18 @@ final class DistanceFilter extends AbstractFilter
         ];
     }
 
+    /**
+     * @param string $property
+     * @param mixed $value
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     protected function filterProperty(string $property,
-                                      $value,
+                                      mixed $value,
                                       QueryBuilder $queryBuilder,
                                       QueryNameGeneratorInterface $queryNameGenerator,
                                       string $resourceClass,

+ 12 - 2
src/Filter/Utils/FindInSetFilter.php

@@ -10,8 +10,18 @@ use Doctrine\ORM\QueryBuilder;
 use Symfony\Component\PropertyInfo\Type;
 
 final class FindInSetFilter extends AbstractFilter {
+    /**
+     * @param string $property
+     * @param mixed $value
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     protected function filterProperty(string $property,
-                                             $value,
+                                      mixed $value,
                                       QueryBuilder $queryBuilder,
                                       QueryNameGeneratorInterface $queryNameGenerator,
                                       string $resourceClass,
@@ -34,7 +44,7 @@ final class FindInSetFilter extends AbstractFilter {
     /**
      * API docs
      * @param string $resourceClass
-     * @return array[]
+     * @return array<string, mixed[]>
      */
     public function getDescription(string $resourceClass): array
     {

+ 12 - 2
src/Filter/Utils/InFilter.php

@@ -13,8 +13,18 @@ use Symfony\Component\PropertyInfo\Type;
  * Is property included in the given CSV array
  */
 final class InFilter extends AbstractFilter {
+    /**
+     * @param string $property
+     * @param mixed $value
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param mixed[] $context
+     * @return void
+     */
     protected function filterProperty(string $property,
-                                             $value,
+                                      mixed $value,
                                       QueryBuilder $queryBuilder,
                                       QueryNameGeneratorInterface $queryNameGenerator,
                                       string $resourceClass,
@@ -39,7 +49,7 @@ final class InFilter extends AbstractFilter {
     /**
      * API docs
      * @param string $resourceClass
-     * @return array[]
+     * @return array<string, mixed[]>
      */
     public function getDescription(string $resourceClass): array
     {

+ 1 - 1
src/Message/Command/Parameters/AverageChange.php

@@ -11,7 +11,7 @@ class AverageChange
     public function __construct(private int $parametersId)
     { }
 
-    public function getParametersId(){
+    public function getParametersId(): int{
         // Todo: penser à ajouter cette commande à la section routing du fichier config/packages/messenger.yaml
         return $this->parametersId;
     }

+ 1 - 1
src/Message/Handler/ExportHandler.php

@@ -20,7 +20,7 @@ class ExportHandler
         private Notifier $notifier
     ) {}
 
-    public function __invoke(Export $export)
+    public function __invoke(Export $export): void
     {
         $exportRequest = $export->getExportRequest();
         $exportService = $this->handler->getExporterFor($exportRequest);

+ 1 - 1
src/Message/Handler/MailerHandler.php

@@ -22,7 +22,7 @@ class MailerHandler
     {
     }
 
-    public function __invoke(MailerCommand $mailerCommand)
+    public function __invoke(MailerCommand $mailerCommand): void
     {
         $mailerModel = $mailerCommand->getMailerModel();
         $emails = $this->mailer->main($mailerModel);

+ 1 - 1
src/Message/Handler/Parameters/AverageChangeHandler.php

@@ -25,7 +25,7 @@ class AverageChangeHandler
      * Fonction permettant de remettre à jour les notes dans elasticsearch par rapport à la note maximale changée
      * @param AverageChange $averageChange
      */
-    public function __invoke(AverageChange $averageChange)
+    public function __invoke(AverageChange $averageChange): void
     {
         $parameter = $this->parametersRepository->find($averageChange->getParametersId());
         if($parameter){

+ 1 - 1
src/Message/Handler/Typo3/Typo3DeleteCommandHandler.php

@@ -16,7 +16,7 @@ class Typo3DeleteCommandHandler
     /**
      * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
      */
-    public function __invoke(Typo3DeleteCommand $command) {
+    public function __invoke(Typo3DeleteCommand $command): void {
         $this->typo3Service->deleteSite($command->getOrganizationId());
     }
 }

+ 1 - 1
src/Message/Handler/Typo3/Typo3UndeleteCommandHandler.php

@@ -16,7 +16,7 @@ class Typo3UndeleteCommandHandler
     /**
      * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
      */
-    public function __invoke(Typo3UndeleteCommand $command) {
+    public function __invoke(Typo3UndeleteCommand $command): void {
         $this->typo3Service->undeleteSite($command->getOrganizationId());
     }
 }

+ 1 - 1
src/Message/Handler/Typo3/Typo3UpdateCommandHandler.php

@@ -16,7 +16,7 @@ class Typo3UpdateCommandHandler
     /**
      * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
      */
-    public function __invoke(Typo3UpdateCommand $command) {
+    public function __invoke(Typo3UpdateCommand $command): void {
         $this->typo3Service->updateSite($command->getOrganizationId());
     }
 }

+ 5 - 1
src/OpenApi/OpenApiFactory.php

@@ -18,13 +18,17 @@ final class OpenApiFactory implements OpenApiFactoryInterface
         '/api/dolibarr_contracts/{ref}',
     ];
 
-    private $decorated;
+    private mixed $decorated;
 
     public function __construct(OpenApiFactoryInterface $decorated)
     {
         $this->decorated = $decorated;
     }
 
+    /**
+     * @param mixed[] $context
+     * @return OpenApi
+     */
     public function __invoke(array $context = []): OpenApi
     {
         $openApi = $this->decorated->__invoke($context);

+ 18 - 8
src/Repository/Access/AccessRepository.php

@@ -6,6 +6,7 @@ namespace App\Repository\Access;
 use App\DQL\DateConditions;
 use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
+use App\Enum\Access\FunctionEnum;
 use DateTime;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
@@ -40,17 +41,17 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
         if($this->requestStack->getMainRequest()->headers->get(self::HTTP_X_SWITCH_USER) === $identifier)
             return $this->getEntityManager()->find(Access::class, $identifier);
 
-        return $this->findAccessByUsernameAndAccessId($identifier, $this->requestStack->getMainRequest()->headers->get(self::ACCESS_NAME_HEADER));
+        return $this->findAccessByUsernameAndAccessId($identifier, (int) $this->requestStack->getMainRequest()->headers->get(self::ACCESS_NAME_HEADER));
     }
 
     /**
      * Récupère un access grâce à son username et son ID
      * @param string $username
-     * @param $id
+     * @param int $id
      * @return mixed
      * @throws \Doctrine\ORM\NonUniqueResultException
      */
-    private function findAccessByUsernameAndAccessId(string $username, $id): mixed
+    private function findAccessByUsernameAndAccessId(string $username, int $id): mixed
     {
         $entityManager = $this->getEntityManager();
         return $entityManager->createQuery(
@@ -78,6 +79,8 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
     }
 
     /**
+     * Retourne tous les access qui appartiennent à une organisation qui est active dans un réseau
+     *
      * @param Access $access
      * @return mixed
      * @throws \Exception
@@ -99,7 +102,14 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
       ;
     }
 
-    public function hasGotFunctionAtThisDate(Access $access, $function, \DateTime $date): bool
+    /**
+     * Retourne si oui ou non un access possède une fonction F active à une date précise
+     * @param Access $access
+     * @param FunctionEnum $function
+     * @param DateTime $date
+     * @return bool
+     */
+    public function hasGotFunctionAtThisDate(Access $access, FunctionEnum $function, \DateTime $date): bool
     {
         $this->_em->getFilters()->disable('date_time_filter');
 
@@ -125,11 +135,11 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
      * Retourne tous les accesses de l'organization ayant la fonction donnée à la date donnée
      *
      * @param Organization $organization
-     * @param $function
+     * @param string $function
      * @param DateTime|null $date
-     * @return array
+     * @return list<Access>
      */
-    public function findByOrganizationAndMission(Organization $organization, $function, \DateTime $date = null): array
+    public function findByOrganizationAndMission(Organization $organization, string $function, \DateTime $date = null): array
     {
         if ($date === null)
             $date = new DateTime();
@@ -157,7 +167,7 @@ class AccessRepository extends ServiceEntityRepository implements UserLoaderInte
      *
      * Used by App\Service\Dolibarr\DolibarrSync\DolibarrSyncService
      *
-     * @return array
+     * @return list<Access>
      */
     public function getAllActiveMembersAndMissions(): array
     {

+ 5 - 4
src/Repository/Booking/CourseRepository.php

@@ -5,6 +5,7 @@ namespace App\Repository\Booking;
 
 use App\Entity\Booking\Course;
 use App\Entity\Organization\Organization;
+use DateTimeInterface;
 use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
 
@@ -18,11 +19,11 @@ class CourseRepository extends ServiceEntityRepository
     /**
      * Récupère les cours d'une organisation d'une date à une autre
      * @param Organization $organization
-     * @param \DateTimeInterface $start
-     * @param \DateTimeInterface $end
-     * @return array
+     * @param DateTimeInterface $start
+     * @param DateTimeInterface $end
+     * @return list<Course>
      */
-    public function getCoursesToFrom(Organization $organization, \DateTimeInterface $start, \DateTimeInterface $end): array
+    public function getCoursesToFrom(Organization $organization, DateTimeInterface $start, DateTimeInterface $end): array
     {
         $this->_em->getFilters()->disable('activity_year_filter');
 

+ 2 - 2
src/Repository/Core/ContactPointRepository.php

@@ -26,7 +26,7 @@ class ContactPointRepository extends ServiceEntityRepository
      * Récupération des points de contacts d'une organization et d'un type précis
      * @param String $type
      * @param Organization $organization
-     * @return array
+     * @return list<ContactPoint>
      */
     public function getByTypeAndOrganization(String $type, Organization $organization): array
     {
@@ -45,7 +45,7 @@ class ContactPointRepository extends ServiceEntityRepository
      * Récupération des points de contacts d'une person et d'un type précis
      * @param String $type
      * @param Person $person
-     * @return array
+     * @return list<ContactPoint>
      */
     public function getByTypeAndPerson(String $type, Person $person): array
     {

+ 1 - 1
src/Repository/Network/NetworkOrganizationRepository.php

@@ -72,7 +72,7 @@ class NetworkOrganizationRepository extends ServiceEntityRepository
      *
      * @param Organization $organization.
      *
-     * @return array The organizations.
+     * @return list<Organization> The organizations.
      */
     public function findAllParents(Organization $organization): array
     {

+ 1 - 1
src/Repository/Organization/OrganizationAddressPostalRepository.php

@@ -25,7 +25,7 @@ class OrganizationAddressPostalRepository extends ServiceEntityRepository
      * Récupération des adresses postal d'une organization et d'un type précis
      * @param String $type
      * @param Organization $organization
-     * @return array|null
+     * @return list<OrganizationAddressPostal>|null
      */
     public function getByType(String $type, Organization $organization): ?array
     {

+ 1 - 1
src/Security/Voter/BankAccountVoter.php

@@ -15,7 +15,7 @@ class BankAccountVoter extends Voter
     public function __construct(private Security $security)
     { }
 
-    protected function supports($attribute, $subject): bool
+    protected function supports(string $attribute, $subject): bool
     {
         return in_array($attribute, ['BANK_ACCOUNT_READ', 'BANK_ACCOUNT_EDIT', 'BANK_ACCOUNT_DELETE'])
             && $subject instanceof BankAccount;

+ 1 - 1
src/Security/Voter/ContactPointVoter.php

@@ -15,7 +15,7 @@ class ContactPointVoter extends Voter
     public function __construct(private Security $security)
     { }
 
-    protected function supports($attribute, $subject): bool
+    protected function supports(string $attribute, $subject): bool
     {
         return in_array($attribute, ['CONTACT_POINT_READ', 'CONTACT_POINT_EDIT', 'CONTACT_POINT_DELETE'])
             && $subject instanceof ContactPoint;

+ 1 - 1
src/Security/Voter/CotisationVoter.php

@@ -18,7 +18,7 @@ class CotisationVoter extends Voter
         private NetworkUtils $networkUtils)
     { }
 
-    protected function supports($attribute, $subject): bool
+    protected function supports(string $attribute, $subject): bool
     {
         return in_array($attribute, ['COTISATION_CALL']) && $subject instanceof Cotisation;
     }

+ 2 - 1
src/Security/Voter/ModuleVoter.php

@@ -40,13 +40,14 @@ class ModuleVoter extends Voter
      */
     protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
-        if (!$subject->attributes->get('_api_resource_class') || !$resourceMetadata = $this->resourceMetadataFactory->create($subject->attributes->get('_api_resource_class'))) {
+        if (!$subject->attributes->get('_api_resource_class')) {
             throw new AccessDeniedHttpException(sprintf('Missing resource class'));
         }
         if ($token instanceof NullToken) {
             return false;
         }
 
+        $resourceMetadata = $this->resourceMetadataFactory->create($subject->attributes->get('_api_resource_class'));
         $module = $this->module->getModuleByResourceName($resourceMetadata->getOperation()->getShortName());
 
         //Check if there is a module for this entity : eq configuration problem

+ 3 - 1
src/Security/Voter/SwitchUserVoter.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 namespace App\Security\Voter;
 
+use App\Entity\Access\Access;
 use App\Service\Security\SwitchUser;
 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
 use Symfony\Component\Security\Core\Authorization\Voter\Voter;
@@ -14,7 +15,7 @@ class SwitchUserVoter extends Voter
     public function __construct(private Security $security, private SwitchUser $switchUser)
     { }
 
-    protected function supports($attribute, $subject): bool
+    protected function supports(string $attribute, $subject): bool
     {
         return in_array($attribute, ['CAN_SWITCH_USER'])
             && $subject instanceof UserInterface;
@@ -28,6 +29,7 @@ class SwitchUserVoter extends Voter
      */
     protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
     {
+        /** @var Access $user */
         $user = $token->getUser();
 
         // if the user is anonymous or if the subject is not a user, do not grant access

+ 9 - 1
src/Serializer/AccessContextBuilder.php

@@ -22,6 +22,12 @@ final class AccessContextBuilder implements SerializerContextBuilderInterface
     { }
 
 
+    /**
+     * @param Request $request
+     * @param bool $normalization
+     * @param mixed[]|null $extractedAttributes
+     * @return mixed[]
+     */
     public function createFromRequest(Request $request, bool $normalization, ?array $extractedAttributes = null): array
     {
         $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);
@@ -29,11 +35,13 @@ final class AccessContextBuilder implements SerializerContextBuilderInterface
 
         //On ajoute un nouveau groupe seulement si : la ressource est Access, on est en denormalization, l'utilisateur n'a pas le ROLE_USERS
         //et la denormalization est faite sur l'Access de l'utilisateur connecté
+        /** @var Access $access */
+        $access = $this->security->getUser();
         if (
             $resourceClass === Access::class &&
             false === $normalization &&
             !$this->authorizationChecker->isGranted('ROLE_USERS') &&
-            $request->get('id') == $this->security->getUser()->getId()
+            (int) $request->get('id') === $access->getId()
         ){
             $context['groups'] = $context['groups'] ?? [];
             $context['groups'][] = 'my_access:input';

+ 35 - 2
src/Serializer/DefaultNormalizer.php

@@ -5,7 +5,10 @@ namespace App\Serializer;
 
 use App\Entity\Access\Access;
 use App\Service\Utils\EntityUtils;
+use ArrayObject;
+use ReflectionException;
 use Symfony\Bundle\SecurityBundle\Security;
+use Symfony\Component\Serializer\Exception\ExceptionInterface;
 use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 use Symfony\Component\Serializer\SerializerAwareInterface;
@@ -27,23 +30,53 @@ final class DefaultNormalizer implements NormalizerInterface, DenormalizerInterf
         }
     }
 
+    /**
+     * @param $data
+     * @param $format
+     * @param mixed[] $context
+     * @return bool
+     */
     public function supportsNormalization($data, $format = null, array $context = []): bool
     {
         return $this->decorated->supportsNormalization($data, $format);
     }
 
-    public function normalize($object, $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
+    /**
+     * @param $object
+     * @param $format
+     * @param mixed[]  $context
+     * @return mixed
+     * @throws ExceptionInterface
+     */
+    public function normalize($object, $format = null, array $context = []): mixed
     {
         return $this->decorated->normalize($object, $format, $context);
     }
 
+    /**
+     * @param $data
+     * @param $type
+     * @param $format
+     * @param mixed[] $context
+     * @return bool
+     */
     public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
     {
+        /** @phpstan-ignore-next-line */
         return $this->decorated->supportsDenormalization($data, $type, $format);
     }
 
+    /**
+     * @param $data
+     * @param $class
+     * @param $format
+     * @param mixed[] $context
+     * @return mixed
+     * @throws ReflectionException
+     */
     public function denormalize($data, $class, $format = null, array $context = []): mixed
     {
+        /** @phpstan-ignore-next-line */
         $entity = $this->decorated->denormalize($data, $class, $format, $context);
 
         /** @var Access $access */
@@ -53,7 +86,7 @@ final class DefaultNormalizer implements NormalizerInterface, DenormalizerInterf
         return $entity;
     }
 
-    public function setSerializer(SerializerInterface $serializer)
+    public function setSerializer(SerializerInterface $serializer): void
     {
         if($this->decorated instanceof SerializerAwareInterface) {
             $this->decorated->setSerializer($serializer);

+ 5 - 5
src/Service/Access/Utils.php

@@ -18,9 +18,9 @@ use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
 class Utils
 {
     public function __construct(
-        private RoleHierarchyInterface $roleHierarchy,
-        private AccessRepository $accessRepository,
-        private OptionalsRolesIterator $optionalsRolesIterator
+        readonly private RoleHierarchyInterface $roleHierarchy,
+        readonly private AccessRepository $accessRepository,
+        readonly private OptionalsRolesIterator $optionalsRolesIterator
     )
     {}
 
@@ -28,7 +28,7 @@ class Utils
      * Filtre un tableau d'Access pour ne laisser que les Accesses ne correspondant pas à l'Access passé en second parametre
      * @param array<Access> $accesses
      * @param Access $access
-     * @return array
+     * @return array<Access>
      * @see UtilsTest::testFilterAccesses()
      * TODO: est-ce qu'on essaierait pas de trouver un nom plus explicite? j'ai pas trop d'idée la tout de suite cela dit
      */
@@ -55,7 +55,7 @@ class Utils
     /**
      * Va récupérer les roles d'access + les roles optionnels possibles
      * @param Access $access
-     * @return array
+     * @return string[]
      * @see UtilsTest::testGetAllRoles()
      */
     public function getAllRoles(Access $access): array

+ 17 - 6
src/Service/ApiLegacy/ApiLegacyRequestService.php

@@ -11,6 +11,7 @@ use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
 use Symfony\Bundle\SecurityBundle\Security;
 use Symfony\Contracts\HttpClient\HttpClientInterface;
 use Symfony\Contracts\HttpClient\ResponseInterface;
+use App\Entity\Access\Access;
 
 /**
  * Service d'appel à l'API opentalent V1
@@ -27,7 +28,13 @@ class ApiLegacyRequestService extends ApiRequestService
         parent::__construct($apiLegacyClient);
     }
 
-    /** @noinspection PhpPossiblePolymorphicInvocationInspection */
+    /**
+     * @param string $method
+     * @param string $url
+     * @param array<mixed> $parameters
+     * @param array<mixed> $options
+     * @noinspection PhpPossiblePolymorphicInvocationInspection
+     */
     public function request(
         string $method,
         string $url,
@@ -44,20 +51,24 @@ class ApiLegacyRequestService extends ApiRequestService
             'Content-Type' => 'application/ld+json',
         ];
 
+        /** @var Access $activeUser */
+        $activeUser = $token->getUser();
+
         $jwt = null;
         if ($token instanceof SwitchUserToken) {
+            /** @var Access|null $originalUser */
             $originalUser = $token->getOriginalToken()->getUser();
+
             if ($originalUser === null) {
                 throw new HttpException(500, 'Request error : Switch original user missing');
             }
 
             $jwt = $this->jwtManager->create($originalUser->getPerson());
             $headers['x-accessid'] = $originalUser->getId();
-            $headers['x-switch-access'] = $token->getUser()->getId();
-        }
-        elseif ($token !== null && !($token instanceof NullToken) && $token->getUser() !== null) {
-            $jwt = $this->jwtManager->create($token->getUser()->getPerson());
-            $headers['x-accessid'] = $token->getUser()->getId();
+            $headers['x-switch-access'] = $activeUser->getId();
+        } elseif ($token !== null && !($token instanceof NullToken) && $token->getUser() !== null) {
+            $jwt = $this->jwtManager->create($activeUser->getPerson());
+            $headers['x-accessid'] = $activeUser->getId();
         }
 
         if ($jwt !== null) {

+ 19 - 0
src/Service/ApiResourceBuilder/Dolibarr/DolibarrAccountBuilder.php

@@ -52,6 +52,11 @@ class DolibarrAccountBuilder
         return $dolibarrAccount;
     }
 
+    /**
+     * @param int $organizationId
+     * @param array<mixed>|null $accountData
+     * @return DolibarrAccount
+     */
     public function createDolibarrAccount(int $organizationId, ?array $accountData): DolibarrAccount {
         $dolibarrAccount = new DolibarrAccount();
         $dolibarrAccount->setOrganizationId($organizationId);
@@ -73,6 +78,10 @@ class DolibarrAccountBuilder
         return $dolibarrAccount;
     }
 
+    /**
+     * @param array<mixed> $contractData
+     * @return DolibarrContract
+     */
     public function createDolibarrContract(array $contractData): DolibarrContract {
         $contract = new DolibarrContract();
         $contract->setRef($contractData['ref'] ?? '')
@@ -86,6 +95,11 @@ class DolibarrAccountBuilder
         return $contract;
     }
 
+    /**
+     * @param array<mixed> $lineData
+     * @return DolibarrContractLine
+     * @throws \Exception
+     */
     public function createDolibarrContractLine(array $lineData): DolibarrContractLine {
         $line = new DolibarrContractLine();
         return $line->setId((int)$lineData['id'])
@@ -96,6 +110,11 @@ class DolibarrAccountBuilder
                     ->setDateEnd(new \DateTime(date('c', (int)$lineData['date_end'])));
     }
 
+    /**
+     * @param array<mixed> $billData
+     * @return DolibarrBill
+     * @throws \Exception
+     */
     public function createDolibarrBill(array $billData): DolibarrBill {
         $bill = new DolibarrBill();
         return $bill->setId((int)$billData['id'])

+ 16 - 16
src/Service/Constraint/AbstractTimeConstraintUtils.php

@@ -19,20 +19,20 @@ abstract class AbstractTimeConstraintUtils
 
     /**
      * Retourne true si l'utilisateur veux une période précise
-     * @param $historical
+     * @param array<bool|string> $historical
      * @return bool
      * @see DateTimeConstraintTest::testHasCustomPeriods()
      */
-    protected function hasCustomPeriods($historical): bool
+    protected function hasCustomPeriods(array $historical): bool
     {
         return array_key_exists('dateStart', $historical) && $historical['dateStart'] && array_key_exists('dateEnd', $historical) && $historical['dateEnd'];
     }
 
     /**
      * Fonction permettant d'ajouter une nouvelle contrainte de date
-     * @param array $contraints
-     * @param array $newContraint
-     * @return array
+     * @param array<string, array<string, list<int>>> $contraints
+     * @param array<string, list<int>> $newContraint
+     * @return array<string, array<string, int[]>>
      * @see DateTimeConstraintTest::testAddConstraint()
      */
     protected function addConstraint(array $contraints, array $newContraint): array
@@ -43,10 +43,10 @@ abstract class AbstractTimeConstraintUtils
 
     /**
      * Construit le tableau de contraintes pour une condition (start, end)
-     * @param array $contraints
-     * @param array $newContraint
+     * @param array<string, array<string, list<int>>> $contraints
+     * @param array<string, list<int>> $newContraint
      * @param string $key
-     * @return array
+     * @return array<string, array<string, int[]>>
      */
     protected function mergeConstraint(array $contraints, array $newContraint, string $key): array
     {
@@ -68,8 +68,8 @@ abstract class AbstractTimeConstraintUtils
 
     /**
      * Nettoyage des contraintes (toutes celles supérieur à la condition cancel et les valeurs null isolées)
-     * @param array $constraints
-     * @return array
+     * @param array<string, array<string, list<int>>> $constraints
+     * @return array<string, array<string, list<int>>>
      * @see DateTimeConstraintTest::testCleanConstraints()
      */
     protected function cleanConstraints(array $constraints): array
@@ -85,9 +85,9 @@ abstract class AbstractTimeConstraintUtils
     /**
      * Pour chaque contraintes appliquées à une date on vérifie qu'on ne dépasse pas la valeur cancel : c'est à dire
      * la condition qui démontre que toutes les valeurs arithmétiques ont été choisies
-     * @param array $constraints
-     * @param $key
-     * @return array
+     * @param array<string, array<string, list<int>>> $constraints
+     * @param string $key
+     * @return array<string, list<int>>
      * @see DateTimeConstraintTest::testFilterConstraint()
      */
     protected function filterConstraint(array $constraints, string $key): array
@@ -100,9 +100,9 @@ abstract class AbstractTimeConstraintUtils
     /**
      * On ne conserve pas les contraintes sur des conditions start et end si ces dernieres ne possède qu'une valeur null :
      * une valeur null doit obligatoirement s'appliquer avec un OR
-     * @param array $constraints
-     * @param $key
-     * @return array
+     * @param array<string, array<string, list<int>>> $constraints
+     * @param string $key
+     * @return array<string, list<int>>
      * @see DateTimeConstraintTest::testClearNull()
      */
     protected function clearNull(array $constraints, string $key): array

+ 12 - 12
src/Service/Constraint/ActivityYearConstraint.php

@@ -23,7 +23,7 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
      * Main method
      *
      * @param int $accessID
-     * @return array
+     * @return array<string, array<string, list<int>>>
      * @throws \Exception
      */
     public function invoke(int $accessID): array
@@ -53,7 +53,7 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
      * @param Access $access
      * @param string $dateStart
      * @param string $dateEnd
-     * @return string[]
+     * @return int[]
      */
     protected function getRangeYear(Access $access, string $dateStart, string $dateEnd): array
     {
@@ -68,7 +68,7 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
      * Une période est dans le présent si :
      * - l'année de début est égale (=) à l'année à afficher
      * @param int $year
-     * @return array
+     * @return array<string, list<int>>
      */
     protected function presentConstraint(int $year): array
     {
@@ -82,10 +82,10 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
     /**
      * Une période est dans le passée si :
      * - l'année de début est plus petite (<) à l'année à afficher
-     * @param $year
-     * @return array
+     * @param int $year
+     * @return array<string, list<int>>
      */
-    protected function pastConstraint($year): array
+    protected function pastConstraint(int $year): array
     {
         return [
             self::END_KEY => [
@@ -97,10 +97,10 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
     /**
      * Une période est dans le futur si :
      * - l'année de début est plus grande (>) à l'année à afficher
-     * @param $year
-     * @return array
+     * @param int $year
+     * @return array<string, list<int>>
      */
-    protected function futureConstraint($year): array
+    protected function futureConstraint(int $year): array
     {
         return [
             self::START_KEY => [
@@ -115,10 +115,10 @@ class ActivityYearConstraint extends AbstractTimeConstraintUtils
      * - l'année de début est plus grande ou égale (>=) à l'année de départ
      * - l'année de début est plus petite ou égale (<=) à l'année de fin
      *
-     * @param $years
-     * @return array
+     * @param array<int> $years
+     * @return array<string, list<int>>
      */
-    protected function customConstraint($years): array
+    protected function customConstraint(array $years): array
     {
         return [
             self::START_KEY => [

+ 15 - 15
src/Service/Constraint/DateTimeConstraint.php

@@ -7,7 +7,7 @@ use App\Entity\Access\Access;
 use App\Service\Organization\Utils as OrganizationUtils;
 use App\Tests\Service\Constraint\DateTimeConstraintTest;
 use Doctrine\ORM\EntityManagerInterface;
-use JetBrains\PhpStorm\ArrayShape;
+use Exception;
 
 /**
  * Classe DateTimeConstraint qui définie les dates de débuts et fin de périodes
@@ -16,16 +16,16 @@ use JetBrains\PhpStorm\ArrayShape;
 class DateTimeConstraint extends AbstractTimeConstraintUtils
 {
     public function __construct(
-        private EntityManagerInterface $entityManager,
-        private OrganizationUtils $organizationUtils
+        readonly private EntityManagerInterface $entityManager,
+        readonly private OrganizationUtils $organizationUtils
     )
     { }
 
     /**
      * Main méthod
      * @param int $accessID
-     * @return array
-     * @throws \Exception
+     * @return array<string, array<string, list<int>>>
+     * @throws Exception
      */
     public function invoke(int $accessID): array
     {
@@ -69,8 +69,8 @@ class DateTimeConstraint extends AbstractTimeConstraintUtils
      * Fonction permettant de récupérer les périodes de début et de fin d'affichage
      *
      * @param Access $access
-     * @return array
-     * @throws \Exception
+     * @return string[]
+     * @throws Exception
      * @see DateTimeConstraintTest::testGetPeriodsToday()
      */
     protected function getPeriods(Access $access): array
@@ -96,8 +96,8 @@ class DateTimeConstraint extends AbstractTimeConstraintUtils
      * ET
      *  - la date de fin est plus grande ou égale (>=) à la date de fin de période à afficher OU que la date de fin n'est pas remplie (NULL)
      *
-     * @param array $periods
-     * @return array
+     * @param string[] $periods
+     * @return array<string, int[]>
      *
      * @see DateTimeConstraintTest::testPresentConstrain()
      */
@@ -117,11 +117,11 @@ class DateTimeConstraint extends AbstractTimeConstraintUtils
     /**
      * Une période est dans le passé si :
      * - la date de fin est plus petite (<) que la date de début de période à afficher
-     * @param $periods
-     * @return array
+     * @param string[] $periods
+     * @return array<string, int[]>
      * @see DateTimeConstraintTest::testPastConstrain()
      */
-    protected function pastConstraint($periods): array
+    protected function pastConstraint(array $periods): array
     {
         return [
             self::END_KEY => [
@@ -133,11 +133,11 @@ class DateTimeConstraint extends AbstractTimeConstraintUtils
     /**
      * Une période est dans le futur si :
      * - la date de début est plus grande (>) que la date de fin de période à afficher
-     * @param $periods
-     * @return array
+     * @param string[] $periods
+     * @return array<string, int[]>
      * @see DateTimeConstraintTest::testFuturConstrain()
      */
-    protected function futureConstraint($periods): array
+    protected function futureConstraint(array $periods): array
     {
         return [
             self::START_KEY => [

+ 0 - 1
src/Service/Cotisation/Utils.php

@@ -114,7 +114,6 @@ class Utils
 
     /**
      * Retourne dans quelle année de cotisation on est aujourd'hui
-     * @param \DateTime|null $date
      * @return int
      * @throws \Exception
      * @see UtilsTest::testGetCurrentCotisationYear()

+ 5 - 5
src/Service/Cron/Job/CleanTempFiles.php

@@ -105,11 +105,11 @@ class CleanTempFiles extends BaseCronJob implements CronjobInterface
 
         $criteria = new Criteria();
         $criteria->where(
-            Criteria::expr()?->andX(
-                Criteria::expr()?->eq('isTemporaryFile', true),
-                Criteria::expr()?->orX(
-                    Criteria::expr()?->lt('createDate', $maxDate),
-                    Criteria::expr()?->isNull('createDate')
+            Criteria::expr()->andX(
+                Criteria::expr()->eq('isTemporaryFile', true),
+                Criteria::expr()->orX(
+                    Criteria::expr()->lt('createDate', $maxDate),
+                    Criteria::expr()->isNull('createDate')
                 )
             )
         );

+ 1 - 2
src/Service/Cron/UI/ConsoleUI.php

@@ -2,7 +2,6 @@
 
 namespace App\Service\Cron\UI;
 
-use App\Tests\Service\Cron\UI\MockableProgressBar;
 use Symfony\Component\Console\Helper\ProgressBar;
 use Symfony\Component\Console\Output\OutputInterface;
 
@@ -13,7 +12,7 @@ use Symfony\Component\Console\Output\OutputInterface;
  */
 class ConsoleUI implements CronUIInterface
 {
-    protected ProgressBar | MockableProgressBar $progressBar;
+    protected ProgressBar $progressBar;
 
     public function __construct(
         private OutputInterface $output

+ 7 - 3
src/Service/Dolibarr/DolibarrApiService.php

@@ -26,7 +26,7 @@ class DolibarrApiService extends ApiRequestService
      * Get a dolibarr society by its opentalent organization id
      *
      * @param int $organizationId
-     * @return array|null
+     * @return array<mixed>|null
      * @throws \JsonException
      */
     public function getSociety(int $organizationId): ?array
@@ -48,7 +48,7 @@ class DolibarrApiService extends ApiRequestService
      * Get the first active contract for the given dolibarr society
      *
      * @param int $socId
-     * @return array|null
+     * @return array<mixed>|null
      */
     public function getActiveContract(int $socId): ?array
     {
@@ -70,7 +70,7 @@ class DolibarrApiService extends ApiRequestService
      * Get a society bills by their society id
      *
      * @param int $socId
-     * @return array
+     * @return array<mixed>
      */
     public function getBills(int $socId): array
     {
@@ -89,6 +89,8 @@ class DolibarrApiService extends ApiRequestService
 
     /**
      * Get all the societies which are Opentalent client
+     *
+     * @return array<mixed>
      * @throws HttpException
      */
     public function getAllClients(): array
@@ -102,6 +104,7 @@ class DolibarrApiService extends ApiRequestService
     /**
      * Get the society contacts
      *
+     * @return array<mixed>
      * @throws HttpException
      */
     public function getContacts(int $socId): array
@@ -123,6 +126,7 @@ class DolibarrApiService extends ApiRequestService
     /**
      * Get the society contacts that have a non-null personId
      *
+     * @return array<mixed>
      * @throws HttpException
      */
     public function getActiveOpentalentContacts(int $socId): array

+ 20 - 20
src/Service/Dolibarr/DolibarrSyncService.php

@@ -71,10 +71,10 @@ class DolibarrSyncService
      *
      * Returns an array of DolibarrSyncOperations
      *
+     * @param callable | null $progressionCallback A callback method for indicating the current progression of the process;
+     *                                           Shall accept two integer arguments: current progression, and total.
      * @return array<BaseRestOperation>
      * @throws Exception
-     * @var callable | null $progressionCallback A callback method for indicating the current progression of the process;
-     *                                           Shall accept two integer arguments: current progression, and total.
      *
      * @noinspection NullPointerExceptionInspection
      */
@@ -233,8 +233,8 @@ class DolibarrSyncService
                     'lastname' => trim($person->getName()),
                     'firstname' => trim($person->getGivenName()),
                     'email' => $contact?->getEmail(),
-                    'phone_pro' => $contact?->getTelphone() ? $this->formatPhoneNumber($contact?->getTelphone()) : null,
-                    'phone_mobile' => $contact?->getMobilPhone() ? $this->formatPhoneNumber($contact?->getMobilPhone()): null,
+                    'phone_pro' => $contact?->getTelphone() ? $this->formatPhoneNumber($contact->getTelphone()) : null,
+                    'phone_mobile' => $contact?->getMobilPhone() ? $this->formatPhoneNumber($contact->getMobilPhone()): null,
                     'poste' => $this->formatContactPosition($missions, $person->getGender()),
                     'statut' => '1'
                 ];
@@ -318,10 +318,10 @@ class DolibarrSyncService
      * Returns an array of DolibarrSyncOperations
      *
      * @param array<BaseRestOperation> $operations
+     * @param callable | null $progressionCallback A callback method for indicating the current progression of the process;
+     *                                           Shall accept two integer arguments: current progression, and total.
      * @return array<BaseRestOperation>
      * @throws Exception
-     *@var callable | null $progressionCallback A callback method for indicating the current progression of the process;
-     *                                           Shall accept two integer arguments: current progression, and total.
      */
     public function execute(array $operations, ?callable $progressionCallback = null): array
     {
@@ -361,7 +361,7 @@ class DolibarrSyncService
                     try {
                         $this->validateResponse($response, $operation);
                     } catch (RuntimeException $e) {
-                        $this->logger->warning($e);
+                        $this->logger->warning($e->getMessage());
                     }
                 }
 
@@ -369,7 +369,7 @@ class DolibarrSyncService
             } catch (RuntimeException $e) {
                 $this->logger->error('Error while executing operation : ' . $operation);
                 $this->logger->error(implode("\n", $operation->getChangeLog()));
-                $this->logger->error($e);
+                $this->logger->error($e->getMessage());
                 $errors++;
             }
 
@@ -408,7 +408,7 @@ class DolibarrSyncService
     /**
      * Get the client societies dolibarr and index them by organization id
      *
-     * @return array An index of the form [$organizationId => $dolibarrData]
+     * @return array<mixed> An index of the form [$organizationId => $dolibarrData]
      */
     protected function getDolibarrSocietiesIndex(): array
     {
@@ -440,7 +440,7 @@ class DolibarrSyncService
      *
      * Index is the form: [$organizationId => [$accessId => [$mission, $mission...], $accessId...], $organizationId2...]
      *
-     * @return array
+     * @return array<mixed>
      */
     protected function getActiveMembersIndex(): array
     {
@@ -467,9 +467,9 @@ class DolibarrSyncService
      *
      * If none are found with the person id, try to find one with the same full name and no person id
      *
-     * @param array $dolibarrContacts
+     * @param array<mixed> $dolibarrContacts
      * @param Person $person
-     * @return array|null
+     * @return array<mixed>|null
      */
     protected function findDolibarrContactFor(array $dolibarrContacts, Person $person): ?array
     {
@@ -488,8 +488,8 @@ class DolibarrSyncService
                 !($contactData["array_options"]["options_2iopen_person_id"] ?? null) &&
                 $person->getName() !== null &&
                 $person->getGivenName() !== null &&
-                strtolower($person->getName() ?? '') === strtolower($contactData["lastname"] ?? '') &&
-                strtolower($person->getGivenName() ?? '') === strtolower($contactData["firstname"] ?? '')
+                strtolower($person->getName()) === strtolower($contactData["lastname"] ?? '') &&
+                strtolower($person->getGivenName()) === strtolower($contactData["firstname"] ?? '')
             ) {
                 return $contactData;
             }
@@ -504,8 +504,8 @@ class DolibarrSyncService
      * As far as we know, there is no harm here to replace every empty string value by a null value
      * (no loss of information)
      *
-     * @param array|null $data
-     * @return array|null
+     * @param array<mixed>|null $data
+     * @return array<mixed>|null
      */
     protected function sanitizeDolibarrData(?array $data): ?array
     {
@@ -630,8 +630,8 @@ class DolibarrSyncService
     /**
      * Returns the number of accesses possessing at least one of the missions
      *
-     * @param array $missions A list of missions
-     * @param array $members An organization members as returned by getActiveMembersIndex: [$accessID => [$missions...]]
+     * @param array<mixed> $missions A list of missions
+     * @param array<mixed> $members An organization members as returned by getActiveMembersIndex: [$accessID => [$missions...]]
      * @return int
      */
     protected function countWithMission(array $missions, array $members): int
@@ -670,7 +670,7 @@ class DolibarrSyncService
     /**
      * Format the contact position from its gender and missions
      *
-     * @param array $missions
+     * @param list<string> $missions
      * @param string|null $gender
      * @return string
      */
@@ -733,7 +733,7 @@ class DolibarrSyncService
      * In the case of a validation error, throw an HttpException
      *
      * @param ResponseInterface $response
-     * @param BaseRestOperation $operation
+     * @param UpdateOperation | CreateOperation  $operation
      * @throws RuntimeException
      */
     protected function validateResponse(ResponseInterface $response, UpdateOperation | CreateOperation $operation): void

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels