瀏覽代碼

resolve conflicts

Olivier Massot 2 年之前
父節點
當前提交
4b40ff9463
共有 100 個文件被更改,包括 964 次插入648 次删除
  1. 2 2
      .env
  2. 6 1
      .gitignore
  3. 3 1
      .gitlab-ci.yml
  4. 73 28
      composer.json
  5. 0 26
      config/api_platform/Access/access.yaml
  6. 10 8
      config/bundles.php
  7. 16 0
      config/opentalent/modulesbyconditions.yaml
  8. 2 1
      config/opentalent/products.yaml
  9. 0 5
      config/packages/debug.yaml
  10. 2 0
      config/packages/docker/hautelook_alice.yaml
  11. 9 0
      config/packages/docker/nelmio_alice.yaml
  12. 4 0
      config/packages/docker/zenstruck_foundry.yaml
  13. 0 4
      config/packages/framework.yaml
  14. 0 5
      config/packages/hautelook_alice.yaml
  15. 0 9
      config/packages/messenger.yaml
  16. 0 44
      config/packages/monolog.yaml
  17. 0 12
      config/packages/nelmio_alice.yaml
  18. 0 8
      config/packages/prod/deprecations.yaml
  19. 0 13
      config/packages/security.yaml
  20. 4 0
      config/packages/staging/debug.yaml
  21. 2 0
      config/packages/staging/hautelook_alice.yaml
  22. 9 0
      config/packages/staging/nelmio_alice.yaml
  23. 4 0
      config/packages/staging/zenstruck_foundry.yaml
  24. 11 0
      config/packages/test/security.yaml
  25. 0 6
      config/packages/test/web_profiler.yaml
  26. 0 17
      config/packages/web_profiler.yaml
  27. 0 7
      config/packages/zenstruck_foundry.yaml
  28. 0 4
      config/routes/framework.yaml
  29. 0 0
      config/routes/prod/.gitkeep
  30. 3 0
      config/routes/staging/framework.yaml
  31. 0 0
      config/routes/test/.gitkeep
  32. 0 8
      config/routes/web_profiler.yaml
  33. 9 34
      config/services.yaml
  34. 21 0
      config/services/api-platform.yaml
  35. 7 0
      config/services/monolog.yaml
  36. 3 0
      doc/internal_requests.md
  37. 186 0
      doc/security.md
  38. 2 2
      public/index.php
  39. 1 1
      sql/schema-extensions/002-view_federation_structures.sql
  40. 1 14
      src/ApiResources/Access/AdminAccess.php
  41. 10 9
      src/ApiResources/Cotisation/Cotisation.php
  42. 59 0
      src/ApiResources/OnlineRegistration/RegistrationAvailability.php
  43. 48 0
      src/ApiResources/OnlineRegistration/RegistrationStatus.php
  44. 3 3
      src/ApiResources/Profile/OrganizationProfile.php
  45. 37 7
      src/Doctrine/AbstractExtension.php
  46. 0 11
      src/Doctrine/Access/AccessExtensionInterface.php
  47. 15 0
      src/Doctrine/Access/AdditionalExtension/AdditionalAccessExtensionInterface.php
  48. 6 3
      src/Doctrine/Access/AdditionalExtension/DateTimeConstraintExtensionAdditional.php
  49. 7 4
      src/Doctrine/Access/AdditionalExtension/StudentsExtensionAdditional.php
  50. 6 32
      src/Doctrine/Access/CurrentAccessExtension.php
  51. 7 7
      src/Doctrine/Access/CurrentUserPersonalizedListExtension.php
  52. 7 6
      src/Doctrine/Billing/CurrentResidenceAreaExtension.php
  53. 7 6
      src/Doctrine/Booking/CurrentCoursesExtension.php
  54. 6 5
      src/Doctrine/Core/AllowedAddressPostalExtension.php
  55. 7 6
      src/Doctrine/Core/CurrentUserNotificationExtension.php
  56. 7 6
      src/Doctrine/Core/CurrentUserNotificationUserExtension.php
  57. 6 7
      src/Doctrine/Education/CurrentCycleExtension.php
  58. 7 6
      src/Doctrine/Education/CurrentEducationNotationConfigExtension.php
  59. 7 6
      src/Doctrine/Education/CurrentEducationTimingExtension.php
  60. 7 6
      src/Doctrine/Network/CurrentNetworkOrganizationExtension.php
  61. 7 6
      src/Doctrine/Organization/CurrentOrganizationAddressPostalExtension.php
  62. 7 6
      src/Doctrine/Organization/CurrentOrganizationArticleExtension.php
  63. 6 5
      src/Doctrine/Organization/CurrentOrganizationExtension.php
  64. 32 7
      src/Entity/Access/Access.php
  65. 2 8
      src/Entity/Access/AccessFamily.php
  66. 1 1
      src/Entity/Access/OrganizationFunction.php
  67. 6 1
      src/Entity/Access/PersonalizedList.php
  68. 44 2
      src/Entity/AccessWish/AccessFamilyWish.php
  69. 55 2
      src/Entity/AccessWish/AccessWish.php
  70. 40 1
      src/Entity/AccessWish/EducationStudentWish.php
  71. 2 8
      src/Entity/Billing/AccessBilling.php
  72. 1 1
      src/Entity/Billing/AccessIntangible.php
  73. 1 7
      src/Entity/Billing/AccessPayer.php
  74. 2 8
      src/Entity/Billing/Bill.php
  75. 1 7
      src/Entity/Billing/BillAccounting.php
  76. 2 8
      src/Entity/Billing/BillCredit.php
  77. 2 8
      src/Entity/Billing/BillLine.php
  78. 1 7
      src/Entity/Billing/BillingIntangibleExcludeDate.php
  79. 1 5
      src/Entity/Billing/BillingSetting.php
  80. 2 8
      src/Entity/Billing/EducationalProjectPayer.php
  81. 2 8
      src/Entity/Billing/FamilyQuotient.php
  82. 5 18
      src/Entity/Billing/ResidenceArea.php
  83. 2 8
      src/Entity/Booking/Attendance.php
  84. 1 7
      src/Entity/Booking/AttendanceBooking.php
  85. 5 9
      src/Entity/Booking/Course.php
  86. 2 8
      src/Entity/Booking/EducationalProject.php
  87. 1 7
      src/Entity/Booking/Event.php
  88. 2 8
      src/Entity/Booking/EventUser.php
  89. 2 8
      src/Entity/Booking/Examen.php
  90. 3 1
      src/Entity/Booking/ExamenConvocation.php
  91. 2 8
      src/Entity/Booking/OrganizationHoliday.php
  92. 2 8
      src/Entity/Booking/PersonHoliday.php
  93. 1 1
      src/Entity/Core/AbstractInformation.php
  94. 7 8
      src/Entity/Core/AddressPostal.php
  95. 4 15
      src/Entity/Core/BankAccount.php
  96. 4 15
      src/Entity/Core/ContactPoint.php
  97. 46 6
      src/Entity/Core/File.php
  98. 4 1
      src/Entity/Core/Notification.php
  99. 3 0
      src/Entity/Core/NotificationUser.php
  100. 2 8
      src/Entity/Core/Tagg.php

+ 2 - 2
.env

@@ -66,7 +66,7 @@ MAILER_DSN=smtp://localhost
 ###< symfony/mailer ###
 ###< symfony/mailer ###
 
 
 ###> bindfile populate buffer file
 ###> bindfile populate buffer file
-BIND_FILE_BUFFER_FILE=/env/subdomain.txt
+BIND_FILE_BUFFER_FILE=var/subdomain.txt
 ###< bindfile populate buffer file
 ###< bindfile populate buffer file
 
 
 ###> elasticsearch ###
 ###> elasticsearch ###
@@ -106,5 +106,5 @@ LOG_FILE_NAME=undefined
 
 
 ### Internal requests (@see doc/internal_requests.md)
 ### Internal requests (@see doc/internal_requests.md)
 INTERNAL_REQUESTS_TOKEN=sRyfu6SZLR9StpnSKYRdl6i9wr5qs1bJQzro4DUiVyYJ2jknl
 INTERNAL_REQUESTS_TOKEN=sRyfu6SZLR9StpnSKYRdl6i9wr5qs1bJQzro4DUiVyYJ2jknl
-INTERNAL_FILES_DOWNLOAD_URI=https://api.opentalent.fr/_internal/secure/files
+INTERNAL_FILES_DOWNLOAD_URI=https://local.api.opentalent.fr/_internal/secure/files
 ###
 ###

+ 6 - 1
.gitignore

@@ -40,4 +40,9 @@ symfony.lock
 
 
 ###> phpstan ###
 ###> phpstan ###
 .phpstan.neon
 .phpstan.neon
-###< phpstan ###
+###< phpstan ###
+public/phpstorm_debug_validator.phar
+
+public/phpstorm_debug.php
+
+public/phpstorm_index.php

+ 3 - 1
.gitlab-ci.yml

@@ -16,7 +16,9 @@ before_script:
 
 
 static_analysis:
 static_analysis:
   script:
   script:
-    - php --version && php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format gitlab > phpstan.json
+    - php --version
+    - php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon.dist --error-format gitlab > phpstan.json  # Display code quality in MR
+    - php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon.dist  # Display in console
   artifacts:
   artifacts:
     when: always
     when: always
     reports:
     reports:

+ 73 - 28
composer.json

@@ -15,7 +15,7 @@
     "php": ">=8.1",
     "php": ">=8.1",
     "ext-ctype": "*",
     "ext-ctype": "*",
     "ext-iconv": "*",
     "ext-iconv": "*",
-    "api-platform/core": "^3.1",
+    "api-platform/core": "3.1.7",
     "beberlei/doctrineextensions": "^1.3",
     "beberlei/doctrineextensions": "^1.3",
     "blackfire/php-sdk": "^1.23",
     "blackfire/php-sdk": "^1.23",
     "composer/package-versions-deprecated": "^1.11",
     "composer/package-versions-deprecated": "^1.11",
@@ -36,33 +36,33 @@
     "phpdocumentor/reflection-docblock": "^5.2",
     "phpdocumentor/reflection-docblock": "^5.2",
     "ramsey/uuid": "^4.2",
     "ramsey/uuid": "^4.2",
     "ramsey/uuid-doctrine": "^2.0",
     "ramsey/uuid-doctrine": "^2.0",
-    "symfony/asset": "6.2.*",
-    "symfony/console": "6.2.*",
-    "symfony/doctrine-messenger": "6.2.*",
-    "symfony/dotenv": "6.2.*",
-    "symfony/error-handler": "6.2.*",
-    "symfony/expression-language": "6.2.*",
+    "symfony/asset": "6.3.*",
+    "symfony/console": "6.3.*",
+    "symfony/doctrine-messenger": "6.3.*",
+    "symfony/dotenv": "6.3.*",
+    "symfony/error-handler": "6.3.*",
+    "symfony/expression-language": "6.3.*",
     "symfony/flex": "^1.3.1",
     "symfony/flex": "^1.3.1",
-    "symfony/framework-bundle": "6.2.*",
-    "symfony/http-client": "6.2.*",
-    "symfony/intl": "6.2.*",
-    "symfony/lock": "6.2.*",
-    "symfony/mailer": "6.2.*",
+    "symfony/framework-bundle": "6.3.*",
+    "symfony/http-client": "6.3.*",
+    "symfony/intl": "6.3.*",
+    "symfony/lock": "6.3.*",
+    "symfony/mailer": "6.3.*",
     "symfony/mercure": "^0.6.1",
     "symfony/mercure": "^0.6.1",
     "symfony/mercure-bundle": "^0.3.4",
     "symfony/mercure-bundle": "^0.3.4",
-    "symfony/messenger": "6.2.*",
+    "symfony/messenger": "6.3.*",
     "symfony/monolog-bundle": "^3.7",
     "symfony/monolog-bundle": "^3.7",
     "symfony/polyfill-intl-icu": "^1.21",
     "symfony/polyfill-intl-icu": "^1.21",
     "symfony/polyfill-intl-messageformatter": "^1.24",
     "symfony/polyfill-intl-messageformatter": "^1.24",
-    "symfony/property-access": "6.2.*",
-    "symfony/property-info": "6.2.*",
-    "symfony/security-bundle": "6.2.*",
-    "symfony/serializer": "6.2.*",
-    "symfony/translation": "6.2.*",
-    "symfony/twig-bundle": "6.2.*",
-    "symfony/uid": "6.2.*",
-    "symfony/validator": "6.2.*",
-    "symfony/yaml": "6.2.*",
+    "symfony/property-access": "6.3.*",
+    "symfony/property-info": "6.3.*",
+    "symfony/security-bundle": "6.3.*",
+    "symfony/serializer": "6.3.*",
+    "symfony/translation": "6.3.*",
+    "symfony/twig-bundle": "6.3.*",
+    "symfony/uid": "6.3.*",
+    "symfony/validator": "6.3.*",
+    "symfony/yaml": "6.3.*",
     "twig/cssinliner-extra": "^3.4",
     "twig/cssinliner-extra": "^3.4",
     "twig/extra-bundle": "^3.4",
     "twig/extra-bundle": "^3.4",
     "twig/inky-extra": "^3.4",
     "twig/inky-extra": "^3.4",
@@ -84,13 +84,13 @@
     "phpstan/phpstan-symfony": "^1.2",
     "phpstan/phpstan-symfony": "^1.2",
     "phpunit/phpunit": "^9.6",
     "phpunit/phpunit": "^9.6",
     "rector/rector": "^0.15.13",
     "rector/rector": "^0.15.13",
-    "symfony/browser-kit": "6.2.*",
-    "symfony/css-selector": "6.2.*",
-    "symfony/debug-bundle": "6.2.*",
+    "symfony/browser-kit": "6.3.*",
+    "symfony/css-selector": "6.3.*",
+    "symfony/debug-bundle": "6.3.*",
     "symfony/maker-bundle": "^1.48",
     "symfony/maker-bundle": "^1.48",
     "symfony/phpunit-bridge": "^6.2",
     "symfony/phpunit-bridge": "^6.2",
-    "symfony/stopwatch": "6.2.*",
-    "symfony/web-profiler-bundle": "6.2.*",
+    "symfony/stopwatch": "6.3.*",
+    "symfony/web-profiler-bundle": "6.3.*",
     "timeweb/phpstan-enum": "^3.1",
     "timeweb/phpstan-enum": "^3.1",
     "zenstruck/foundry": "^1.31"
     "zenstruck/foundry": "^1.31"
   },
   },
@@ -110,6 +110,51 @@
     "psr-4": {
     "psr-4": {
       "App\\": "src/"
       "App\\": "src/"
     },
     },
+    "classmap": [
+      "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocx.php",
+      "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocxFromTemplate.php"
+    ],
+    "autoload-dev": {
+        "psr-4": {
+            "DataFixtures\\": "tests/Fixture",
+            "App\\Tests\\": "tests/"
+        }
+    },
+    "replace": {
+        "paragonie/random_compat": "2.*",
+        "symfony/polyfill-ctype": "*",
+        "symfony/polyfill-iconv": "*",
+        "symfony/polyfill-php72": "*",
+        "symfony/polyfill-php71": "*",
+        "symfony/polyfill-php70": "*",
+        "symfony/polyfill-php56": "*"
+    },
+    "scripts": {
+        "auto-scripts": {
+            "cache:clear": "symfony-cmd",
+            "assets:install %PUBLIC_DIR%": "symfony-cmd"
+        },
+        "post-install-cmd": [
+            "@auto-scripts"
+        ],
+        "post-update-cmd": [
+            "@auto-scripts"
+        ]
+    },
+    "conflict": {
+        "symfony/symfony": "*"
+    },
+    "extra": {
+        "symfony": {
+            "allow-contrib": false,
+            "require": "6.3.*"
+        },
+        "phpstan": {
+            "includes": [
+                "extension.neon"
+            ]
+        }
+    }
     "classmap": [
     "classmap": [
       "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocx.php",
       "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocx.php",
       "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocxFromTemplate.php"
       "vendor/opentalent/phpdocx/Classes/Phpdocx/Create/CreateDocxFromTemplate.php"
@@ -156,4 +201,4 @@
       ]
       ]
     }
     }
   }
   }
-}
+}

+ 0 - 26
config/api_platform/Access/access.yaml

@@ -1,35 +1,9 @@
 resources:
 resources:
   App\Entity\Access\Access:
   App\Entity\Access\Access:
     - operations:
     - operations:
-        ApiPlatform\Metadata\GetCollection: ~
-
         ApiPlatform\Metadata\Get:
         ApiPlatform\Metadata\Get:
           security: '(is_granted("ROLE_USERS_VIEW") and object.getOrganization().getId() == user.getOrganization().getId()) or (object.getId() == user.getId())'
           security: '(is_granted("ROLE_USERS_VIEW") and object.getOrganization().getId() == user.getOrganization().getId()) or (object.getId() == user.getId())'
 
 
         ApiPlatform\Metadata\Put:
         ApiPlatform\Metadata\Put:
           security: 'is_granted("ROLE_USERS") or (object.getId() == user.getId())'
           security: 'is_granted("ROLE_USERS") or (object.getId() == user.getId())'
 
 
-        ApiPlatform\Metadata\Delete: ~
-
-    - operations:
-        ApiPlatform\Metadata\GetCollection:
-          name: 'cget_students'
-          uriTemplate: '/students'
-          security: 'is_granted("ROLE_USERS_VIEW")'
-
-    - operations:
-        ApiPlatform\Metadata\GetCollection:
-          name: 'cget_access_person_ref'
-          uriTemplate: '/access_people'
-          normalization_context:
-            groups: [ 'access_people_ref' ]
-
-    - operations:
-        ApiPlatform\Metadata\Get:
-          name: 'get_access_address'
-          uriTemplate: '/access_addresses/{id}'
-          requirements:
-            id: '\d+'
-          normalization_context:
-            groups: [ 'access_address', 'address' ] ]
-          security: 'object.getOrganization().getId() == user.getOrganization().getId()'

+ 10 - 8
config/bundles.php

@@ -1,9 +1,10 @@
 <?php
 <?php
 
 
+$devEnvs = ['dev' => true, 'docker' => true, 'test' => false, 'staging' => true];
+
 return [
 return [
     Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
     Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
     Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
     Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
-    Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'docker' => true, 'test' => true, 'staging' => true],
     Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
     Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
     Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
     Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
     Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
     Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
@@ -12,17 +13,18 @@ return [
     Jb\Bundle\PhumborBundle\JbPhumborBundle::class => ['all' => true],
     Jb\Bundle\PhumborBundle\JbPhumborBundle::class => ['all' => true],
     Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true],
     Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true],
     Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
     Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
-    Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true, 'docker' => true, 'staging' => true],
     FOS\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
     FOS\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
     Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true],
     Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true],
     Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true],
     Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true],
     Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
     Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
-    Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'docker' => true, 'test' => true, 'staging' => true],
     Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
     Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
     Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
     Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
-    Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'staging' => true],
-    Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['staging' => true],
-    Hautelook\AliceBundle\HautelookAliceBundle::class => ['staging' => true],
-    Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['staging' => true],
-    Zenstruck\Foundry\ZenstruckFoundryBundle::class => ['staging' => true],
+    Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => $devEnvs,
+    Symfony\Bundle\MakerBundle\MakerBundle::class => $devEnvs,
+    Symfony\Bundle\DebugBundle\DebugBundle::class => $devEnvs,
+    Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => $devEnvs,
+    Zenstruck\Foundry\ZenstruckFoundryBundle::class => $devEnvs,
+    Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => $devEnvs,
+    Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => $devEnvs,
+    Hautelook\AliceBundle\HautelookAliceBundle::class => $devEnvs,
 ];
 ];

+ 16 - 0
config/opentalent/modulesbyconditions.yaml

@@ -1,5 +1,21 @@
 parameters:
 parameters:
     opentalent.modulesbyconditions:
     opentalent.modulesbyconditions:
+        ConsultOwnPedagogicResult:
+          conditions:
+            service:
+              name: App\Service\Education\Utils
+              function: isConsultOwnPedagogicResult
+        TeacherContactList:
+          conditions:
+            service:
+              name: App\Service\Education\Utils
+              function: isConsultTeacherListing
+        PeriodValidation:
+          conditions:
+            service:
+              name: App\Service\Education\Utils
+              function: isPeriodValidation
+
         CotisationCall:
         CotisationCall:
             roles:
             roles:
                 - ROLE_COTISATION
                 - ROLE_COTISATION

+ 2 - 1
config/opentalent/products.yaml

@@ -228,6 +228,8 @@ parameters:
             - AccessTmp
             - AccessTmp
             - EducationStudentWish
             - EducationStudentWish
             - OnlineRegistrationSettings
             - OnlineRegistrationSettings
+            - RegistrationStatus
+            - RegistrationAvailability
           roles:
           roles:
             - ROLE_ONLINEREGISTRATION_ADMINISTRATION
             - ROLE_ONLINEREGISTRATION_ADMINISTRATION
 
 
@@ -283,7 +285,6 @@ parameters:
           - Messages
           - Messages
           - Tagg
           - Tagg
           - Statistic
           - Statistic
-          - Cotisation
           - Dolibarr
           - Dolibarr
 
 
       artist_premium:
       artist_premium:

+ 0 - 5
config/packages/debug.yaml

@@ -1,5 +0,0 @@
-when@dev:
-    debug:
-        # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
-        # See the "server:dump" command to start a new server.
-        dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

+ 2 - 0
config/packages/docker/hautelook_alice.yaml

@@ -0,0 +1,2 @@
+hautelook_alice:
+    fixtures_path: fixtures

+ 9 - 0
config/packages/docker/nelmio_alice.yaml

@@ -0,0 +1,9 @@
+nelmio_alice:
+    functions_blacklist:
+        - 'current'
+        - 'shuffle'
+        - 'date'
+        - 'time'
+        - 'file'
+        - 'md5'
+        - 'sha1'

+ 4 - 0
config/packages/docker/zenstruck_foundry.yaml

@@ -0,0 +1,4 @@
+# See full configuration: https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#full-default-bundle-configuration
+zenstruck_foundry:
+    # Whether to auto-refresh proxies by default (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#auto-refresh)
+    auto_refresh_proxies: true

+ 0 - 4
config/packages/framework.yaml

@@ -40,7 +40,3 @@ framework:
                     Content-Type: 'application/json'
                     Content-Type: 'application/json'
             apiLegacyClient:
             apiLegacyClient:
                 base_uri: '%env(API_LEG_BASE_URL)%'
                 base_uri: '%env(API_LEG_BASE_URL)%'
-
-when@staging:
-    framework:
-        test: true

+ 0 - 5
config/packages/hautelook_alice.yaml

@@ -1,5 +0,0 @@
-when@dev: &dev
-    hautelook_alice:
-        fixtures_path: fixtures
-
-when@staging: *dev

+ 0 - 9
config/packages/messenger.yaml

@@ -17,12 +17,3 @@ framework:
             'App\Message\Command\Typo3\Typo3UpdateCommand': async
             'App\Message\Command\Typo3\Typo3UpdateCommand': async
             'App\Message\Command\Typo3\Typo3DeleteCommand': async
             'App\Message\Command\Typo3\Typo3DeleteCommand': async
             'App\Message\Command\Typo3\Typo3UndeleteCommand': async
             'App\Message\Command\Typo3\Typo3UndeleteCommand': async
-
-
-# when@test:
-#    framework:
-#        messenger:
-#            transports:
-#                # replace with your transport name here (e.g., my_transport: 'in-memory://')
-#                # For more Messenger testing tools, see https://github.com/zenstruck/messenger-test
-#                async: 'in-memory://'

+ 0 - 44
config/packages/monolog.yaml

@@ -1,47 +1,3 @@
 monolog:
 monolog:
     channels:
     channels:
         - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
         - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
-
-when@dev:
-    monolog:
-        handlers:
-            main:
-                type: stream
-                path: "%kernel.logs_dir%/%kernel.environment%.log"
-                level: debug
-                channels: ["!event"]
-            # uncomment to get logging in your browser
-            # you may have to allow bigger header sizes in your Web server configuration
-            #firephp:
-            #    type: firephp
-            #    level: info
-            #chromephp:
-            #    type: chromephp
-            #    level: info
-            console:
-                type: console
-                process_psr_3_messages: false
-                channels: ["!event", "!doctrine", "!console"]
-
-when@prod:
-    monolog:
-        handlers:
-            main:
-                type: fingers_crossed
-                action_level: error
-                handler: nested
-                excluded_http_codes: [404, 405]
-                buffer_size: 50 # How many messages should be saved? Prevent memory leaks
-            nested:
-                type: stream
-                path: php://stderr
-                level: debug
-                formatter: monolog.formatter.json
-            console:
-                type: console
-                process_psr_3_messages: false
-                channels: ["!event", "!doctrine"]
-            deprecation:
-                type: stream
-                channels: [deprecation]
-                path: php://stderr

+ 0 - 12
config/packages/nelmio_alice.yaml

@@ -1,12 +0,0 @@
-when@dev: &dev
-    nelmio_alice:
-        functions_blacklist:
-            - 'current'
-            - 'shuffle'
-            - 'date'
-            - 'time'
-            - 'file'
-            - 'md5'
-            - 'sha1'
-
-when@staging: *dev

+ 0 - 8
config/packages/prod/deprecations.yaml

@@ -1,8 +0,0 @@
-# As of Symfony 5.1, deprecations are logged in the dedicated "deprecation" channel when it exists
-#monolog:
-#    channels: [deprecation]
-#    handlers:
-#        deprecation:
-#            type: stream
-#            channels: [deprecation]
-#            path: php://stderr

+ 0 - 13
config/packages/security.yaml

@@ -172,16 +172,3 @@ security:
         - { path: ^/api/internal, roles: INTERNAL_REQUEST }
         - { path: ^/api/internal, roles: INTERNAL_REQUEST }
         - { path: ^/api/internal, roles: ROLE_NO_ACCESS }
         - { path: ^/api/internal, roles: ROLE_NO_ACCESS }
         - { path: ^/api/, roles: IS_HAVING_MODULE }
         - { path: ^/api/, roles: IS_HAVING_MODULE }
-
-when@test:
-    security:
-        password_hashers:
-            # By default, password hashers are resource intensive and take time. This is
-            # important to generate secure password hashes. In tests however, secure hashes
-            # are not important, waste resources and increase test times. The following
-            # reduces the work factor to the lowest possible values.
-            Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
-                algorithm: auto
-                cost: 4 # Lowest possible value for bcrypt
-                time_cost: 3 # Lowest possible value for argon
-                memory_cost: 10 # Lowest possible value for argon

+ 4 - 0
config/packages/staging/debug.yaml

@@ -0,0 +1,4 @@
+debug:
+    # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
+    # See the "server:dump" command to start a new server.
+    dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

+ 2 - 0
config/packages/staging/hautelook_alice.yaml

@@ -0,0 +1,2 @@
+hautelook_alice:
+    fixtures_path: fixtures

+ 9 - 0
config/packages/staging/nelmio_alice.yaml

@@ -0,0 +1,9 @@
+nelmio_alice:
+    functions_blacklist:
+        - 'current'
+        - 'shuffle'
+        - 'date'
+        - 'time'
+        - 'file'
+        - 'md5'
+        - 'sha1'

+ 4 - 0
config/packages/staging/zenstruck_foundry.yaml

@@ -0,0 +1,4 @@
+# See full configuration: https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#full-default-bundle-configuration
+zenstruck_foundry:
+    # Whether to auto-refresh proxies by default (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#auto-refresh)
+    auto_refresh_proxies: true

+ 11 - 0
config/packages/test/security.yaml

@@ -0,0 +1,11 @@
+security:
+  password_hashers:
+    # By default, password hashers are resource intensive and take time. This is
+    # important to generate secure password hashes. In tests however, secure hashes
+    # are not important, waste resources and increase test times. The following
+    # reduces the work factor to the lowest possible values.
+    Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
+      algorithm: auto
+      cost: 4 # Lowest possible value for bcrypt
+      time_cost: 3 # Lowest possible value for argon
+      memory_cost: 10 # Lowest possible value for argon

+ 0 - 6
config/packages/test/web_profiler.yaml

@@ -1,6 +0,0 @@
-web_profiler:
-    toolbar: false
-    intercept_redirects: false
-
-framework:
-    profiler: { collect: false }

+ 0 - 17
config/packages/web_profiler.yaml

@@ -1,17 +0,0 @@
-when@dev:
-    web_profiler:
-        toolbar: true
-        intercept_redirects: false
-
-    framework:
-        profiler:
-            only_exceptions: false
-            collect_serializer_data: true
-
-when@test:
-    web_profiler:
-        toolbar: false
-        intercept_redirects: false
-
-    framework:
-        profiler: { collect: false }

+ 0 - 7
config/packages/zenstruck_foundry.yaml

@@ -1,7 +0,0 @@
-when@dev: &dev
-    # See full configuration: https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#full-default-bundle-configuration
-    zenstruck_foundry:
-        # Whether to auto-refresh proxies by default (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#auto-refresh)
-        auto_refresh_proxies: true
-
-when@staging: *dev

+ 0 - 4
config/routes/framework.yaml

@@ -1,4 +0,0 @@
-when@dev:
-    _errors:
-        resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
-        prefix: /_error

+ 0 - 0
config/routes/prod/.gitkeep


+ 3 - 0
config/routes/staging/framework.yaml

@@ -0,0 +1,3 @@
+_errors:
+    resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
+    prefix: /_error

+ 0 - 0
config/routes/test/.gitkeep


+ 0 - 8
config/routes/web_profiler.yaml

@@ -1,8 +0,0 @@
-when@dev:
-    web_profiler_wdt:
-        resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
-        prefix: /_wdt
-
-    web_profiler_profiler:
-        resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
-        prefix: /_profiler

+ 9 - 34
config/services.yaml

@@ -1,35 +1,13 @@
 # config/services.yaml
 # config/services.yaml
 imports:
 imports:
     - { resource: opentalent/* }
     - { resource: opentalent/* }
+    - { resource: services/* }
 
 
 # Put parameters here that don't need to change on each machine where the app is deployed
 # Put parameters here that don't need to change on each machine where the app is deployed
 # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
 # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
 parameters:
 parameters:
 
 
 services:
 services:
-    ########### Speeds up api-platform cache build substantially ###########
-    #### see https://github.com/api-platform/core/issues/4975  ####
-    api_platform.cache.metadata.property:
-        parent: cache.system
-        tags: [ cache.pool ]
-    api_platform.cache.metadata.resource:
-        parent: cache.system
-        tags: [ cache.pool ]
-    api_platform.cache.metadata.resource_collection:
-        parent: cache.system
-        tags: [ cache.pool ]
-    api_platform.cache.route_name_resolver:
-        parent: cache.system
-        tags: [ cache.pool ]
-    api_platform.cache.identifiers_extractor:
-        parent: cache.system
-        tags: [ cache.pool ]
-    api_platform.elasticsearch.cache.metadata.document:
-        parent: cache.system
-        tags: [ cache.pool ]
-
-    ########### End Speeds up api-platform cache build substantially ###########
-
     # default configuration for services in *this* file
     # default configuration for services in *this* file
     _defaults:
     _defaults:
         autowire: true      # Automatically injects dependencies in your services.
         autowire: true      # Automatically injects dependencies in your services.
@@ -43,13 +21,6 @@ services:
             $removeProcessor: '@api_platform.doctrine.orm.state.remove_processor'
             $removeProcessor: '@api_platform.doctrine.orm.state.remove_processor'
             $opentalentNoReplyEmailAddress: 'noreply@opentalent.fr'
             $opentalentNoReplyEmailAddress: 'noreply@opentalent.fr'
 
 
-    # Logging: a shorter version of the default monolog line formatter
-    monolog.formatter.message:
-        class: Monolog\Formatter\LineFormatter
-        arguments:
-            - "[%%datetime%%] %%level_name%% : %%message%%\n"
-            - "Y-m-d H:i:s.v"
-
     # makes classes in src/ available to be used as services
     # makes classes in src/ available to be used as services
     # this creates a service per class whose id is the fully-qualified class name
     # this creates a service per class whose id is the fully-qualified class name
     App\:
     App\:
@@ -68,6 +39,9 @@ services:
     App\Service\Cotisation\Utils:
     App\Service\Cotisation\Utils:
         public: true
         public: true
 
 
+    App\Service\Education\Utils:
+        public: true
+
     App\Service\Network\Utils:
     App\Service\Network\Utils:
         public: true
         public: true
 
 
@@ -76,10 +50,14 @@ services:
 
 
     Gaufrette\Filesystem: '@knp_gaufrette.filesystem_map'
     Gaufrette\Filesystem: '@knp_gaufrette.filesystem_map'
 
 
+    # To use the test fixtures
+    App\Tests\Fixture\:
+        resource: '%kernel.project_dir%/tests/Fixture/*'
+
     #########################################
     #########################################
     ##  TAG Services ##
     ##  TAG Services ##
     _instanceof:
     _instanceof:
-        App\Doctrine\Access\AccessExtensionInterface:
+        App\Doctrine\Access\AdditionalExtension\AdditionalAccessExtensionInterface:
             tags: ['app.extensions.access']
             tags: ['app.extensions.access']
         App\Service\Access\OptionalsRolesInterface:
         App\Service\Access\OptionalsRolesInterface:
             tags: ['app.optionalsroles']
             tags: ['app.optionalsroles']
@@ -139,6 +117,3 @@ services:
     Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
     Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
     #########################################
     #########################################
 
 
-    # To use the test fixtures
-    App\Tests\Fixture\:
-        resource: '%kernel.project_dir%/tests/Fixture/*'

+ 21 - 0
config/services/api-platform.yaml

@@ -0,0 +1,21 @@
+services:
+    # Speeds up api-platform cache build substantially
+    # @see https://github.com/api-platform/core/issues/4975
+    api_platform.cache.metadata.property:
+      parent: cache.system
+      tags: [ cache.pool ]
+    api_platform.cache.metadata.resource:
+      parent: cache.system
+      tags: [ cache.pool ]
+    api_platform.cache.metadata.resource_collection:
+      parent: cache.system
+      tags: [ cache.pool ]
+    api_platform.cache.route_name_resolver:
+      parent: cache.system
+      tags: [ cache.pool ]
+    api_platform.cache.identifiers_extractor:
+      parent: cache.system
+      tags: [ cache.pool ]
+    api_platform.elasticsearch.cache.metadata.document:
+      parent: cache.system
+      tags: [ cache.pool ]

+ 7 - 0
config/services/monolog.yaml

@@ -0,0 +1,7 @@
+services:
+    # Logging: a shorter version of the default monolog line formatter
+    monolog.formatter.message:
+      class: Monolog\Formatter\LineFormatter
+      arguments:
+        - "[%%datetime%%] %%level_name%% : %%message%%\n"
+        - "Y-m-d H:i:s.v"

+ 3 - 0
doc/internal_requests.md

@@ -46,6 +46,9 @@ Les appels à cette route ne sont autorisés que si :
 
 
 Si ces deux conditions ne sont pas remplies, la requête est rejetée, et ce même si l'utilisateur est authentifié.
 Si ces deux conditions ne sont pas remplies, la requête est rejetée, et ce même si l'utilisateur est authentifié.
 
 
+Les routes internal sont configurées ici : `config/packages/security.yaml`
+
+
 
 
 ### Valider le fonctionnement
 ### Valider le fonctionnement
 
 

+ 186 - 0
doc/security.md

@@ -0,0 +1,186 @@
+# Security
+
+## Authentification Symfony
+
+### Fonctionnement de base
+
+L'authentification se fait via une requête POST envoyée à l'adresse `/login_check` avec le body suivant : 
+
+    {
+        "username": "login",
+        "password": "password"
+    }
+
+En cas de succès, la requête renvoie un token qui servira ensuite à l'utilisateur à s'identifier.
+
+Les requêtes suivantes devront posséder les headers suivants : 
+
+* `x-accessid` : l'id de l'utilisateur (ou Access)
+* `authorization` : une chaine de caractères de la forme "BEARER XXXXX", où XXXXX est le token retourné par la requête de login
+
+### Connexion Switch
+
+Certains utilisateurs (admins, familles) peuvent prendre le rôle d'un autre utilisateur via la connexion switch.
+
+Pour ce faire, un nouveau header doit être ajouté aux requêtes : 
+
+* `x-switch-user`: l'id de l'utilisateur dont on veut prendre le rôle
+
+
+
+## Roles et Modules
+
+Les droits d'un utilisateur sont conditionnés à différents critères, dont : 
+
+* Les **modules** que possède l'organisation à laquelle il est appartient
+* Les **rôles** de cet utilisateur au sein de cette organisation
+
+On peut obtenir la liste des modules de l'organisation et des rôles de l'utilisateur actif en son sein au moyen de la 
+requête : `/api/my_profile`
+
+
+### Modules
+
+Les modules d'une organisation dépendent du produit acheté par celle-ci et des éventuels modules complémentaires. Ces deux 
+informations sont stoquées dans la table `Settings`.
+
+Le fichier `config/opentalent/products.yaml` définit :
+
+- L'appartenance des _modules_ aux _products_
+- L'appartenance des _entities_ aux _modules_
+
+De plus, le fichier `config/opentalent/modulesbyconditions.yaml` complète cette configuration en définissant des modules
+présentant des conditions particulières (appartenance à la CMF en particulier)
+
+A chaque requête effectuée, la classe `\App\Security\Voter\ModuleVoter` vérifie si la ressource demandée appartient à un
+module possédé par l'organisation de l'utilisateur. Si ce n'est pas le cas, une erreur `AccessDeniedHttpException` est levée.
+
+
+## Différentes méthodes de sécurisation
+
+### Les annotations Api-Platform
+
+La sécurité des ApiResources peut être définie de manière globale pour la ressource, ou pour chaque opération (Get, 
+GetCollection, Put, Post, Delete) via les annotations.
+
+Exemple : 
+
+    #[ApiResource(
+        operations: [
+            new Get(
+                security: '(is_granted("ROLE_ORGANIZATION_VIEW") or is_granted("ROLE_ORGANIZATION")) and object.getOrganization().getId() == user.getOrganization().getId()'
+            ),
+            new Put(
+                security: 'is_granted("ROLE_ORGANIZATION") and object.getOrganization().getId() == user.getOrganization().getId()'
+            )
+        ],
+    )]
+
+Dans certains cas plus complexes (ex: Access), cette configuration peut être déplacée dans un fichier de configuration
+situé dans le répertoire `~/config/api_platform/` et portant le nom de la ressource.
+
+> Voir plus : https://api-platform.com/docs/core/security/
+
+
+### Voters
+
+Les voters permettent de contrôler l'accès à certaines ressources, selon le type d'opération.
+
+Ils implémentent essentiellement deux méthodes : `supports` et `voteOnAttribute` qui prennent en paramètres la ressource 
+et le type d'opération. `supports` retourne `true` si le voter doit s'appliquer dans ce cas. Si oui, `voteOnAttribute`
+est appellée et retourne `true` si l'opération est autorisée.
+
+> TODO: quand faut-il retourner false et quand faut-il lever une AccessDeniedHttpException ?
+
+Pour qu'un Voter soit appellé, il faut configurer la sécurité de la ressource via son annotation et utiliser la méthode 
+`is_granted` combinée à une des constantes : 
+
+Exemple : 
+
+    #[ApiResource(
+        operations: [
+            new Get(security: "is_granted('READ', object)"),
+            new Put(security: "is_granted('EDIT', object)"),
+            new Post(security: "is_granted('CREATE', object)"),
+            new Delete(security: "is_granted('DELETE', object)"),
+        ]
+    )]
+    class File
+
+    
+
+Les voters custom sont enregistrés dans le répertoire `src/Security/Voter`.
+
+> Voir plus : https://symfony.com/doc/current/security/voters.html
+
+
+### Extensions Doctrine
+
+Le framework Api-Platform propose un système d'extensions doctrine pour ajouter des filtres automatiques aux opérations
+réalisées sur des ressources voulues.
+
+Concrètement, l'extension ajoutera une condition au `WHERE` de la requête SQL.
+
+Une extension implémente trois méthodes : 
+
+* `applyToCollection`
+* `applyToItem`
+* `addWhere`
+
+Les deux premières permettent de tester si l'extension doit s'appliquer à la ressource.
+
+La dernière ajoute la condition en question.
+
+> Voir : https://api-platform.com/docs/core/extensions/
+
+
+### Quand utiliser les annotations, un Voter ou une Extension Doctrine ?
+
+Si la sécurité doit pouvoir s'appliquer à une collection et filtrer le résultat de celle-ci (exemple: les notifications 
+d'un utilisateur) : on utilisera une _Extension Doctrine_
+
+Sinon, si les conditions d'accès peuvent s'écrire facilement avec l'expression language des annotations
+api-platform, on utilisera les _annotations Api-platform_.
+
+Si aucune des conditions précédentes n'est remplie, on utilisera un _Voter Symfony_.
+
+
+## Internal Requests
+
+Certaines routes de la forme `/internal/...` permettent d'accepter des requêtes sans que le client ne
+soit authentifié (cf `config/packages/security.yaml`), en se basant sur un contrôle de l'IP et un token. 
+
+> Voir: https://gitlab.2iopenservice.com/opentalent/ap2i/-/blob/develop/doc/internal_requests.md
+
+
+
+## Cas particuliers 
+
+### Les Fichiers
+
+Le client est autorisé à consulter l'enregistrement si l'une de ces conditions est vraie :
+
+* pas de date de disponibilité ou date de disponibilité antérieure à Now
+* date de disponibilité postérieure à Now, mais utilisateur a le rôle ROLE_BILLACCOUNTING et le fichier est de type BILL (facture)
+* visibilité est 'EVERYBODY' 
+* requête interne
+* est connecté et fait partie des AccessPersons du fichier
+* est connecté et est le propriétaire du fichier
+* est connecté et a le rôle ROLE_FILE et fichier appartient à l'utilisateur ou à son organisation
+* est connecté et fichier a des accessRoles et user a un des roles présents dans accessRoles et fichier appartient à l'utilisateur ou à son organisation (deprecated)
+
+
+Est autorisé à éditer si :
+
+* pas de date de disponibilité ou date de disponibilité antérieure à Now
+* date de disponibilité postérieure à Now, mais utilisateur a le rôle ROLE_BILLACCOUNTING et le fichier est de type BILL (facture)
+* est connecté et a le rôle ROLE_FILE et fichier appartient à l'utilisateur ou à son organisation
+* est connecté et est le propriétaire du fichier
+
+Est autorisé à créer si :
+
+* est connecté
+
+Est autorisé à supprimer si :
+
+* est connecté et est autorisé à éditer

+ 2 - 2
public/index.php

@@ -42,10 +42,10 @@ $response->send();
 $kernel->terminate($request, $response);
 $kernel->terminate($request, $response);
 
 
 // If the header is set
 // If the header is set
-//if (isset($_SERVER['HTTP_BLACKFIRETRIGGER'])) {
+if (isset($_SERVER['HTTP_BLACKFIRETRIGGER'])) {
     // When runtime shuts down, let's finish the profiling session
     // When runtime shuts down, let's finish the profiling session
     register_shutdown_function(function () use ($blackfire, $probe) {
     register_shutdown_function(function () use ($blackfire, $probe) {
         // See the PHP SDK documentation for using the $profile object
         // See the PHP SDK documentation for using the $profile object
         $profile = $blackfire->endProbe($probe);
         $profile = $blackfire->endProbe($probe);
     });
     });
-//}
+}

+ 1 - 1
sql/schema-extensions/002-view_federation_structures.sql

@@ -1,6 +1,6 @@
 CREATE OR REPLACE VIEW view_federation_structures
 CREATE OR REPLACE VIEW view_federation_structures
 AS
 AS
-    SELECT o.id, o.name, o.logo_id as logoId, o.description, o.image_id as imageId, o.principalType as type, p.otherWebsite as website,
+    SELECT o.id, o.name, o.logo_id as logoId, o.description, o.image_id as imageId, o.principalType as type, p.website as website,
            CONCAT('[', GROUP_CONCAT(COLUMN_JSON(COLUMN_CREATE(
            CONCAT('[', GROUP_CONCAT(COLUMN_JSON(COLUMN_CREATE(
                    'type', oa.type, 'latitude', a.latitude, 'longitude', a.longitude,
                    'type', oa.type, 'latitude', a.latitude, 'longitude', a.longitude,
                    'streetAddress', TRIM(BOTH '\n' FROM CONCAT_WS('\n', a.streetAddress, a.streetAddressSecond, a.streetAddressThird)),
                    'streetAddress', TRIM(BOTH '\n' FROM CONCAT_WS('\n', a.streetAddress, a.streetAddressSecond, a.streetAddressThird)),

+ 1 - 14
src/ApiResources/Access/AdminAccess.php

@@ -15,20 +15,7 @@ use Symfony\Component\Validator\Constraints as Assert;
 /**
 /**
  * Classe resource qui contient les champs d'un compte admin
  * Classe resource qui contient les champs d'un compte admin
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            uriTemplate: '/admin/{id}',
-            defaults: ['id' => 0],
-            provider: AdminAccessProvider::class
-        ),
-        new Put(
-            uriTemplate: '/admin/{id}',
-            defaults: ['id' => 0],
-            processor: AdminAccessProcessor::class
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 class AdminAccess implements ApiResourcesInterface
 class AdminAccess implements ApiResourcesInterface
 {
 {
     #[ApiProperty(identifier: true)]
     #[ApiProperty(identifier: true)]

+ 10 - 9
src/ApiResources/Cotisation/Cotisation.php

@@ -12,16 +12,17 @@ use Symfony\Component\Validator\Constraints as Assert;
 
 
 /**
 /**
  * Classe resource qui contient les informations des cotisations de la 5.9
  * Classe resource qui contient les informations des cotisations de la 5.9
+ *
+ * Security :
+ *   * @see App\Security\Voter\CotisationVoter
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            uriTemplate: '/cotisations/{organizationId}',
-            security: 'is_granted("ROLE_COTISATION", object) and object.getOrganizationId() == user.getOrganization().getId()',
-            provider: CotisationProvider::class
-        )
-    ]
-)]
+#[ApiResource(operations: [
+    new Get(
+        uriTemplate: '/cotisations/{organizationId}',
+        security: 'is_granted("ROLE_COTISATION", object) and object.getOrganizationId() == user.getOrganization().getId()',
+        provider: CotisationProvider::class
+    )
+])]
 class Cotisation implements ApiResourcesInterface
 class Cotisation implements ApiResourcesInterface
 {
 {
     #[ApiProperty(identifier: true)]
     #[ApiProperty(identifier: true)]

+ 59 - 0
src/ApiResources/OnlineRegistration/RegistrationAvailability.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\ApiResources\OnlineRegistration;
+
+use ApiPlatform\Metadata\ApiProperty;
+use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Metadata\Get;
+use App\ApiResources\ApiResourcesInterface;
+use App\State\Provider\OnlineRegistration\RegistrationAvailabilityProvider;
+
+#[ApiResource(
+    operations: [
+        new Get(
+            uriTemplate: '/online_registration/availability/{accessId}',
+            requirements: ['accessId' => '\\d+'],
+            defaults: ['accessId' => 0],
+            provider: RegistrationAvailabilityProvider::class
+        )
+    ]
+)]
+class RegistrationAvailability implements ApiResourcesInterface
+{
+    #[ApiProperty(identifier: true)]
+    private int $accessId;
+
+    private bool $available;
+
+    private ?string $message = null;
+
+    public function getAccessId(): int
+    {
+        return $this->accessId;
+    }
+
+    public function setAccessId(int $accessId): void
+    {
+        $this->accessId = $accessId;
+    }
+
+    public function isAvailable(): bool
+    {
+        return $this->available;
+    }
+
+    public function setAvailable(bool $available): void
+    {
+        $this->available = $available;
+    }
+
+    public function getMessage(): ?string
+    {
+        return $this->message;
+    }
+
+    public function setMessage(?string $message): void
+    {
+        $this->message = $message;
+    }
+}

+ 48 - 0
src/ApiResources/OnlineRegistration/RegistrationStatus.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\ApiResources\OnlineRegistration;
+
+use ApiPlatform\Metadata\ApiProperty;
+use ApiPlatform\Metadata\ApiResource;
+use ApiPlatform\Metadata\Get;
+use App\ApiResources\ApiResourcesInterface;
+use App\State\Provider\OnlineRegistration\RegistrationStatusProvider;
+use Symfony\Component\Serializer\Annotation\Groups;
+
+#[ApiResource(
+    operations: [
+        new Get(
+            uriTemplate: '/online_registration/status/{accessId}',
+            requirements: ['accessId' => '\\d+'],
+            defaults: ['accessId' => 0],
+            provider: RegistrationStatusProvider::class
+        )
+    ]
+)]
+class RegistrationStatus implements ApiResourcesInterface
+{
+    #[ApiProperty(identifier: true)]
+    private int $accessId;
+
+    private ?string $status = null;
+
+    public function getAccessId(): int
+    {
+        return $this->accessId;
+    }
+
+    public function setAccessId(int $accessId): void
+    {
+        $this->accessId = $accessId;
+    }
+
+    public function getStatus(): ?string
+    {
+        return $this->status;
+    }
+
+    public function setStatus(?string $status): void
+    {
+        $this->status = $status;
+    }
+}

+ 3 - 3
src/ApiResources/Profile/OrganizationProfile.php

@@ -40,14 +40,14 @@ class OrganizationProfile implements ApiResourcesInterface
     #[Groups('access_profile_read')]
     #[Groups('access_profile_read')]
     private ?string $website = null;
     private ?string $website = null;
 
 
-    /** @var list<string>|null $modules  */
+    /** @var list<string> $modules  */
     #[Groups('access_profile_read')]
     #[Groups('access_profile_read')]
     private ?array $modules = [];
     private ?array $modules = [];
 
 
     #[Groups('access_profile_read')]
     #[Groups('access_profile_read')]
     private bool $hasChildren = false;
     private bool $hasChildren = false;
 
 
-    /** @var list<Organization>|null  */
+    /** @var list<OrganizationProfile>  */
     #[Groups('access_profile_read')]
     #[Groups('access_profile_read')]
     private ?array $parents = [];
     private ?array $parents = [];
 
 
@@ -160,7 +160,7 @@ class OrganizationProfile implements ApiResourcesInterface
     }
     }
 
 
     /**
     /**
-     * @return list<Organization>
+     * @return list<OrganizationProfile>
      */
      */
     public function getParents(): array
     public function getParents(): array
     {
     {

+ 37 - 7
src/Doctrine/AbstractExtension.php

@@ -11,11 +11,13 @@ use Doctrine\ORM\QueryBuilder;
 use Exception;
 use Exception;
 
 
 /**
 /**
- * Classe ... qui ...
+ * Base class for custom doctrine extensions
  */
  */
 abstract class AbstractExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 abstract class AbstractExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
 {
 {
     /**
     /**
+     * Called by doctrine when getting a collection
+     *
      * @param QueryBuilder $queryBuilder
      * @param QueryBuilder $queryBuilder
      * @param QueryNameGeneratorInterface $queryNameGenerator
      * @param QueryNameGeneratorInterface $queryNameGenerator
      * @param string $resourceClass
      * @param string $resourceClass
@@ -26,10 +28,12 @@ abstract class AbstractExtension implements QueryCollectionExtensionInterface, Q
      */
      */
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
     public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
     {
     {
-        $this->addWhere($queryBuilder, $resourceClass);
+        $this->apply($queryBuilder, $resourceClass, $operation);
     }
     }
 
 
     /**
     /**
+     * Called by doctrine when getting an item
+     *
      * @param QueryBuilder $queryBuilder
      * @param QueryBuilder $queryBuilder
      * @param QueryNameGeneratorInterface $queryNameGenerator
      * @param QueryNameGeneratorInterface $queryNameGenerator
      * @param string $resourceClass
      * @param string $resourceClass
@@ -41,11 +45,37 @@ abstract class AbstractExtension implements QueryCollectionExtensionInterface, Q
      */
      */
     public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, Operation $operation = null, array $context = []): void
     public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, Operation $operation = null, array $context = []): void
     {
     {
-        $this->addWhere($queryBuilder, $resourceClass);
+        $this->apply($queryBuilder, $resourceClass, $operation);
     }
     }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        throw new Exception('need override addWhere function', 500);
+    /**
+     * Generic application of the extension
+     *
+     * @param $queryBuilder
+     * @param $resourceClass
+     * @return void
+     */
+    protected function apply(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void {
+        if (!$this->supports($resourceClass, $operation)) {
+            return;
+        }
+        $this->addWhere($queryBuilder, $resourceClass, $operation);
     }
     }
-}
+
+    /**
+     * Returns true if the extension supports the given resource
+     *
+     * @param string $resourceClass
+     * @return bool
+     */
+    abstract protected function supports(string $resourceClass, ?Operation $operation): bool;
+
+    /**
+     * Add one or more filters to the query
+     *
+     * @param QueryBuilder $queryBuilder
+     * @param string $resourceClass
+     * @return void
+     */
+    abstract protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void;
+}

+ 0 - 11
src/Doctrine/Access/AccessExtensionInterface.php

@@ -1,11 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Doctrine\Access;
-
-use Doctrine\ORM\QueryBuilder;
-
-interface AccessExtensionInterface{
-    public function support(string $name): bool;
-    public function addWhere(QueryBuilder $queryBuilder): void;
-}

+ 15 - 0
src/Doctrine/Access/AdditionalExtension/AdditionalAccessExtensionInterface.php

@@ -0,0 +1,15 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Doctrine\Access\AdditionalExtension;
+
+use Doctrine\ORM\QueryBuilder;
+
+/**
+ * Complément d'extension pour CurrentAccessExtension.
+ * Les classes implémentant cette interface seront appellées par le service CurrentAccessExtensionIterator
+ */
+interface AdditionalAccessExtensionInterface{
+    public function support(string $name): bool;
+    public function addWhere(QueryBuilder $queryBuilder): void;
+}

+ 6 - 3
src/Doctrine/Access/Extensions/DateTimeConstraintExtension.php → src/Doctrine/Access/AdditionalExtension/DateTimeConstraintExtensionAdditional.php

@@ -1,13 +1,16 @@
 <?php
 <?php
 declare(strict_types=1);
 declare(strict_types=1);
 
 
-namespace App\Doctrine\Access\Extensions;
+namespace App\Doctrine\Access\AdditionalExtension;
 
 
-use App\Doctrine\Access\AccessExtensionInterface;
 use Doctrine\ORM\QueryBuilder;
 use Doctrine\ORM\QueryBuilder;
 use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\HttpFoundation\RequestStack;
 
 
-class DateTimeConstraintExtension implements AccessExtensionInterface {
+/**
+ * Contrainte supplémentaire pour CurrentAccessExtension.
+ * Ajoute un critère de dates
+ */
+class DateTimeConstraintExtensionAdditional implements AdditionalAccessExtensionInterface {
     public function __construct(
     public function __construct(
         private RequestStack $requestStack
         private RequestStack $requestStack
     ){
     ){

+ 7 - 4
src/Doctrine/Access/Extensions/StudentsExtension.php → src/Doctrine/Access/AdditionalExtension/StudentsExtensionAdditional.php

@@ -1,12 +1,15 @@
 <?php
 <?php
 declare(strict_types=1);
 declare(strict_types=1);
 
 
-namespace App\Doctrine\Access\Extensions;
+namespace App\Doctrine\Access\AdditionalExtension;
 
 
-use App\Doctrine\Access\AccessExtensionInterface;
 use Doctrine\ORM\QueryBuilder;
 use Doctrine\ORM\QueryBuilder;
 
 
-class StudentsExtension implements AccessExtensionInterface {
+/**
+ * Contrainte supplémentaire pour CurrentAccessExtension.
+ *
+ */
+class StudentsExtensionAdditional implements AdditionalAccessExtensionInterface {
 
 
     public function support(string $name): bool
     public function support(string $name): bool
     {
     {
@@ -16,4 +19,4 @@ class StudentsExtension implements AccessExtensionInterface {
     public function addWhere(QueryBuilder $queryBuilder): void
     public function addWhere(QueryBuilder $queryBuilder): void
     {
     {
     }
     }
-}
+}

+ 6 - 32
src/Doctrine/Access/CurrentAccessExtension.php

@@ -7,6 +7,7 @@ use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
 use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
 use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
 use ApiPlatform\Metadata\Operation;
 use ApiPlatform\Metadata\Operation;
+use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Service\ServiceIterator\CurrentAccessExtensionIterator;
 use App\Service\ServiceIterator\CurrentAccessExtensionIterator;
 use Doctrine\ORM\QueryBuilder;
 use Doctrine\ORM\QueryBuilder;
@@ -16,7 +17,7 @@ use Symfony\Bundle\SecurityBundle\Security;
  * Class CurrentAccessExtension : Filtre de sécurité par défaut pour une resource Access
  * Class CurrentAccessExtension : Filtre de sécurité par défaut pour une resource Access
  * @package App\Doctrine\Access
  * @package App\Doctrine\Access
  */
  */
-final class CurrentAccessExtension  implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
+final class CurrentAccessExtension extends AbstractExtension
 {
 {
     public function __construct(
     public function __construct(
         private Security $security,
         private Security $security,
@@ -24,39 +25,12 @@ 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());
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === Access::class;
     }
     }
 
 
-    /**
-     * @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
+    public function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
     {
     {
-        $this->addWhere($queryBuilder, $resourceClass, $operation?->getName());
-    }
-
-    public function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?string $operationName): void
-    {
-        if (Access::class !== $resourceClass) {
-            return;
-        }
-
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -65,6 +39,6 @@ final class CurrentAccessExtension  implements QueryCollectionExtensionInterface
             ->setParameter('current_organization', $currentUser->getOrganization())
             ->setParameter('current_organization', $currentUser->getOrganization())
         ;
         ;
 
 
-        $this->currentAccessExtensionIterator->addWhere($queryBuilder, $operationName);
+        $this->currentAccessExtensionIterator->addWhere($queryBuilder, $operation?->getName());
     }
     }
 }
 }

+ 7 - 7
src/Doctrine/Access/CurrentUserPersonalizedListExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Access;
 namespace App\Doctrine\Access;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\PersonalizedList;
 use App\Entity\Access\PersonalizedList;
 use Doctrine\ORM\QueryBuilder;
 use Doctrine\ORM\QueryBuilder;
@@ -17,16 +18,15 @@ final class CurrentUserPersonalizedListExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (PersonalizedList::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === PersonalizedList::class;
+    }
 
 
-        /** @var PersonalizedList $currentUser */
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $queryBuilder->andWhere(sprintf('%s.access = :current_access', $rootAlias));
         $queryBuilder->andWhere(sprintf('%s.access = :current_access', $rootAlias));
         $queryBuilder->setParameter('current_access', $currentUser);
         $queryBuilder->setParameter('current_access', $currentUser);
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Billing/CurrentResidenceAreaExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Billing;
 namespace App\Doctrine\Billing;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Billing\ResidenceArea;
 use App\Entity\Billing\ResidenceArea;
@@ -18,12 +19,12 @@ final class CurrentResidenceAreaExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (ResidenceArea::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === ResidenceArea::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentResidenceAreaExtension extends AbstractExtension
             ->setParameter('billingSetting', $currentUser->getOrganization()->getBillingSetting())
             ->setParameter('billingSetting', $currentUser->getOrganization()->getBillingSetting())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Booking/CurrentCoursesExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Booking;
 namespace App\Doctrine\Booking;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Booking\Course;
 use App\Entity\Booking\Course;
@@ -18,15 +19,15 @@ final class CurrentCoursesExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === Course::class;
+    }
+
     /**
     /**
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      */
      */
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
     {
     {
-        if (Course::class !== $resourceClass) {
-            return;
-        }
-
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -37,4 +38,4 @@ final class CurrentCoursesExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 6 - 5
src/Doctrine/Core/AllowedAddressPostalExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Core;
 namespace App\Doctrine\Core;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Core\AddressPostal;
 use App\Entity\Core\AddressPostal;
@@ -18,12 +19,12 @@ final class AllowedAddressPostalExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (AddressPostal::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === AddressPostal::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];

+ 7 - 6
src/Doctrine/Core/CurrentUserNotificationExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Core;
 namespace App\Doctrine\Core;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Core\Notification;
 use App\Entity\Core\Notification;
@@ -10,7 +11,7 @@ use Doctrine\ORM\QueryBuilder;
 use Symfony\Bundle\SecurityBundle\Security;
 use Symfony\Bundle\SecurityBundle\Security;
 
 
 /**
 /**
- * Class NotificationExtension : Filtre de sécurité par défaut pour une resource Notification
+ * Filtre de sécurité par défaut pour une resource Notification
  * @package App\Doctrine\Core
  * @package App\Doctrine\Core
  */
  */
 final class CurrentUserNotificationExtension extends AbstractExtension
 final class CurrentUserNotificationExtension extends AbstractExtension
@@ -18,15 +19,15 @@ final class CurrentUserNotificationExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === Notification::class;
+    }
+
     /**
     /**
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      */
      */
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
     {
     {
-        if (Notification::class !== $resourceClass) {
-            return;
-        }
-
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];

+ 7 - 6
src/Doctrine/Core/CurrentNotificationUserExtension.php → src/Doctrine/Core/CurrentUserNotificationUserExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Core;
 namespace App\Doctrine\Core;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Core\NotificationUser;
 use App\Entity\Core\NotificationUser;
@@ -14,20 +15,20 @@ use Symfony\Bundle\SecurityBundle\Security;
  *
  *
  * @package App\Doctrine\Core
  * @package App\Doctrine\Core
  */
  */
-final class CurrentNotificationUserExtension extends AbstractExtension
+final class CurrentUserNotificationUserExtension extends AbstractExtension
 {
 {
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === NotificationUser::class;
+    }
+
     /**
     /**
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
      */
      */
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
     {
     {
-        if (NotificationUser::class !== $resourceClass) {
-            return;
-        }
-
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];

+ 6 - 7
src/Doctrine/Education/CurrentCycleExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Education;
 namespace App\Doctrine\Education;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Education\Cycle;
 use App\Entity\Education\Cycle;
@@ -18,13 +19,11 @@ final class CurrentCycleExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === Cycle::class;
+    }
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
     {
     {
-        if (Cycle::class !== $resourceClass) {
-            return;
-        }
-
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -33,4 +32,4 @@ final class CurrentCycleExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Education/CurrentEducationNotationConfigExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Education;
 namespace App\Doctrine\Education;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Education\EducationNotationConfig;
 use App\Entity\Education\EducationNotationConfig;
@@ -18,12 +19,12 @@ final class CurrentEducationNotationConfigExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (EducationNotationConfig::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === EducationNotationConfig::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentEducationNotationConfigExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Education/CurrentEducationTimingExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Education;
 namespace App\Doctrine\Education;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Education\EducationTiming;
 use App\Entity\Education\EducationTiming;
@@ -18,12 +19,12 @@ final class CurrentEducationTimingExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (EducationTiming::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === EducationTiming::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentEducationTimingExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Network/CurrentNetworkOrganizationExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Network;
 namespace App\Doctrine\Network;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Network\NetworkOrganization;
 use App\Entity\Network\NetworkOrganization;
@@ -18,12 +19,12 @@ final class CurrentNetworkOrganizationExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (NetworkOrganization::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === NetworkOrganization::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentNetworkOrganizationExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Organization/CurrentOrganizationAddressPostalExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Organization;
 namespace App\Doctrine\Organization;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Organization\OrganizationAddressPostal;
 use App\Entity\Organization\OrganizationAddressPostal;
@@ -18,12 +19,12 @@ final class CurrentOrganizationAddressPostalExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (OrganizationAddressPostal::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === OrganizationAddressPostal::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentOrganizationAddressPostalExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 7 - 6
src/Doctrine/Organization/CurrentOrganizationArticleExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Organization;
 namespace App\Doctrine\Organization;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Organization\OrganizationArticle;
 use App\Entity\Organization\OrganizationArticle;
@@ -18,12 +19,12 @@ final class CurrentOrganizationArticleExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (OrganizationArticle::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === OrganizationArticle::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];
@@ -32,4 +33,4 @@ final class CurrentOrganizationArticleExtension extends AbstractExtension
             ->setParameter('organization', $currentUser->getOrganization())
             ->setParameter('organization', $currentUser->getOrganization())
         ;
         ;
     }
     }
-}
+}

+ 6 - 5
src/Doctrine/Organization/CurrentOrganizationExtension.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Doctrine\Organization;
 namespace App\Doctrine\Organization;
 
 
+use ApiPlatform\Metadata\Operation;
 use App\Doctrine\AbstractExtension;
 use App\Doctrine\AbstractExtension;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Organization;
@@ -18,12 +19,12 @@ final class CurrentOrganizationExtension extends AbstractExtension
     public function __construct(private Security $security)
     public function __construct(private Security $security)
     { }
     { }
 
 
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        if (Organization::class !== $resourceClass) {
-            return;
-        }
+    public function supports(string $resourceClass, ?Operation $operation): bool {
+        return $resourceClass === Organization::class;
+    }
 
 
+    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass, ?Operation $operation): void
+    {
         /** @var Access $currentUser */
         /** @var Access $currentUser */
         $currentUser = $this->security->getUser();
         $currentUser = $this->security->getUser();
         $rootAlias = $queryBuilder->getRootAliases()[0];
         $rootAlias = $queryBuilder->getRootAliases()[0];

+ 32 - 7
src/Entity/Access/Access.php

@@ -65,14 +65,13 @@ use Symfony\Component\Serializer\Annotation\Groups;
 
 
 /**
 /**
  * Fais le lien entre une Person et une Organization
  * Fais le lien entre une Person et une Organization
- * @see : config/api_platform/Access/access.yaml
+ *
+ * Security :
+ *
+ *     @see ~/config/api_platform/Access/access.yaml
+ *     @see App\Doctrine\Access\CurrentAccessExtension
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(security: 'object.getId() == user.getId()'),
-        new Put(security: 'object.getId() == user.getId()'),
-    ]
-)]
+#[ApiResource]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: AccessRepository::class)]
 #[ORM\Entity(repositoryClass: AccessRepository::class)]
 #[ApiFilter(filterClass: BooleanFilter::class, properties: ['person.isPhysical'])]
 #[ApiFilter(filterClass: BooleanFilter::class, properties: ['person.isPhysical'])]
@@ -196,6 +195,12 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: "SET NULL")]
     #[ORM\JoinColumn(referencedColumnName: 'id', nullable: false, onDelete: "SET NULL")]
     private AccessFamily $accessFamily;
     private AccessFamily $accessFamily;
 
 
+    #[ORM\Column]
+    private bool $newAccess = false;
+
+    #[ORM\Column]
+    private bool $ielEnabled = false;
+
     #[ORM\OneToMany(mappedBy: 'educationalProjectPayer', targetEntity: EducationalProjectPayer::class, cascade: ['persist'], orphanRemoval: true)]
     #[ORM\OneToMany(mappedBy: 'educationalProjectPayer', targetEntity: EducationalProjectPayer::class, cascade: ['persist'], orphanRemoval: true)]
     private Collection $billingEducationalProjectPayers;
     private Collection $billingEducationalProjectPayers;
 
 
@@ -1037,6 +1042,26 @@ class Access implements UserInterface, PasswordAuthenticatedUserInterface
         return $this;
         return $this;
     }
     }
 
 
+    public function isNewAccess(): bool
+    {
+        return $this->newAccess;
+    }
+
+    public function setNewAccess(bool $newAccess): void
+    {
+        $this->newAccess = $newAccess;
+    }
+
+    public function isIelEnabled(): bool
+    {
+        return $this->ielEnabled;
+    }
+
+    public function setIelEnabled(bool $ielEnabled): void
+    {
+        $this->ielEnabled = $ielEnabled;
+    }
+
     /**
     /**
      * @return Collection<int, EducationalProjectPayer>
      * @return Collection<int, EducationalProjectPayer>
      */
      */

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

@@ -14,13 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\')'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class AccessFamily
 class AccessFamily
@@ -102,4 +96,4 @@ class AccessFamily
         }
         }
         return $this;
         return $this;
     }
     }
-}
+}

+ 1 - 1
src/Entity/Access/OrganizationFunction.php

@@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints as Assert;
 /**
 /**
  * Fonction d'un Access dans une Organization sur une période donnée
  * Fonction d'un Access dans une Organization sur une période donnée
  */
  */
-#[ApiResource]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: OrganizationFunctionRepository::class)]
 #[ORM\Entity(repositoryClass: OrganizationFunctionRepository::class)]
 #[DateTimeConstraintAware(startDateFieldName: "startDate", endDateFieldName: "endDate")]
 #[DateTimeConstraintAware(startDateFieldName: "startDate", endDateFieldName: "endDate")]

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

@@ -14,6 +14,11 @@ use Symfony\Component\Serializer\Annotation\Groups;
 
 
 /**
 /**
  * Liste personnalisées
  * Liste personnalisées
+ *
+ * Security :
+ *
+ *     @see \App\Doctrine\Access\CurrentUserPersonalizedListExtension
+ *
  */
  */
 #[ApiResource(
 #[ApiResource(
     operations: [
     operations: [
@@ -25,7 +30,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
         )
         )
     ],
     ],
     paginationEnabled: false
     paginationEnabled: false
-)]
+)] // @see App\Doctrine\Access\CurrentUserPersonalizedListExtension
 #[ORM\Entity(repositoryClass: PersonalizedListRepository::class)]
 #[ORM\Entity(repositoryClass: PersonalizedListRepository::class)]
 class PersonalizedList
 class PersonalizedList
 {
 {

+ 44 - 2
src/Entity/AccessWish/AccessFamilyWish.php

@@ -9,7 +9,7 @@ use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\Common\Collections\Collection;
 
 
 /**
 /**
- * Classe ... qui ...
+ * Famille à laquelle est rattaché un AccessWish
  */
  */
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
@@ -23,6 +23,19 @@ class AccessFamilyWish
     #[ORM\OneToMany(mappedBy: 'accessFamilyWish', targetEntity: AccessWish::class, cascade: ['remove'])]
     #[ORM\OneToMany(mappedBy: 'accessFamilyWish', targetEntity: AccessWish::class, cascade: ['remove'])]
     private Collection $accessWishes;
     private Collection $accessWishes;
 
 
+    /**
+     * Date de dernière mise à jour de l'entité
+     * @var \DateTimeInterface
+     */
+    #[ORM\Column(type: 'datetime', nullable: true)]
+    private \DateTimeInterface $updateDate;
+
+    #[ORM\Column]
+    private bool $registrationCompleted = false;
+
+    #[ORM\Column]
+    private bool $closeRegistration = false;
+
     public function __construct()
     public function __construct()
     {
     {
         $this->accessWishes = new ArrayCollection();
         $this->accessWishes = new ArrayCollection();
@@ -63,4 +76,33 @@ class AccessFamilyWish
         return $this;
         return $this;
     }
     }
 
 
-}
+    public function getUpdateDate(): \DateTimeInterface
+    {
+        return $this->updateDate;
+    }
+
+    public function setUpdateDate(\DateTimeInterface $updateDate): void
+    {
+        $this->updateDate = $updateDate;
+    }
+
+    public function isRegistrationCompleted(): bool
+    {
+        return $this->registrationCompleted;
+    }
+
+    public function setRegistrationCompleted(bool $registrationCompleted): void
+    {
+        $this->registrationCompleted = $registrationCompleted;
+    }
+
+    public function isCloseRegistration(): bool
+    {
+        return $this->closeRegistration;
+    }
+
+    public function setCloseRegistration(bool $closeRegistration): void
+    {
+        $this->closeRegistration = $closeRegistration;
+    }
+}

+ 55 - 2
src/Entity/AccessWish/AccessWish.php

@@ -3,20 +3,25 @@ declare(strict_types=1);
 
 
 namespace App\Entity\AccessWish;
 namespace App\Entity\AccessWish;
 
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Core\Country;
 use App\Entity\Core\Country;
 use App\Entity\Core\File;
 use App\Entity\Core\File;
 use App\Entity\Core\Tagg;
 use App\Entity\Core\Tagg;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\Organization;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Enum\OnlineRegistration\ValidationStateEnum;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\Common\Collections\Collection;
+use \DateTime;
+use Symfony\Component\Validator\Constraints as Assert;
 
 
 /**
 /**
- * Classe ... qui ...
+ * Demande d'inscription d'un Access via l'IEL
  */
  */
 //#[Auditable]
 //#[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 #[ORM\Entity]
 class AccessWish
 class AccessWish
 {
 {
@@ -58,6 +63,24 @@ class AccessWish
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
     #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id')]
     private Collection $tags;
     private Collection $tags;
 
 
+    #[ORM\Column(length: 50)]
+    #[Assert\Choice(callback: [ValidationStateEnum::class, 'toArray'])]
+    private string $validationState;
+
+    /**
+     * Date de création dde l'entité
+     * @var DateTime
+     */
+    #[ORM\Column(type: 'datetime', nullable: true)]
+    private \DateTimeInterface $createDate;
+
+    /**
+     * Date de dernière mise à jour de l'entité
+     * @var DateTime
+     */
+    #[ORM\Column(type: 'datetime', nullable: true)]
+    private \DateTimeInterface $updateDate;
+
     public function __construct()
     public function __construct()
     {
     {
         $this->educationStudentWishes = new ArrayCollection();
         $this->educationStudentWishes = new ArrayCollection();
@@ -244,4 +267,34 @@ class AccessWish
 
 
         return $this;
         return $this;
     }
     }
-}
+
+    public function getCreateDate(): DateTime
+    {
+        return $this->createDate;
+    }
+
+    public function setCreateDate(DateTime $createDate): void
+    {
+        $this->createDate = $createDate;
+    }
+
+    public function getUpdateDate(): DateTime
+    {
+        return $this->updateDate;
+    }
+
+    public function setUpdateDate(DateTime $updateDate): void
+    {
+        $this->updateDate = $updateDate;
+    }
+
+    public function getValidationState(): string
+    {
+        return $this->validationState;
+    }
+
+    public function setValidationState(string $validationState): void
+    {
+        $this->validationState = $validationState;
+    }
+}

+ 40 - 1
src/Entity/AccessWish/EducationStudentWish.php

@@ -8,7 +8,10 @@ use App\Entity\Education\EducationCurriculum;
 use App\Entity\Education\EducationStudent;
 use App\Entity\Education\EducationStudent;
 use App\Entity\Education\EducationTiming;
 use App\Entity\Education\EducationTiming;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
+use App\Enum\OnlineRegistration\RegistrationStatusEnum;
+use App\Enum\OnlineRegistration\WishRegistrationEnum;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
 
 
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
@@ -22,6 +25,22 @@ class EducationStudentWish
     #[ORM\GeneratedValue]
     #[ORM\GeneratedValue]
     private ?int $id = null;
     private ?int $id = null;
 
 
+    /**
+     * TODO: Documenter
+     * @var string|null
+     */
+    #[ORM\Column(length: 50)]
+    #[Assert\Choice(callback: [WishRegistrationEnum::class, 'toArray'])]
+    private ?string $wishRegistration = null;
+
+    /**
+     * Statut de l'enregistrement en ligne
+     * @var string|null
+     */
+    #[ORM\Column(length: 50)]
+    #[Assert\Choice(callback: [RegistrationStatusEnum::class, 'toArray'])]
+    private ?string $registrationStatus = null;
+
     #[ORM\ManyToOne]
     #[ORM\ManyToOne]
     #[ORM\JoinColumn(referencedColumnName: 'id' ,nullable: true, onDelete: 'SET NULL')]
     #[ORM\JoinColumn(referencedColumnName: 'id' ,nullable: true, onDelete: 'SET NULL')]
     private Education $educationWish;
     private Education $educationWish;
@@ -49,6 +68,26 @@ class EducationStudentWish
         return $this->id;
         return $this->id;
     }
     }
 
 
+    public function getWishRegistration(): ?string
+    {
+        return $this->wishRegistration;
+    }
+
+    public function setWishRegistration(?string $wishRegistration): void
+    {
+        $this->wishRegistration = $wishRegistration;
+    }
+
+    public function getRegistrationStatus(): ?string
+    {
+        return $this->registrationStatus;
+    }
+
+    public function setRegistrationStatus(?string $registrationStatus): void
+    {
+        $this->registrationStatus = $registrationStatus;
+    }
+
     public function getEducationWish(): ?Education
     public function getEducationWish(): ?Education
     {
     {
         return $this->educationWish;
         return $this->educationWish;
@@ -120,4 +159,4 @@ class EducationStudentWish
 
 
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Billing/AccessBilling.php

@@ -14,13 +14,7 @@ use Doctrine\Common\Collections\Collection;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getAccess().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class AccessBilling
 class AccessBilling
@@ -179,4 +173,4 @@ class AccessBilling
         $this->access = $access;
         $this->access = $access;
         return $this;
         return $this;
     }
     }
-}
+}

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

@@ -14,7 +14,7 @@ use Doctrine\Common\Collections\Collection;
 /**
 /**
  * Enregistrement d'un produit à facturer par un Access
  * Enregistrement d'un produit à facturer par un Access
  */
  */
-#[ApiResource]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: AccessIntangibleRepository::class)]
 #[ORM\Entity(repositoryClass: AccessIntangibleRepository::class)]
 class AccessIntangible extends AbstractBillingIntangible
 class AccessIntangible extends AbstractBillingIntangible

+ 1 - 7
src/Entity/Billing/AccessPayer.php

@@ -17,13 +17,7 @@ use Doctrine\ORM\Mapping as ORM;
  * Fais le lien entre l'Access qui règle la facture et l'Access concerné
  * Fais le lien entre l'Access qui règle la facture et l'Access concerné
  *
  *
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getAccessPayer().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Table(name: 'BillingPayer')]
 #[ORM\Table(name: 'BillingPayer')]
 #[ORM\Entity(repositoryClass: AccessPayerRepository::class)]
 #[ORM\Entity(repositoryClass: AccessPayerRepository::class)]

+ 2 - 8
src/Entity/Billing/Bill.php

@@ -13,13 +13,7 @@ use Doctrine\ORM\Mapping as ORM;
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Bill, et supprimer l'attribut discr.
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Bill, et supprimer l'attribut discr.
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'BillAccounting')]
 #[ORM\Table(name: 'BillAccounting')]
@@ -42,4 +36,4 @@ class Bill extends BillAccounting implements BillAccountingInterface
         $this->access = $access;
         $this->access = $access;
         return $this;
         return $this;
     }
     }
-}
+}

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

@@ -16,13 +16,7 @@ use Doctrine\Common\Collections\Collection;
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table BillAccounting, et supprimer l'attribut discr.
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table BillAccounting, et supprimer l'attribut discr.
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class BillAccounting
 class BillAccounting

+ 2 - 8
src/Entity/Billing/BillCredit.php

@@ -14,13 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
  *
  *
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'BillAccounting')]
 #[ORM\Table(name: 'BillAccounting')]
@@ -43,4 +37,4 @@ class BillCredit extends BillAccounting implements BillAccountingInterface
         $this->access = $access;
         $this->access = $access;
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Billing/BillLine.php

@@ -14,13 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getAccess().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class BillLine
 class BillLine
@@ -91,4 +85,4 @@ class BillLine
         $this->equipmentLoan = $equipmentLoan;
         $this->equipmentLoan = $equipmentLoan;
         return $this;
         return $this;
     }
     }
-}
+}

+ 1 - 7
src/Entity/Billing/BillingIntangibleExcludeDate.php

@@ -12,13 +12,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\')'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class BillingIntangibleExcludeDate
 class BillingIntangibleExcludeDate

+ 1 - 5
src/Entity/Billing/BillingSetting.php

@@ -13,11 +13,7 @@ use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\ORM\Mapping as ORM;
 use JetBrains\PhpStorm\Pure;
 use JetBrains\PhpStorm\Pure;
 
 
-#[ApiResource(
-    operations: [
-        new Get()
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: BillingSettingRepository::class)]
 #[ORM\Entity(repositoryClass: BillingSettingRepository::class)]
 class BillingSetting
 class BillingSetting

+ 2 - 8
src/Entity/Billing/EducationalProjectPayer.php

@@ -15,13 +15,7 @@ use Doctrine\ORM\Mapping as ORM;
  *
  *
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getEducationalProjectPayer().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Table(name: 'BillingPayer')]
 #[ORM\Table(name: 'BillingPayer')]
 #[ORM\Entity]
 #[ORM\Entity]
@@ -67,4 +61,4 @@ class EducationalProjectPayer
         $this->educationalProjectReceiver = $educationalProjectReceiver;
         $this->educationalProjectReceiver = $educationalProjectReceiver;
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Billing/FamilyQuotient.php

@@ -14,13 +14,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class FamilyQuotient
 class FamilyQuotient
@@ -117,4 +111,4 @@ class FamilyQuotient
         }
         }
         return $this;
         return $this;
     }
     }
-}
+}

+ 5 - 18
src/Entity/Billing/ResidenceArea.php

@@ -19,25 +19,12 @@ use Doctrine\Common\Collections\Collection;
 
 
 /**
 /**
  * Zone de résidence d'un Access, telle que définie par l'Organization
  * Zone de résidence d'un Access, telle que définie par l'Organization
+ *
+ * Security :
+ *
+ *     @see \App\Doctrine\Billing\CurrentResidenceAreaExtension
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ORGANIZATION_VIEW\') and object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()'
-        ),
-        new Put(
-            security: 'object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()'
-        ),
-        new Delete(
-            security: 'object.getBillingSetting().getOrganization().getId() == user.getOrganization().getId()'
-        ),
-        new GetCollection(
-            security: 'is_granted(\'ROLE_ORGANIZATION_VIEW\')'
-        ),
-        new Post()
-    ],
-    security: 'is_granted(\'ROLE_ORGANIZATION\')'
-)]
+#[ApiResource(operations: [])] // @see App\Doctrine\Billing\CurrentResidenceAreaExtension
 //#[Auditable]
 //#[Auditable]
 #[BillingSettingDefaultValue(fieldName: "billingSetting")]
 #[BillingSettingDefaultValue(fieldName: "billingSetting")]
 #[ORM\Entity(repositoryClass: ResidenceAreaRepository::class)]
 #[ORM\Entity(repositoryClass: ResidenceAreaRepository::class)]

+ 2 - 8
src/Entity/Booking/Attendance.php

@@ -15,13 +15,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class Attendance
 class Attendance
@@ -114,4 +108,4 @@ class Attendance
         }
         }
         return $this;
         return $this;
     }
     }
-}
+}

+ 1 - 7
src/Entity/Booking/AttendanceBooking.php

@@ -12,13 +12,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\')'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class AttendanceBooking
 class AttendanceBooking

+ 5 - 9
src/Entity/Booking/Course.php

@@ -25,15 +25,11 @@ use Doctrine\Common\Collections\Collection;
  * @todo : migration table tag_booking
  * @todo : migration table tag_booking
  *
  *
  * Classe Course qui permet de gérer les cours de la structure.
  * Classe Course qui permet de gérer les cours de la structure.
+ *
+ * Security :
+ *   * @see App\Doctrine\Booking\CurrentCoursesExtension
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_COURSE_VIEW\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        ),
-        new GetCollection()
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: CourseRepository::class)]
 #[ORM\Entity(repositoryClass: CourseRepository::class)]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]
@@ -401,4 +397,4 @@ class Course extends AbstractBooking
         $this->tags->removeElement($tag);
         $this->tags->removeElement($tag);
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Booking/EducationalProject.php

@@ -24,13 +24,7 @@ use Doctrine\ORM\Mapping as ORM;
  * @todo : migration table tag_booking
  * @todo : migration table tag_booking
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Entity]
 #[ORM\Entity]
@@ -461,4 +455,4 @@ class EducationalProject extends AbstractBooking
         $this->tags->removeElement($tag);
         $this->tags->removeElement($tag);
         return $this;
         return $this;
     }
     }
-}
+}

+ 1 - 7
src/Entity/Booking/Event.php

@@ -23,13 +23,7 @@ use Symfony\Component\Validator\Constraints as Assert;
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Event, et supprimer l'attribut discr.
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Event, et supprimer l'attribut discr.
  * @todo : migration table tag_booking
  * @todo : migration table tag_booking
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]

+ 2 - 8
src/Entity/Booking/EventUser.php

@@ -12,13 +12,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getAccess().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class EventUser
 class EventUser
@@ -60,4 +54,4 @@ class EventUser
         $this->guest = $guest;
         $this->guest = $guest;
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Booking/Examen.php

@@ -22,13 +22,7 @@ use Doctrine\ORM\Mapping as ORM;
  * @todo : migration table tag_booking
  * @todo : migration table tag_booking
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]
@@ -324,4 +318,4 @@ class Examen extends AbstractBooking
         $this->tags->removeElement($tag);
         $this->tags->removeElement($tag);
         return $this;
         return $this;
     }
     }
-}
+}

+ 3 - 1
src/Entity/Booking/ExamenConvocation.php

@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 
 namespace App\Entity\Booking;
 namespace App\Entity\Booking;
 
 
+use ApiPlatform\Metadata\ApiResource;
 use App\Entity\Access\Access;
 use App\Entity\Access\Access;
 use App\Entity\Product\Equipment;
 use App\Entity\Product\Equipment;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
 //use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
@@ -14,6 +15,7 @@ use Doctrine\ORM\Mapping as ORM;
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
 //#[Auditable]
 //#[Auditable]
+#[ApiResource(operations: [])]
 #[ORM\Entity]
 #[ORM\Entity]
 class ExamenConvocation
 class ExamenConvocation
 {
 {
@@ -91,4 +93,4 @@ class ExamenConvocation
 
 
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Booking/OrganizationHoliday.php

@@ -16,13 +16,7 @@ use Doctrine\ORM\Mapping as ORM;
  *
  *
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]
@@ -92,4 +86,4 @@ class OrganizationHoliday extends AbstractBooking
         $this->organization = $organization;
         $this->organization = $organization;
         return $this;
         return $this;
     }
     }
-}
+}

+ 2 - 8
src/Entity/Booking/PersonHoliday.php

@@ -16,13 +16,7 @@ use Doctrine\ORM\Mapping as ORM;
  *
  *
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getAccess().getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'Booking')]
 #[ORM\Table(name: 'Booking')]
@@ -91,4 +85,4 @@ class PersonHoliday extends AbstractBooking
         $this->access = $access;
         $this->access = $access;
         return $this;
         return $this;
     }
     }
-}
+}

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

@@ -26,7 +26,7 @@ use Symfony\Component\Serializer\Annotation\Context;
  *
  *
  * Classe Notification. qui permet de gérer les notifications aux utilisateurs.
  * Classe Notification. qui permet de gérer les notifications aux utilisateurs.
  */
  */
-#[ApiResource]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 #[ORM\Table(name: 'Information')]
 #[ORM\Table(name: 'Information')]

+ 7 - 8
src/Entity/Core/AddressPostal.php

@@ -17,14 +17,13 @@ use Doctrine\ORM\Mapping as ORM;
 use App\Entity\Person\PersonAddressPostal;
 use App\Entity\Person\PersonAddressPostal;
 use Symfony\Component\Serializer\Annotation\Groups;
 use Symfony\Component\Serializer\Annotation\Groups;
 
 
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ORGANIZATION_VIEW\') and object.getOrganizationAddressPostal().getOrganization().getId() == user.getOrganization().getId()'
-        ),
-        new GetCollection()
-    ]
-)]
+/**
+ * Adresse postale d'une organisation ou d'une personne
+ *
+ * Security :
+ *   * @see App\Doctrine\Core\AllowedAddressPostalExtension
+ */
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: AddressPostalRepository::class)]
 #[ORM\Entity(repositoryClass: AddressPostalRepository::class)]
 class AddressPostal
 class AddressPostal

+ 4 - 15
src/Entity/Core/BankAccount.php

@@ -21,22 +21,11 @@ use Symfony\Component\Validator\Constraints as Assert;
 
 
 /**
 /**
  * Données bancaire d'une Person ou d'une Organization
  * Données bancaire d'une Person ou d'une Organization
+ *
+ * Security :
+ *   * @see App\Security\Voter\BankAccountVoter
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted("BANK_ACCOUNT_READ", object)'
-        ),
-        new Put(
-            security: 'is_granted("BANK_ACCOUNT_EDIT", object)'
-        ),
-        new Delete(
-            security: 'is_granted("BANK_ACCOUNT_DELETE", object)'
-        ),
-        new Post(),
-        new GetCollection()
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: BankAccountRepository::class)]
 #[ORM\Entity(repositoryClass: BankAccountRepository::class)]
 class BankAccount
 class BankAccount

+ 4 - 15
src/Entity/Core/ContactPoint.php

@@ -25,22 +25,11 @@ use App\Validator\Core as OpentalentAssert;
 
 
 /**
 /**
  * Données de contact d'une Person ou d'une Organization ou d'un lieu
  * Données de contact d'une Person ou d'une Organization ou d'un lieu
+ *
+ * Security :
+ *   * @see App\Security\Voter\ContactPointVoter
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted("CONTACT_POINT_READ", object)'
-        ),
-        new Put(
-            security: 'is_granted("CONTACT_POINT_EDIT", object)'
-        ),
-        new Delete(
-            security: 'is_granted("CONTACT_POINT_DELETE", object)'
-        ),
-        new Post(),
-        new GetCollection()
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity(repositoryClass: ContactPointRepository::class)]
 #[ORM\Entity(repositoryClass: ContactPointRepository::class)]
 #[OpentalentAssert\ContactPoint]
 #[OpentalentAssert\ContactPoint]

+ 46 - 6
src/Entity/Core/File.php

@@ -5,6 +5,8 @@ namespace App\Entity\Core;
 
 
 use ApiPlatform\Metadata\Put;
 use ApiPlatform\Metadata\Put;
 use ApiPlatform\Metadata\Get;
 use ApiPlatform\Metadata\Get;
+use ApiPlatform\Metadata\Post;
+use ApiPlatform\Metadata\Delete;
 use ApiPlatform\Metadata\ApiResource;
 use ApiPlatform\Metadata\ApiResource;
 use App\Entity\AccessWish\DocumentWish;
 use App\Entity\AccessWish\DocumentWish;
 use App\Entity\Booking\Event;
 use App\Entity\Booking\Event;
@@ -28,10 +30,18 @@ use Symfony\Component\Serializer\Annotation\Groups;
 use Symfony\Component\Validator\Constraints as Assert;
 use Symfony\Component\Validator\Constraints as Assert;
 use App\Enum\Core\FileStatusEnum;
 use App\Enum\Core\FileStatusEnum;
 
 
+/**
+ * Fichier, généré ou uploadé, appartenant à une organisation ou à une personne.
+ *
+ * Security :
+ *   * @see App\Security\Voter\FileVoter
+ */
 #[ApiResource(
 #[ApiResource(
     operations: [
     operations: [
-        new Get(),
-        new Put()
+        new Get(security: "is_granted('READ', object)"),
+        new Put(security: "is_granted('EDIT', object)"),
+        new Post(security: "is_granted('CREATE', object)"),
+        new Delete(security: "is_granted('DELETE', object)")
     ]
     ]
 )]
 )]
 //#[Auditable]
 //#[Auditable]
@@ -172,10 +182,14 @@ class File
 
 
     //    #[ORM\Column]
     //    #[ORM\Column]
     //    private ?int $eventReport_id;
     //    private ?int $eventReport_id;
-    //
-    //    #[ORM\Column]
-    //    private ?\DateTime $availabilityDate;
-    //
+
+    /**
+     * TODO: complete
+     * @var DateTime|null
+     */
+    #[ORM\Column]
+    private ?\DateTime $availabilityDate;
+
     //    #[ORM\Column]
     //    #[ORM\Column]
     //    private ?int $documentWish_id;
     //    private ?int $documentWish_id;
     //
     //
@@ -187,6 +201,7 @@ class File
     //
     //
     //    #[ORM\Column]
     //    #[ORM\Column]
     //    private ?int $work_id;
     //    private ?int $work_id;
+
     #[ORM\ManyToMany(targetEntity: Person::class, inversedBy: 'personFiles')]
     #[ORM\ManyToMany(targetEntity: Person::class, inversedBy: 'personFiles')]
     #[Groups(['file_person'])]
     #[Groups(['file_person'])]
     private Collection $accessPersons;
     private Collection $accessPersons;
@@ -367,6 +382,15 @@ class File
         return $this;
         return $this;
     }
     }
 
 
+    /**
+     * A priori inutilisé
+     * @deprecated
+     * @return Collection
+     */
+    public function getAccessRoles(): Collection {
+        return new ArrayCollection([]);
+    }
+
     /**
     /**
      * @return string
      * @return string
      */
      */
@@ -604,6 +628,22 @@ class File
         return $this;
         return $this;
     }
     }
 
 
+    /**
+     * @return DateTime|null
+     */
+    public function getAvailabilityDate(): ?DateTime
+    {
+        return $this->availabilityDate;
+    }
+
+    /**
+     * @param DateTime|null $availabilityDate
+     */
+    public function setAvailabilityDate(?DateTime $availabilityDate): void
+    {
+        $this->availabilityDate = $availabilityDate;
+    }
+
     /**
     /**
      * @return Collection<int, Person>
      * @return Collection<int, Person>
      */
      */

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

@@ -24,7 +24,10 @@ use Symfony\Component\Serializer\Annotation\Context;
 /**
 /**
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Notification, et supprimer l'attribut discr.
  * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Notification, et supprimer l'attribut discr.
  *
  *
- * Classe Notification. qui permet de gérer les notifications aux utilisateurs.
+ * Notification à un utilisateur
+ *
+ * Security :
+ *   * @see App\Doctrine\Core\CurrentUserNotificationExtension
  */
  */
 #[ApiResource(
 #[ApiResource(
     operations: [
     operations: [

+ 3 - 0
src/Entity/Core/NotificationUser.php

@@ -16,6 +16,9 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Les NotificationUser permettent de garder la trace des notifications et des tips
  * Les NotificationUser permettent de garder la trace des notifications et des tips
  * qui ont été lues par les utilisateurs
  * qui ont été lues par les utilisateurs
+ *
+ * Security :
+ *   * @see App\Doctrine\Core\CurrentUserNotificationUserExtension
  */
  */
 #[ApiResource(
 #[ApiResource(
     operations: [
     operations: [

+ 2 - 8
src/Entity/Core/Tagg.php

@@ -41,13 +41,7 @@ use Doctrine\ORM\Mapping as ORM;
 /**
 /**
  * Classe ... qui ...
  * Classe ... qui ...
  */
  */
-#[ApiResource(
-    operations: [
-        new Get(
-            security: 'is_granted(\'ROLE_ADMIN\') and object.getOrganization().getId() == user.getOrganization().getId()'
-        )
-    ]
-)]
+#[ApiResource(operations: [])]
 //#[Auditable]
 //#[Auditable]
 #[ORM\Entity]
 #[ORM\Entity]
 class Tagg
 class Tagg
@@ -863,4 +857,4 @@ class Tagg
         }
         }
         return $this;
         return $this;
     }
     }
-}
+}

Some files were not shown because too many files changed in this diff