mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-03 18:58:24 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			fix-templa
			...
			fix-timeli
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8364518282 | 
@@ -11,15 +11,14 @@ before_script:
 | 
			
		||||
  - PGPASSWORD=$POSTGRES_PASSWORD psql -U $POSTGRES_USER -h db -c "CREATE EXTENSION IF NOT EXISTS unaccent; CREATE EXTENSION IF NOT EXISTS pg_trgm;"
 | 
			
		||||
  # Install and run Composer
 | 
			
		||||
  - curl -sS https://getcomposer.org/installer | php
 | 
			
		||||
  - php -d memory_limit=2G composer.phar install
 | 
			
		||||
  - php composer.phar install
 | 
			
		||||
  - php tests/app/bin/console doctrine:migrations:migrate -n
 | 
			
		||||
  - php -d memory_limit=2G tests/app/bin/console doctrine:fixtures:load -n
 | 
			
		||||
  - echo "before_script finished"
 | 
			
		||||
  - php tests/app/bin/console doctrine:fixtures:load -n
 | 
			
		||||
 | 
			
		||||
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
 | 
			
		||||
# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
 | 
			
		||||
services:
 | 
			
		||||
  - name: postgis/postgis:12-3.1-alpine
 | 
			
		||||
  - name: postgres:12
 | 
			
		||||
    alias: db
 | 
			
		||||
  - name: redis
 | 
			
		||||
    alias: redis
 | 
			
		||||
@@ -39,4 +38,4 @@ variables:
 | 
			
		||||
# Run our tests
 | 
			
		||||
test:
 | 
			
		||||
  script:
 | 
			
		||||
    - php -d memory_limit=3G bin/phpunit --colors=never
 | 
			
		||||
    - bin/phpunit --colors=never
 | 
			
		||||
 
 | 
			
		||||
@@ -73,8 +73,7 @@
 | 
			
		||||
        "symfony/web-profiler-bundle": "^5.0",
 | 
			
		||||
        "symfony/var-dumper": "4.*",
 | 
			
		||||
        "symfony/debug-bundle": "^5.1",
 | 
			
		||||
        "symfony/phpunit-bridge": "^5.2",    
 | 
			
		||||
        "nelmio/alice": "^3.8"
 | 
			
		||||
        "symfony/phpunit-bridge": "^5.2"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "auto-scripts": {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,6 @@ API
 | 
			
		||||
 | 
			
		||||
Chill provides a basic framework to build REST api.
 | 
			
		||||
 | 
			
		||||
Basic configuration
 | 
			
		||||
*******************
 | 
			
		||||
 | 
			
		||||
Configure a route
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +34,7 @@ You can also:
 | 
			
		||||
    * `How to create your custom normalizer <https://symfony.com/doc/current/serializer/custom_normalizer.html>`_
 | 
			
		||||
 | 
			
		||||
Auto-loading the routes
 | 
			
		||||
=======================
 | 
			
		||||
***********************
 | 
			
		||||
 | 
			
		||||
Ensure that those lines are present in your file `app/config/routing.yml`:
 | 
			
		||||
 | 
			
		||||
@@ -50,7 +47,7 @@ Ensure that those lines are present in your file `app/config/routing.yml`:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Create your model
 | 
			
		||||
=================
 | 
			
		||||
*****************
 | 
			
		||||
 | 
			
		||||
Create your model on the usual way:
 | 
			
		||||
 | 
			
		||||
@@ -90,7 +87,7 @@ Create your model on the usual way:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Configure api
 | 
			
		||||
=============
 | 
			
		||||
*************
 | 
			
		||||
 | 
			
		||||
Configure the api using Yaml (see the full configuration: :ref:`api_full_configuration`):
 | 
			
		||||
 | 
			
		||||
@@ -174,7 +171,7 @@ Configure the api using Yaml (see the full configuration: :ref:`api_full_configu
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
The :code:`_index` and :code:`_entity` action
 | 
			
		||||
*********************************************
 | 
			
		||||
=============================================
 | 
			
		||||
 | 
			
		||||
The :code:`_index` and :code:`_entity` action are default actions:
 | 
			
		||||
 | 
			
		||||
@@ -192,7 +189,7 @@ Entity:
 | 
			
		||||
   Path: :code:`/api/1.0/person/accompanying-period/origin/{id}.{_format}`
 | 
			
		||||
 | 
			
		||||
Role
 | 
			
		||||
****
 | 
			
		||||
====
 | 
			
		||||
 | 
			
		||||
By default, the key `base_role` is used to check ACL. Take care of creating the :code:`Voter` required to take that into account.
 | 
			
		||||
 | 
			
		||||
@@ -219,7 +216,7 @@ You can also define a role for each method. In this case, this role is used for
 | 
			
		||||
                           HEAD: MY ROLE_SEE
 | 
			
		||||
 | 
			
		||||
Customize the controller
 | 
			
		||||
************************
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
You can customize the controller by hooking into the default actions. Take care of extending :code:`Chill\MainBundle\CRUD\Controller\ApiController`.
 | 
			
		||||
 | 
			
		||||
@@ -267,7 +264,7 @@ And set your controller in configuration:
 | 
			
		||||
                           HEAD: true
 | 
			
		||||
 | 
			
		||||
Create your own actions
 | 
			
		||||
***********************
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
You can add your own actions:
 | 
			
		||||
 | 
			
		||||
@@ -364,297 +361,8 @@ Then, create the corresponding action into your controller:
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
Managing association
 | 
			
		||||
********************
 | 
			
		||||
 | 
			
		||||
ManyToOne association
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
In ManyToOne association, you can add associated entities using the :code:`PATCH` request. By default, the serializer deserialize entities only with their id and discriminator type, if any.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. code-block:: bash
 | 
			
		||||
 | 
			
		||||
   curl -X 'PATCH' \
 | 
			
		||||
     'http://localhost:8001/api/1.0/person/accompanying-course/2668.json' \
 | 
			
		||||
     -H 'accept: */*' \
 | 
			
		||||
     -H 'Content-Type: application/json' \
 | 
			
		||||
      # see the data sent to the server: \
 | 
			
		||||
     -d '{
 | 
			
		||||
     "type": "accompanying_period",
 | 
			
		||||
     "id": 2668,
 | 
			
		||||
     "origin": { "id": 11 }
 | 
			
		||||
   }'
 | 
			
		||||
 | 
			
		||||
ManyToMany associations
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
In OneToMany association, you can easily create route for adding and removing entities, using :code:`POST` and :code:`DELETE` requests.
 | 
			
		||||
 | 
			
		||||
Prepare your entity, creating the methods :code:`addYourEntity` and :code:`removeYourEntity`:
 | 
			
		||||
 | 
			
		||||
.. code-block:: php
 | 
			
		||||
 | 
			
		||||
   namespace Chill\PersonBundle\Entity;
 | 
			
		||||
 | 
			
		||||
   use Chill\MainBundle\Entity\Scope;
 | 
			
		||||
   use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
   use Doctrine\Common\Collections\Collection;
 | 
			
		||||
   use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
   use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
   use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * AccompanyingPeriod Class
 | 
			
		||||
    *
 | 
			
		||||
    * @ORM\Entity
 | 
			
		||||
    * @ORM\Table(name="chill_person_accompanying_period")
 | 
			
		||||
    * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
    *  "accompanying_period"=AccompanyingPeriod::class
 | 
			
		||||
    *  })
 | 
			
		||||
    */
 | 
			
		||||
   class AccompanyingPeriod
 | 
			
		||||
   {
 | 
			
		||||
       /**
 | 
			
		||||
        * @var Collection
 | 
			
		||||
        * @ORM\ManyToMany(
 | 
			
		||||
        *     targetEntity=Scope::class,
 | 
			
		||||
        *     cascade={}
 | 
			
		||||
        *     )
 | 
			
		||||
        * @Groups({"read"})
 | 
			
		||||
        */
 | 
			
		||||
       private $scopes;
 | 
			
		||||
 | 
			
		||||
       public function addScope(Scope $scope): self
 | 
			
		||||
       {
 | 
			
		||||
           $this->scopes[] = $scope;
 | 
			
		||||
 | 
			
		||||
           return $this;
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       public function removeScope(Scope $scope): void
 | 
			
		||||
       {
 | 
			
		||||
           $this->scopes->removeElement($scope);
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Create your route into the configuration:
 | 
			
		||||
 | 
			
		||||
.. code-block:: yaml
 | 
			
		||||
 | 
			
		||||
   chill_main:
 | 
			
		||||
       apis:
 | 
			
		||||
           -
 | 
			
		||||
               class: Chill\PersonBundle\Entity\AccompanyingPeriod
 | 
			
		||||
               name: accompanying_course
 | 
			
		||||
               base_path: /api/1.0/person/accompanying-course
 | 
			
		||||
               controller: Chill\PersonBundle\Controller\AccompanyingCourseApiController
 | 
			
		||||
               actions:
 | 
			
		||||
                   scope:
 | 
			
		||||
                       methods:
 | 
			
		||||
                           POST: true
 | 
			
		||||
                           DELETE: true
 | 
			
		||||
                           GET: false
 | 
			
		||||
                           HEAD: false
 | 
			
		||||
                           PUT: false
 | 
			
		||||
                           PATCH: false
 | 
			
		||||
                       roles:
 | 
			
		||||
                           POST: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
 | 
			
		||||
                           DELETE: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
 | 
			
		||||
                           GET: null
 | 
			
		||||
                           HEAD: null
 | 
			
		||||
                           PUT: null
 | 
			
		||||
                           PATCH: null
 | 
			
		||||
                       controller_action: null
 | 
			
		||||
                       path: null
 | 
			
		||||
                       single-collection: single
 | 
			
		||||
 | 
			
		||||
This will create a new route, which will accept two methods: DELETE and POST:
 | 
			
		||||
 | 
			
		||||
.. code-block:: raw
 | 
			
		||||
 | 
			
		||||
   +--------------+---------------------------------------------------------------------------------------+
 | 
			
		||||
   | Property     | Value                                                                                 |
 | 
			
		||||
   +--------------+---------------------------------------------------------------------------------------+
 | 
			
		||||
   | Route Name   | chill_api_single_accompanying_course_scope                                            |
 | 
			
		||||
   | Path         | /api/1.0/person/accompanying-course/{id}/scope.{_format}                              |
 | 
			
		||||
   | Path Regex   | {^/api/1\.0/person/accompanying\-course/(?P<id>[^/]++)/scope\.(?P<_format>[^/]++)$}sD |
 | 
			
		||||
   | Host         | ANY                                                                                   |
 | 
			
		||||
   | Host Regex   |                                                                                       |
 | 
			
		||||
   | Scheme       | ANY                                                                                   |
 | 
			
		||||
   | Method       | POST|DELETE                                                                           |
 | 
			
		||||
   | Requirements | {id}: \d+                                                                             |
 | 
			
		||||
   | Class        | Symfony\Component\Routing\Route                                                       |
 | 
			
		||||
   | Defaults     | _controller: csapi_accompanying_course_controller:scopeApi                            |
 | 
			
		||||
   | Options      | compiler_class: Symfony\Component\Routing\RouteCompiler                               |
 | 
			
		||||
   +--------------+---------------------------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Then, create the controller action. Call the method:
 | 
			
		||||
 | 
			
		||||
.. code-block:: php
 | 
			
		||||
 | 
			
		||||
   namespace Chill\PersonBundle\Controller;
 | 
			
		||||
 | 
			
		||||
   use Chill\MainBundle\CRUD\Controller\ApiController;
 | 
			
		||||
   use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
   use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
   use Chill\MainBundle\Entity\Scope;
 | 
			
		||||
 | 
			
		||||
   class MyController extends ApiController
 | 
			
		||||
   {
 | 
			
		||||
       public function scopeApi($id, Request $request, string $_format): Response
 | 
			
		||||
       {
 | 
			
		||||
           return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, [ 'groups' => [ 'read' ] ]);
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
This will allow to add a scope by his id, and delete them.
 | 
			
		||||
 | 
			
		||||
Curl requests:
 | 
			
		||||
 | 
			
		||||
.. code-block:: bash
 | 
			
		||||
 | 
			
		||||
   # add a scope with id 5
 | 
			
		||||
   curl -X 'POST' \
 | 
			
		||||
     'http://localhost:8001/api/1.0/person/accompanying-course/2868/scope.json' \
 | 
			
		||||
     -H 'accept: */*' \
 | 
			
		||||
     -H 'Content-Type: application/json' \
 | 
			
		||||
     -d '{
 | 
			
		||||
     "type": "scope",
 | 
			
		||||
     "id": 5
 | 
			
		||||
   }'
 | 
			
		||||
 | 
			
		||||
   # remove a scope with id 5
 | 
			
		||||
   curl -X 'DELETE' \
 | 
			
		||||
     'http://localhost:8001/api/1.0/person/accompanying-course/2868/scope.json' \
 | 
			
		||||
     -H 'accept: */*' \
 | 
			
		||||
     -H 'Content-Type: application/json' \
 | 
			
		||||
     -d '{
 | 
			
		||||
     "id": 5,
 | 
			
		||||
     "type": "scope"
 | 
			
		||||
   }'
 | 
			
		||||
 | 
			
		||||
Deserializing an association where multiple types are allowed
 | 
			
		||||
=============================================================
 | 
			
		||||
 | 
			
		||||
Sometimes, multiples types are allowed as association to one entity:
 | 
			
		||||
 | 
			
		||||
.. code-block:: php
 | 
			
		||||
 | 
			
		||||
   namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
   use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
   use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
   use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
   class Resource
 | 
			
		||||
   {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
       /**
 | 
			
		||||
        * @ORM\ManyToOne(targetEntity=ThirdParty::class)
 | 
			
		||||
        * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
        */
 | 
			
		||||
       private $thirdParty;
 | 
			
		||||
 | 
			
		||||
       /**
 | 
			
		||||
        * @ORM\ManyToOne(targetEntity=Person::class)
 | 
			
		||||
        * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
        */
 | 
			
		||||
       private $person;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
       /**
 | 
			
		||||
        *
 | 
			
		||||
        * @param $resource Person|ThirdParty
 | 
			
		||||
        */
 | 
			
		||||
       public function setResource($resource): self
 | 
			
		||||
       {
 | 
			
		||||
          // ...
 | 
			
		||||
       }
 | 
			
		||||
       
 | 
			
		||||
       
 | 
			
		||||
       /**
 | 
			
		||||
        * @return ThirdParty|Person
 | 
			
		||||
        * @Groups({"read", "write"})
 | 
			
		||||
        */
 | 
			
		||||
       public function getResource()
 | 
			
		||||
       {
 | 
			
		||||
           return $this->person ?? $this->thirdParty;
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
This is not well taken into account by the Symfony serializer natively.
 | 
			
		||||
 | 
			
		||||
You must, then, create your own CustomNormalizer. You can help yourself using this:
 | 
			
		||||
 | 
			
		||||
.. code-block:: php
 | 
			
		||||
 | 
			
		||||
   namespace Chill\PersonBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
   use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
   use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
   use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
 | 
			
		||||
   use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
 | 
			
		||||
   use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 | 
			
		||||
   use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
 | 
			
		||||
   use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
 | 
			
		||||
   use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait;
 | 
			
		||||
   use Symfony\Component\Serializer\Exception;
 | 
			
		||||
   use Chill\MainBundle\Serializer\Normalizer\DiscriminatedObjectDenormalizer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   class AccompanyingPeriodResourceNormalizer implements DenormalizerInterface, DenormalizerAwareInterface
 | 
			
		||||
   {
 | 
			
		||||
       use DenormalizerAwareTrait;
 | 
			
		||||
       use ObjectToPopulateTrait;
 | 
			
		||||
 | 
			
		||||
       public function __construct(ResourceRepository $repository)
 | 
			
		||||
       {
 | 
			
		||||
           $this->repository = $repository;
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       public function denormalize($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
       {
 | 
			
		||||
           // .. snipped for brevity
 | 
			
		||||
 | 
			
		||||
           if ($resource === NULL) {
 | 
			
		||||
               $resource = new Resource();
 | 
			
		||||
           }
 | 
			
		||||
 | 
			
		||||
           if (\array_key_exists('resource', $data)) {
 | 
			
		||||
               $res = $this->denormalizer->denormalize(
 | 
			
		||||
                   $data['resource'],
 | 
			
		||||
                   // call for a "multiple type"
 | 
			
		||||
                   DiscriminatedObjectDenormalizer::TYPE,
 | 
			
		||||
                   $format,
 | 
			
		||||
                   // into the context, we add the list of allowed types:
 | 
			
		||||
                   [ 
 | 
			
		||||
                       DiscriminatedObjectDenormalizer::ALLOWED_TYPES => 
 | 
			
		||||
                       [ 
 | 
			
		||||
                           Person::class, ThirdParty::class
 | 
			
		||||
                       ]
 | 
			
		||||
                   ]
 | 
			
		||||
               );
 | 
			
		||||
 | 
			
		||||
               $resource->setResource($res);
 | 
			
		||||
           } 
 | 
			
		||||
 | 
			
		||||
           return $resource;
 | 
			
		||||
       }
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
       public function supportsDenormalization($data, string $type, string $format = null)
 | 
			
		||||
       {
 | 
			
		||||
           return $type === Resource::class;
 | 
			
		||||
       }  
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
Serialization for collection
 | 
			
		||||
****************************
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
A specific model has been defined for returning collection:
 | 
			
		||||
 | 
			
		||||
@@ -673,9 +381,8 @@ A specific model has been defined for returning collection:
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
Where this is relevant, this model should be re-used in custom controller actions.
 | 
			
		||||
 | 
			
		||||
In custom actions, this can be achieved quickly by assembling results into a :code:`Chill\MainBundle\Serializer\Model\Collection`. The pagination information is given by using :code:`Paginator` (see :ref:`Pagination <pagination-ref>`).
 | 
			
		||||
This can be achieved quickly by assembling results into a :code:`Chill\MainBundle\Serializer\Model\Collection`. The pagination information is given by using :code:`Paginator` (see :ref:`Pagination <pagination-ref>`).
 | 
			
		||||
 | 
			
		||||
.. code-block:: php
 | 
			
		||||
 | 
			
		||||
@@ -693,11 +400,10 @@ In custom actions, this can be achieved quickly by assembling results into a :co
 | 
			
		||||
       }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _api_full_configuration:
 | 
			
		||||
 | 
			
		||||
Full configuration example
 | 
			
		||||
**************************
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
.. code-block:: yaml
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ Chill will be available at ``http://localhost:8001.`` Currently, there isn't any
 | 
			
		||||
 | 
			
		||||
.. code-block:: bash
 | 
			
		||||
 | 
			
		||||
   docker-compose exec --user $(id -u) php bin/console doctrine:fixtures:load --purge-with-truncate
 | 
			
		||||
   docker-compose exec --user $(id -u) php bin/console doctrine:fixtures:load
 | 
			
		||||
 | 
			
		||||
There are several users available:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,13 +18,12 @@
 | 
			
		||||
       <testsuite name="MainBundle">
 | 
			
		||||
         <directory suffix="Test.php">src/Bundle/ChillMainBundle/Tests/</directory>
 | 
			
		||||
       </testsuite>
 | 
			
		||||
       <!-- remove tests for person temporarily 
 | 
			
		||||
       <!--
 | 
			
		||||
       <testsuite name="PersonBundle">
 | 
			
		||||
         <directory suffix="Test.php">src/Bundle/ChillPersonBundle/Tests/</directory>
 | 
			
		||||
         <exclude>src/Bundle/ChillPersonBundle/Tests/Export/*</exclude>
 | 
			
		||||
        </testsuite>
 | 
			
		||||
        -->
 | 
			
		||||
    </testsuites>
 | 
			
		||||
      -->
 | 
			
		||||
      </testsuites>
 | 
			
		||||
 | 
			
		||||
    <listeners>
 | 
			
		||||
        <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ namespace Chill\MainBundle\CRUD\Controller;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Chill\MainBundle\Pagination\PaginatorFactory;
 | 
			
		||||
use Chill\MainBundle\Pagination\PaginatorInterface;
 | 
			
		||||
 | 
			
		||||
@@ -25,33 +25,12 @@ class AbstractCRUDController extends AbstractController
 | 
			
		||||
     * 
 | 
			
		||||
     * @param string $id
 | 
			
		||||
     * @return object
 | 
			
		||||
     * @throw Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the object is not found
 | 
			
		||||
     */
 | 
			
		||||
    protected function getEntity($action, $id, Request $request): object
 | 
			
		||||
    protected function getEntity($action, $id, Request $request): ?object
 | 
			
		||||
    {
 | 
			
		||||
        $e = $this->getDoctrine()
 | 
			
		||||
        return $this->getDoctrine()
 | 
			
		||||
            ->getRepository($this->getEntityClass())
 | 
			
		||||
            ->find($id);
 | 
			
		||||
 | 
			
		||||
        if (NULL === $e) {
 | 
			
		||||
            throw $this->createNotFoundException(sprintf("The object %s for id %s is not found", $this->getEntityClass(), $id));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $e;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an entity.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param string $action
 | 
			
		||||
     * @param Request $request
 | 
			
		||||
     * @return object
 | 
			
		||||
     */
 | 
			
		||||
    protected function createEntity(string $action, Request $request): object
 | 
			
		||||
    {
 | 
			
		||||
        $type = $this->getEntityClass();
 | 
			
		||||
        
 | 
			
		||||
        return new $type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -243,9 +222,4 @@ class AbstractCRUDController extends AbstractController
 | 
			
		||||
    {
 | 
			
		||||
        return $this->container->get('chill_main.paginator_factory');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getValidator(): ValidatorInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $this->get('validator');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,6 @@ use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Symfony\Component\Serializer\SerializerInterface;
 | 
			
		||||
use Chill\MainBundle\Serializer\Model\Collection;
 | 
			
		||||
use Chill\MainBundle\Pagination\PaginatorInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
 | 
			
		||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
 | 
			
		||||
 | 
			
		||||
class ApiController extends AbstractCRUDController
 | 
			
		||||
{
 | 
			
		||||
@@ -42,6 +38,11 @@ class ApiController extends AbstractCRUDController
 | 
			
		||||
            return $postFetch;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (NULL === $entity) {
 | 
			
		||||
            throw $this->createNotFoundException(sprintf("The %s with id %s "
 | 
			
		||||
                . "is not found", $this->getCrudName(), $id));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->checkACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
@@ -80,186 +81,12 @@ class ApiController extends AbstractCRUDController
 | 
			
		||||
    {
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_GET:
 | 
			
		||||
            case Request::METHOD_HEAD:
 | 
			
		||||
            case REQUEST::METHOD_HEAD:
 | 
			
		||||
                return $this->entityGet('_entity', $request, $id, $_format);
 | 
			
		||||
            case Request::METHOD_PUT:
 | 
			
		||||
            case Request::METHOD_PATCH:
 | 
			
		||||
                return $this->entityPut('_entity', $request, $id, $_format);
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                return $this->entityPostAction('_entity', $request, $id, $_format);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This method is not implemented");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public function entityPost(Request $request, $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        switch($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                return $this->entityPostAction('_entity', $request, $_format);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This method is not implemented");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function entityPostAction($action, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        $entity = $this->createEntity($action, $request);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $entity = $this->deserialize($action, $request, $_format, $entity);
 | 
			
		||||
        } catch (NotEncodableValueException $e) {
 | 
			
		||||
            throw new BadRequestException("invalid json", 400, $e);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $errors = $this->validate($action, $request, $_format, $entity);
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->onAfterValidation($action, $request, $_format, $entity, $errors);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            $response = $this->json($errors);
 | 
			
		||||
            $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
 | 
			
		||||
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->checkACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->onPostCheckACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->persist($entity);
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        $response = $this->onAfterFlush($action, $request, $_format, $entity, $errors);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        $response = $this->onBeforeSerialize($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return $this->json(
 | 
			
		||||
            $entity,
 | 
			
		||||
            Response::HTTP_OK,
 | 
			
		||||
            [], 
 | 
			
		||||
            $this->getContextForSerializationPostAlter($action, $request, $_format, $entity)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    public function entityPut($action, Request $request, $id, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        $entity = $this->getEntity($action, $id, $request, $_format);
 | 
			
		||||
        
 | 
			
		||||
        $postFetch = $this->onPostFetchEntity($action, $request, $entity, $_format);
 | 
			
		||||
        if ($postFetch instanceof Response) {
 | 
			
		||||
            return $postFetch;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (NULL === $entity) {
 | 
			
		||||
            throw $this->createNotFoundException(sprintf("The %s with id %s "
 | 
			
		||||
                . "is not found", $this->getCrudName(), $id));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->checkACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $response = $this->onPostCheckACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $response = $this->onBeforeSerialize($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            $entity = $this->deserialize($action, $request, $_format, $entity);
 | 
			
		||||
        } catch (NotEncodableValueException $e) {
 | 
			
		||||
            throw new BadRequestException("invalid json", 400, $e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $errors = $this->validate($action, $request, $_format, $entity);
 | 
			
		||||
 | 
			
		||||
        $response = $this->onAfterValidation($action, $request, $_format, $entity, $errors);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            $response = $this->json($errors);
 | 
			
		||||
            $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
 | 
			
		||||
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        $response = $this->onAfterFlush($action, $request, $_format, $entity, $errors);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->json(
 | 
			
		||||
            $entity,
 | 
			
		||||
            Response::HTTP_OK,
 | 
			
		||||
            [], 
 | 
			
		||||
            $this->getContextForSerializationPostAlter($action, $request, $_format, $entity)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function onAfterValidation(string $action, Request $request, string $_format, $entity, ConstraintViolationListInterface $errors, array $more = []): ?Response
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected function onAfterFlush(string $action, Request $request, string $_format, $entity, ConstraintViolationListInterface $errors, array $more = []): ?Response
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getValidationGroups(string $action, Request $request, string $_format, $entity): ?array
 | 
			
		||||
    {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function validate(string $action, Request $request, string $_format, $entity, array $more = []): ConstraintViolationListInterface
 | 
			
		||||
    {
 | 
			
		||||
        $validationGroups = $this->getValidationGroups($action, $request, $_format, $entity);
 | 
			
		||||
        
 | 
			
		||||
        return $this->getValidator()->validate($entity, null, $validationGroups);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deserialize the content of the request into the class associated with the curd
 | 
			
		||||
     */
 | 
			
		||||
    protected function deserialize(string $action, Request $request, string $_format, $entity = null): object
 | 
			
		||||
    {
 | 
			
		||||
        $default = [];
 | 
			
		||||
 | 
			
		||||
        if (NULL !== $entity) {
 | 
			
		||||
            $default[AbstractNormalizer::OBJECT_TO_POPULATE] = $entity;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $context = \array_merge(
 | 
			
		||||
            $default,
 | 
			
		||||
            $this->getContextForSerialization($action, $request, $_format, $entity)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return $this->getSerializer()->deserialize($request->getContent(), $this->getEntityClass(), $_format, $context);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Base action for indexing entities
 | 
			
		||||
@@ -345,110 +172,6 @@ class ApiController extends AbstractCRUDController
 | 
			
		||||
        
 | 
			
		||||
        return $this->serializeCollection($action, $request, $_format, $paginator, $entities);    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add or remove an associated entity, using `add` and `remove` methods.
 | 
			
		||||
     *
 | 
			
		||||
     * This method:
 | 
			
		||||
     *
 | 
			
		||||
     * 1. Fetch the base entity (throw 404 if not found)
 | 
			
		||||
     * 2. checkACL, 
 | 
			
		||||
     * 3. run onPostCheckACL, return response if any,
 | 
			
		||||
     * 4. deserialize posted data into the entity given by $postedDataType, with the context in $postedDataContext
 | 
			
		||||
     * 5. run 'add+$property' for POST method, or 'remove+$property' for DELETE method
 | 
			
		||||
     * 6. validate the base entity (not the deserialized one). Groups are fetched from getValidationGroups, validation is perform by `validate`
 | 
			
		||||
     * 7. run onAfterValidation
 | 
			
		||||
     * 8. if errors, return a 422 response with errors
 | 
			
		||||
     * 9. flush the data 
 | 
			
		||||
     * 10. run onAfterFlush
 | 
			
		||||
     * 11. return a 202 response for DELETE with empty body, or HTTP 200 for post with serialized posted entity
 | 
			
		||||
     *
 | 
			
		||||
     * @param string action
 | 
			
		||||
     * @param mixed id
 | 
			
		||||
     * @param Request $request
 | 
			
		||||
     * @param string $_format
 | 
			
		||||
     * @param string $property the name of the property. This will be used to make a `add+$property` and `remove+$property` method
 | 
			
		||||
     * @param string $postedDataType the type of the posted data (the content)
 | 
			
		||||
     * @param string $postedDataContext a context to deserialize posted data (the content)
 | 
			
		||||
     * @throw BadRequestException if unable to deserialize the posted data
 | 
			
		||||
     * @throw BadRequestException if the method is not POST or DELETE
 | 
			
		||||
     *
 | 
			
		||||
     */ 
 | 
			
		||||
    protected function addRemoveSomething(string $action, $id, Request $request, string $_format, string $property, string $postedDataType, $postedDataContext = []): Response
 | 
			
		||||
    {
 | 
			
		||||
        $entity = $this->getEntity($action, $id, $request);
 | 
			
		||||
 | 
			
		||||
        $postFetch = $this->onPostFetchEntity($action, $request, $entity, $_format);
 | 
			
		||||
        if ($postFetch instanceof Response) {
 | 
			
		||||
            return $postFetch;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $response = $this->checkACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $response = $this->onPostCheckACL($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $response = $this->onBeforeSerialize($action, $request, $_format, $entity);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $postedData = $this->getSerializer()->deserialize($request->getContent(), $postedDataType, $_format, $postedDataContext);
 | 
			
		||||
        } catch (\Symfony\Component\Serializer\Exception\UnexpectedValueException $e) {
 | 
			
		||||
            throw new BadRequestException(sprintf("Unable to deserialize posted ".
 | 
			
		||||
                "data: %s", $e->getMessage()), 0, $e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_DELETE:
 | 
			
		||||
                // oups... how to use property accessor to remove element ?
 | 
			
		||||
                $entity->{'remove'.\ucfirst($property)}($postedData);
 | 
			
		||||
                break;
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                $entity->{'add'.\ucfirst($property)}($postedData);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException("this method is not supported");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $errors = $this->validate($action, $request, $_format, $entity, [$postedData]);
 | 
			
		||||
 | 
			
		||||
        $response = $this->onAfterValidation($action, $request, $_format, $entity, $errors, [$postedData]);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            // only format accepted
 | 
			
		||||
            return $this->json($errors, 422);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $response = $this->onAfterFlush($action, $request, $_format, $entity, $errors, [$postedData]);
 | 
			
		||||
        if ($response instanceof Response) {
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_DELETE:
 | 
			
		||||
                return $this->json('', Response::HTTP_OK);
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                return $this->json(
 | 
			
		||||
                    $postedData,
 | 
			
		||||
                    Response::HTTP_OK,
 | 
			
		||||
                    [], 
 | 
			
		||||
                    $this->getContextForSerializationPostAlter($action, $request, $_format, $entity, [$postedData])
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Serialize collections
 | 
			
		||||
@@ -466,27 +189,7 @@ class ApiController extends AbstractCRUDController
 | 
			
		||||
 | 
			
		||||
    protected function getContextForSerialization(string $action, Request $request, string $_format, $entity): array
 | 
			
		||||
    {
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_GET:
 | 
			
		||||
                return [ 'groups' => [ 'read' ]];
 | 
			
		||||
            case Request::METHOD_PUT:
 | 
			
		||||
            case Request::METHOD_PATCH:
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                return [ 'groups' => [ 'write' ]];
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \LogicException("get context for serialization is not implemented for this method");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the context for serialization post alter query (in case of 
 | 
			
		||||
     * PATCH, PUT, or POST method)
 | 
			
		||||
     *
 | 
			
		||||
     * This is called **after** the entity was altered.
 | 
			
		||||
     */
 | 
			
		||||
    protected function getContextForSerializationPostAlter(string $action, Request $request, string $_format, $entity, array $more = []): array
 | 
			
		||||
    {
 | 
			
		||||
        return [ 'groups' => [ 'read' ]];
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -183,26 +183,6 @@ class CRUDRoutesLoader extends Loader
 | 
			
		||||
            $methods = \array_keys(\array_filter($action['methods'], function($value, $key) { return $value; },
 | 
			
		||||
                ARRAY_FILTER_USE_BOTH));
 | 
			
		||||
 | 
			
		||||
            if (count($methods) === 0) {
 | 
			
		||||
                throw new \RuntimeException("The api configuration named \"{$crudConfig['name']}\", action \"{$name}\", ".
 | 
			
		||||
                    "does not have any allowed methods. You should remove this action from the config ".
 | 
			
		||||
                    "or allow, at least, one method"); 
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ('_entity' === $name && \in_array(Request::METHOD_POST, $methods)) {
 | 
			
		||||
                unset($methods[\array_search(Request::METHOD_POST, $methods)]);
 | 
			
		||||
                $entityPostRoute = $this->createEntityPostRoute($name, $crudConfig, $action, 
 | 
			
		||||
                    $controller);
 | 
			
		||||
                $collection->add("chill_api_single_{$crudConfig['name']}_{$name}_create", 
 | 
			
		||||
                    $entityPostRoute);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (count($methods) === 0) {
 | 
			
		||||
                // the only method was POST,
 | 
			
		||||
                // continue to next
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $route = new Route($path, $defaults, $requirements);
 | 
			
		||||
            $route->setMethods($methods);
 | 
			
		||||
            
 | 
			
		||||
@@ -212,17 +192,45 @@ class CRUDRoutesLoader extends Loader
 | 
			
		||||
        return $collection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function createEntityPostRoute(string $name, $crudConfig, array $action, $controller): Route
 | 
			
		||||
    /**
 | 
			
		||||
     * Load routes for api multi
 | 
			
		||||
     *
 | 
			
		||||
     * @param $crudConfig
 | 
			
		||||
     * @return RouteCollection
 | 
			
		||||
     */
 | 
			
		||||
    protected function loadApiMultiConfig(array $crudConfig): RouteCollection
 | 
			
		||||
    {
 | 
			
		||||
        $localPath = $action['path'].'.{_format}';
 | 
			
		||||
        $defaults = [
 | 
			
		||||
            '_controller' => $controller.':'.($action['controller_action'] ?? 'entityPost')
 | 
			
		||||
        ];
 | 
			
		||||
        $path = $crudConfig['base_path'].$localPath;
 | 
			
		||||
        $requirements = $action['requirements'] ?? [];
 | 
			
		||||
        $route = new Route($path, $defaults, $requirements);
 | 
			
		||||
        $route->setMethods([ Request::METHOD_POST ]);
 | 
			
		||||
        $collection = new RouteCollection();
 | 
			
		||||
        $controller ='csapi_'.$crudConfig['name'].'_controller';
 | 
			
		||||
 | 
			
		||||
        return $route;
 | 
			
		||||
        foreach ($crudConfig['actions'] as $name => $action) {
 | 
			
		||||
            // filter only on single actions
 | 
			
		||||
            $singleCollection = $action['single-collection'] ?? $name === '_index' ? 'collection' : NULL;
 | 
			
		||||
            if ('single' === $singleCollection) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $defaults = [
 | 
			
		||||
                '_controller' => $controller.':'.($action['controller_action'] ?? '_entity' === $name ? 'entityApi' : $name.'Api')
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // path are rewritten
 | 
			
		||||
            // if name === 'default', we rewrite it to nothing :-)
 | 
			
		||||
            $localName = '_entity' === $name ? '' : '/'.$name;
 | 
			
		||||
            $localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
 | 
			
		||||
            $path = $crudConfig['base_path'].$localPath;
 | 
			
		||||
 | 
			
		||||
            $requirements = $action['requirements'] ?? [ '{id}' => '\d+' ];
 | 
			
		||||
 | 
			
		||||
            $methods = \array_keys(\array_filter($action['methods'], function($value, $key) { return $value; },
 | 
			
		||||
                ARRAY_FILTER_USE_BOTH));
 | 
			
		||||
 | 
			
		||||
            $route = new Route($path, $defaults, $requirements);
 | 
			
		||||
            $route->setMethods($methods);
 | 
			
		||||
            
 | 
			
		||||
            $collection->add('chill_api_single_'.$crudConfig['name'].'_'.$name, $route);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $collection;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Controller;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Serializer\Model\Collection;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Chill\MainBundle\Search\UnknowSearchDomainException;
 | 
			
		||||
@@ -35,7 +34,6 @@ use Symfony\Component\HttpFoundation\JsonResponse;
 | 
			
		||||
use Chill\MainBundle\Search\SearchProvider;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
use Chill\MainBundle\Pagination\PaginatorFactory;
 | 
			
		||||
use Chill\MainBundle\Search\SearchApi;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class SearchController
 | 
			
		||||
@@ -44,24 +42,32 @@ use Chill\MainBundle\Search\SearchApi;
 | 
			
		||||
 */
 | 
			
		||||
class SearchController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
    protected SearchProvider $searchProvider;
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @var SearchProvider
 | 
			
		||||
     */
 | 
			
		||||
    protected $searchProvider;
 | 
			
		||||
    
 | 
			
		||||
    protected TranslatorInterface $translator;
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @var TranslatorInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $translator;
 | 
			
		||||
    
 | 
			
		||||
    protected PaginatorFactory $paginatorFactory;
 | 
			
		||||
 | 
			
		||||
    protected SearchApi $searchApi;
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @var PaginatorFactory
 | 
			
		||||
     */
 | 
			
		||||
    protected $paginatorFactory;
 | 
			
		||||
    
 | 
			
		||||
    function __construct(
 | 
			
		||||
        SearchProvider $searchProvider, 
 | 
			
		||||
        TranslatorInterface $translator,
 | 
			
		||||
        PaginatorFactory $paginatorFactory,
 | 
			
		||||
        SearchApi $searchApi
 | 
			
		||||
        PaginatorFactory $paginatorFactory
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->searchProvider = $searchProvider;
 | 
			
		||||
        $this->translator = $translator;
 | 
			
		||||
        $this->paginatorFactory = $paginatorFactory;
 | 
			
		||||
        $this->searchApi = $searchApi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
@@ -146,19 +152,6 @@ class SearchController extends AbstractController
 | 
			
		||||
              array('results' => $results, 'pattern' => $pattern)
 | 
			
		||||
              );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function searchApi(Request $request, $_format): JsonResponse
 | 
			
		||||
    {
 | 
			
		||||
        //TODO this is an incomplete implementation
 | 
			
		||||
        $query = $request->query->get('q', '');
 | 
			
		||||
 | 
			
		||||
        $results = $this->searchApi->getResults($query, 0, 150);
 | 
			
		||||
        $paginator = $this->paginatorFactory->create(count($results));
 | 
			
		||||
 | 
			
		||||
        $collection = new Collection($results, $paginator);
 | 
			
		||||
 | 
			
		||||
        return $this->json($collection);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function advancedSearchListAction(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -55,11 +55,11 @@ class LoadCenters extends AbstractFixture implements OrderedFixtureInterface
 | 
			
		||||
    public function load(ObjectManager $manager)
 | 
			
		||||
    {
 | 
			
		||||
        foreach (static::$centers as $new) {
 | 
			
		||||
            $center = new Center();
 | 
			
		||||
            $center->setName($new['name']);
 | 
			
		||||
            $centerA = new Center();
 | 
			
		||||
            $centerA->setName($new['name']);
 | 
			
		||||
 | 
			
		||||
            $manager->persist($center);
 | 
			
		||||
            $this->addReference($new['ref'], $center);
 | 
			
		||||
            $manager->persist($centerA);
 | 
			
		||||
            $this->addReference($new['ref'], $centerA);
 | 
			
		||||
            static::$refs[] = $new['ref'];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
@@ -35,9 +35,6 @@ use Chill\MainBundle\Doctrine\DQL\OverlapsI;
 | 
			
		||||
use Symfony\Component\DependencyInjection\Definition;
 | 
			
		||||
use Symfony\Component\DependencyInjection\Reference;
 | 
			
		||||
use Chill\MainBundle\Doctrine\DQL\Replace;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Type\PointType;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ChillMainExtension
 | 
			
		||||
@@ -136,7 +133,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
 | 
			
		||||
        $loader->load('services/search.yaml');
 | 
			
		||||
        $loader->load('services/serializer.yaml');
 | 
			
		||||
 | 
			
		||||
        $this->configureCruds($container, $config['cruds'], $config['apis'], $loader);
 | 
			
		||||
        $this->configureCruds($container, $config['cruds'], $config['apis'], $loader); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -169,49 +166,37 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
 | 
			
		||||
        $container->prependExtensionConfig('twig', $twigConfig);
 | 
			
		||||
 | 
			
		||||
        //add DQL function to ORM (default entity_manager)
 | 
			
		||||
        $container
 | 
			
		||||
            ->prependExtensionConfig(
 | 
			
		||||
                'doctrine',
 | 
			
		||||
                [
 | 
			
		||||
                    'orm' => [
 | 
			
		||||
                        'dql' => [
 | 
			
		||||
                            'string_functions' => [
 | 
			
		||||
                                'unaccent' => Unaccent::class,
 | 
			
		||||
                                'GET_JSON_FIELD_BY_KEY' => GetJsonFieldByKey::class,
 | 
			
		||||
                                'AGGREGATE' => JsonAggregate::class,
 | 
			
		||||
                                'REPLACE' => Replace::class,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'numeric_functions' => [
 | 
			
		||||
                                'JSONB_EXISTS_IN_ARRAY' => JsonbExistsInArray::class,
 | 
			
		||||
                                'SIMILARITY' => Similarity::class,
 | 
			
		||||
                                'OVERLAPSI' => OverlapsI::class,
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                    ],
 | 
			
		||||
                ],
 | 
			
		||||
        );
 | 
			
		||||
        $container->prependExtensionConfig('doctrine', array(
 | 
			
		||||
           'orm' => array(
 | 
			
		||||
              'dql' => array(
 | 
			
		||||
                 'string_functions' => array(
 | 
			
		||||
                    'unaccent' => Unaccent::class,
 | 
			
		||||
                    'GET_JSON_FIELD_BY_KEY' => GetJsonFieldByKey::class,
 | 
			
		||||
                    'AGGREGATE' => JsonAggregate::class,
 | 
			
		||||
                    'REPLACE' => Replace::class,
 | 
			
		||||
                 ),
 | 
			
		||||
                 'numeric_functions' => [
 | 
			
		||||
                    'JSONB_EXISTS_IN_ARRAY' => JsonbExistsInArray::class,
 | 
			
		||||
                    'SIMILARITY' => Similarity::class,
 | 
			
		||||
                    'OVERLAPSI' => OverlapsI::class
 | 
			
		||||
                ]
 | 
			
		||||
              )
 | 
			
		||||
           )
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        //add dbal types (default entity_manager)
 | 
			
		||||
        $container
 | 
			
		||||
            ->prependExtensionConfig(
 | 
			
		||||
                'doctrine',
 | 
			
		||||
                [
 | 
			
		||||
                   'dbal' => [
 | 
			
		||||
                        // This is mandatory since we are using postgis as database.
 | 
			
		||||
                        'mapping_types' => [
 | 
			
		||||
                            'geometry' => 'string',
 | 
			
		||||
                        ],
 | 
			
		||||
                        'types' => [
 | 
			
		||||
                            'dateinterval' => [
 | 
			
		||||
                                'class' => NativeDateIntervalType::class
 | 
			
		||||
                            ],
 | 
			
		||||
                            'point' => [
 | 
			
		||||
                                'class' => PointType::class
 | 
			
		||||
                            ]
 | 
			
		||||
                        ]
 | 
			
		||||
                    ]
 | 
			
		||||
                ]
 | 
			
		||||
        );
 | 
			
		||||
        $container->prependExtensionConfig('doctrine', array(
 | 
			
		||||
           'dbal' => [
 | 
			
		||||
               'types' => [
 | 
			
		||||
                   'dateinterval' => [
 | 
			
		||||
                       'class' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class
 | 
			
		||||
                   ],
 | 
			
		||||
                   'point' => [
 | 
			
		||||
                       'class' => \Chill\MainBundle\Doctrine\Type\PointType::class
 | 
			
		||||
                   ]
 | 
			
		||||
               ]
 | 
			
		||||
           ]
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        //add current route to chill main
 | 
			
		||||
        $container->prependExtensionConfig('chill_main', array(
 | 
			
		||||
@@ -227,9 +212,6 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
 | 
			
		||||
        $container->prependExtensionConfig('monolog', array(
 | 
			
		||||
            'channels' => array('chill')
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        //add crud api
 | 
			
		||||
        $this->prependCruds($container);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -253,97 +235,4 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
 | 
			
		||||
 | 
			
		||||
        // Note: the controller are loaded inside compiler pass
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param ContainerBuilder $container
 | 
			
		||||
     */
 | 
			
		||||
    protected function prependCruds(ContainerBuilder $container)
 | 
			
		||||
    {
 | 
			
		||||
        $container->prependExtensionConfig('chill_main', [
 | 
			
		||||
            'apis' => [
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\MainBundle\Entity\Address::class,
 | 
			
		||||
                    'name' => 'address',
 | 
			
		||||
                    'base_path' => '/api/1.0/main/address',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_POST => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\MainBundle\Entity\AddressReference::class,
 | 
			
		||||
                    'name' => 'address_reference',
 | 
			
		||||
                    'base_path' => '/api/1.0/main/address-reference',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\MainBundle\Entity\PostalCode::class,
 | 
			
		||||
                    'name' => 'postal_code',
 | 
			
		||||
                    'base_path' => '/api/1.0/main/postal-code',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\MainBundle\Entity\Country::class,
 | 
			
		||||
                    'name' => 'country',
 | 
			
		||||
                    'base_path' => '/api/1.0/main/country',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ]
 | 
			
		||||
            ]
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -221,7 +221,6 @@ class Configuration implements ConfigurationInterface
 | 
			
		||||
                                                ->booleanNode(Request::METHOD_POST)->defaultFalse()->end()
 | 
			
		||||
                                                ->booleanNode(Request::METHOD_DELETE)->defaultFalse()->end()
 | 
			
		||||
                                                ->booleanNode(Request::METHOD_PUT)->defaultFalse()->end()
 | 
			
		||||
                                                ->booleanNode(Request::METHOD_PATCH)->defaultFalse()->end()
 | 
			
		||||
                                            ->end()
 | 
			
		||||
                                        ->end()
 | 
			
		||||
                                        ->arrayNode('roles')
 | 
			
		||||
@@ -233,7 +232,6 @@ class Configuration implements ConfigurationInterface
 | 
			
		||||
                                                ->scalarNode(Request::METHOD_POST)->defaultNull()->end()
 | 
			
		||||
                                                ->scalarNode(Request::METHOD_DELETE)->defaultNull()->end()
 | 
			
		||||
                                                ->scalarNode(Request::METHOD_PUT)->defaultNull()->end()
 | 
			
		||||
                                                ->scalarNode(Request::METHOD_PATCH)->defaultNull()->end()
 | 
			
		||||
                                            ->end()
 | 
			
		||||
                                        ->end()
 | 
			
		||||
                                    ->end()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Doctrine\Event;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Doctrine\Common\EventSubscriber;
 | 
			
		||||
use Doctrine\ORM\Events;
 | 
			
		||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
 | 
			
		||||
use Symfony\Component\Security\Core\Security;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TrackCreateUpdateSubscriber implements EventSubscriber
 | 
			
		||||
{
 | 
			
		||||
    private Security $security;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Security $security
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Security $security)
 | 
			
		||||
    {
 | 
			
		||||
        $this->security = $security;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    public function getSubscribedEvents()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            Events::prePersist,
 | 
			
		||||
            Events::preUpdate
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function prePersist(LifecycleEventArgs $args): void
 | 
			
		||||
    {
 | 
			
		||||
        $object = $args->getObject();
 | 
			
		||||
 | 
			
		||||
        if ($object instanceof TrackCreationInterface
 | 
			
		||||
            && $this->security->getUser() instanceof User) {
 | 
			
		||||
            $object->setCreatedBy($this->security->getUser());
 | 
			
		||||
            $object->setCreatedAt(new \DateTimeImmutable('now'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->onUpdate($object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function preUpdate(LifecycleEventArgs $args): void
 | 
			
		||||
    {
 | 
			
		||||
        $object = $args->getObject();
 | 
			
		||||
 | 
			
		||||
        $this->onUpdate($object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function onUpdate(object $object): void
 | 
			
		||||
    {
 | 
			
		||||
        if ($object instanceof TrackUpdateInterface 
 | 
			
		||||
            && $this->security->getUser() instanceof User) {
 | 
			
		||||
            $object->setUpdatedBy($this->security->getUser());
 | 
			
		||||
            $object->setUpdatedAt(new \DateTimeImmutable('now'));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Doctrine\Model;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
 | 
			
		||||
interface TrackCreationInterface
 | 
			
		||||
{
 | 
			
		||||
    public function setCreatedBy(User $user): self;
 | 
			
		||||
 | 
			
		||||
    public function setCreatedAt(\DateTimeInterface $datetime): self;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Doctrine\Model;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
 | 
			
		||||
interface TrackUpdateInterface
 | 
			
		||||
{
 | 
			
		||||
    public function setUpdatedBy(User $user): self;
 | 
			
		||||
 | 
			
		||||
    public function setUpdatedAt(\DateTimeInterface $datetime): self;
 | 
			
		||||
}
 | 
			
		||||
@@ -137,7 +137,7 @@ class Address
 | 
			
		||||
     * @var ThirdParty|null
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
     */
 | 
			
		||||
    private $linkedToThirdParty;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,12 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Entity;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\AddressReferenceRepository;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\Point;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity()
 | 
			
		||||
 * @ORM\Entity(repositoryClass=AddressReferenceRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_main_address_reference")
 | 
			
		||||
 * @ORM\HasLifecycleCallbacks()
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,16 +24,13 @@ use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Chill\MainBundle\Entity\RoleScope;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity()
 | 
			
		||||
 * @ORM\Table(name="scopes")
 | 
			
		||||
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="acl_cache_region")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *    "scope"=Scope::class
 | 
			
		||||
 * })
 | 
			
		||||
 *
 | 
			
		||||
 * @author Julien Fastré <julien.fastre@champs-libres.coop>
 | 
			
		||||
 */
 | 
			
		||||
class Scope
 | 
			
		||||
{
 | 
			
		||||
@@ -43,7 +40,6 @@ class Scope
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\Column(name="id", type="integer")
 | 
			
		||||
     * @ORM\GeneratedValue(strategy="AUTO")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
    
 | 
			
		||||
@@ -53,7 +49,6 @@ class Scope
 | 
			
		||||
     * @var array
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="json_array")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $name = [];
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
 | 
			
		||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User
 | 
			
		||||
@@ -15,9 +14,6 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 * @ORM\Entity(repositoryClass="Chill\MainBundle\Repository\UserRepository")
 | 
			
		||||
 * @ORM\Table(name="users")
 | 
			
		||||
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="acl_cache_region")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *    "user"=User::class
 | 
			
		||||
 * })
 | 
			
		||||
 */
 | 
			
		||||
class User implements AdvancedUserInterface {
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,9 @@
 | 
			
		||||
div#header-accompanying_course-name {
 | 
			
		||||
  background: none repeat scroll 0 0 #718596;
 | 
			
		||||
  color: #FFF;
 | 
			
		||||
  h1 {
 | 
			
		||||
    margin: 0.4em 0;       
 | 
			
		||||
  }
 | 
			
		||||
  padding-top: 1em;
 | 
			
		||||
  padding-bottom: 1em;
 | 
			
		||||
 | 
			
		||||
  span {
 | 
			
		||||
    a {
 | 
			
		||||
      color: white;
 | 
			
		||||
@@ -39,25 +39,115 @@ div.subheader {
 | 
			
		||||
  height: 130px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// SCRATCH BUTTONS
 | 
			
		||||
.sc-button {
 | 
			
		||||
   &.disabled {
 | 
			
		||||
      cursor: default;
 | 
			
		||||
      &.bt-remove {
 | 
			
		||||
         background-color: #d9d9d9;
 | 
			
		||||
//// VUEJS ////
 | 
			
		||||
 | 
			
		||||
div.vue-component {
 | 
			
		||||
  padding: 1.5em;
 | 
			
		||||
  margin: 2em 0;
 | 
			
		||||
  border: 2px dashed grey;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  &:before {
 | 
			
		||||
    content: "vuejs component";
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 1.5em;
 | 
			
		||||
    top: -0.9em;
 | 
			
		||||
    background-color: white;
 | 
			
		||||
    color: grey;
 | 
			
		||||
    padding: 0 0.3em;
 | 
			
		||||
  }
 | 
			
		||||
  dd { margin-left: 1em; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// MODAL ////
 | 
			
		||||
.modal-mask {
 | 
			
		||||
   position: fixed;
 | 
			
		||||
   z-index: 9998;
 | 
			
		||||
   top: 0;
 | 
			
		||||
   left: 0;
 | 
			
		||||
   width: 100%;
 | 
			
		||||
   height: 100%;
 | 
			
		||||
   background-color: rgba(0, 0, 0, 0.75);
 | 
			
		||||
   display: table;
 | 
			
		||||
   transition: opacity 0.3s ease;
 | 
			
		||||
}
 | 
			
		||||
.modal-header .close { // bootstrap classes, override sc-button 0 radius
 | 
			
		||||
   border-top-right-radius: 0.3rem;
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* The following styles are auto-applied to elements with
 | 
			
		||||
* transition="modal" when their visibility is toggled
 | 
			
		||||
* by Vue.js.
 | 
			
		||||
*
 | 
			
		||||
* You can easily play with the modal transition by editing
 | 
			
		||||
* these styles.
 | 
			
		||||
*/
 | 
			
		||||
.modal-enter {
 | 
			
		||||
   opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
.modal-leave-active {
 | 
			
		||||
   opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
.modal-enter .modal-container,
 | 
			
		||||
.modal-leave-active .modal-container {
 | 
			
		||||
   -webkit-transform: scale(1.1);
 | 
			
		||||
   transform: scale(1.1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// AddPersons modal
 | 
			
		||||
div.modal-body.up {
 | 
			
		||||
   margin: auto 4em;
 | 
			
		||||
   div.search {
 | 
			
		||||
      position: relative;
 | 
			
		||||
      input { 
 | 
			
		||||
         padding: 1.2em 1.5em 1.2em 2.5em;
 | 
			
		||||
         margin: 1em 0;
 | 
			
		||||
      }
 | 
			
		||||
      i {
 | 
			
		||||
         position: absolute;
 | 
			
		||||
         top: 50%; 
 | 
			
		||||
         left: 0.5em;
 | 
			
		||||
         padding: 0.65em 0;
 | 
			
		||||
         opacity: 0.5;
 | 
			
		||||
      }
 | 
			
		||||
         
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
div.results {
 | 
			
		||||
   div.count {
 | 
			
		||||
      margin: -0.5em 0 0.7em;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
   }
 | 
			
		||||
   div.list-item {
 | 
			
		||||
      line-height: 26pt;
 | 
			
		||||
      padding: 0.3em 0.8em;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: row;
 | 
			
		||||
      &.checked {
 | 
			
		||||
         background-color: #ececec;
 | 
			
		||||
         border-bottom: 1px dotted #8b8b8b;
 | 
			
		||||
      }
 | 
			
		||||
      div.container {
 | 
			
		||||
         & > input {
 | 
			
		||||
            margin-right: 0.8em;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
      div.right_actions {
 | 
			
		||||
         margin: 0 0 0 auto;
 | 
			
		||||
         & > * {
 | 
			
		||||
            margin-left: 0.5em;
 | 
			
		||||
         }
 | 
			
		||||
         a.sc-button {
 | 
			
		||||
            border: 1px solid lightgrey;
 | 
			
		||||
            font-size: 70%;
 | 
			
		||||
            padding: 4px;
 | 
			
		||||
         } 
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// à ranger
 | 
			
		||||
.discret {
 | 
			
		||||
   color: grey;
 | 
			
		||||
   margin-right: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table {
 | 
			
		||||
   ul.record_actions {
 | 
			
		||||
      margin: 0;
 | 
			
		||||
      padding: 0.5em;
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   
 | 
			
		||||
   <div v-if="address.address">
 | 
			
		||||
      {{ address.address.street }}, {{ address.address.streetNumber }}
 | 
			
		||||
   </div>
 | 
			
		||||
   <div v-if="address.city">
 | 
			
		||||
      {{ address.city.code }} {{ address.city.name }}
 | 
			
		||||
   </div>
 | 
			
		||||
   <div v-if="address.country">
 | 
			
		||||
      {{ address.country.name }}
 | 
			
		||||
   </div>
 | 
			
		||||
   
 | 
			
		||||
   <add-address
 | 
			
		||||
      @addNewAddress="addNewAddress">
 | 
			
		||||
   </add-address>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { mapState } from 'vuex';
 | 
			
		||||
 | 
			
		||||
import AddAddress from '../_components/AddAddress.vue';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'App',
 | 
			
		||||
   components: {
 | 
			
		||||
      AddAddress
 | 
			
		||||
   },
 | 
			
		||||
   computed: {
 | 
			
		||||
      address() {
 | 
			
		||||
         return this.$store.state.address;
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   methods: {
 | 
			
		||||
      addNewAddress({ address, modal }) {
 | 
			
		||||
         console.log('@@@ CLICK button addNewAdress', address);
 | 
			
		||||
         this.$store.dispatch('addAddress', address.selected);
 | 
			
		||||
         modal.showModal = false;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
import { createApp } from 'vue'
 | 
			
		||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
 | 
			
		||||
import { addressMessages } from './js/i18n'
 | 
			
		||||
import { store } from './store'
 | 
			
		||||
 | 
			
		||||
import App from './App.vue';
 | 
			
		||||
 | 
			
		||||
const i18n = _createI18n(addressMessages);
 | 
			
		||||
 | 
			
		||||
const app = createApp({
 | 
			
		||||
   template: `<app></app>`,
 | 
			
		||||
})
 | 
			
		||||
.use(store)
 | 
			
		||||
.use(i18n)
 | 
			
		||||
.component('app', App)
 | 
			
		||||
.mount('#address');
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
const addressMessages = {
 | 
			
		||||
   fr: {
 | 
			
		||||
      add_an_address: 'Ajouter une adresse',
 | 
			
		||||
      select_an_address: 'Sélectionner une adresse',
 | 
			
		||||
      fill_an_address: 'Compléter l\'adresse',
 | 
			
		||||
      select_country: 'Choisir le pays',
 | 
			
		||||
      select_city: 'Choisir une localité',
 | 
			
		||||
      select_address: 'Choisir une adresse',
 | 
			
		||||
      isNoAddress: 'L\'adresse n\'est pas celle d\'un domicile fixe ?',
 | 
			
		||||
      floor: 'Étage',
 | 
			
		||||
      corridor: 'Couloir',
 | 
			
		||||
      steps: 'Escalier',
 | 
			
		||||
      flat: 'Appartement',
 | 
			
		||||
      buildingName: 'Nom du batiment',
 | 
			
		||||
      extra: 'Complément d\'adresse',
 | 
			
		||||
      distribution: 'Service particulier de distribution'
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
   addressMessages
 | 
			
		||||
};
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
import 'es6-promise/auto';
 | 
			
		||||
import { createStore } from 'vuex';
 | 
			
		||||
 | 
			
		||||
// le fetch POST serait rangé dans la logique du composant qui appelle AddAddress
 | 
			
		||||
//import { postAddress } from '... api' 
 | 
			
		||||
 | 
			
		||||
const debug = process.env.NODE_ENV !== 'production';
 | 
			
		||||
 | 
			
		||||
const store = createStore({
 | 
			
		||||
   strict: debug,
 | 
			
		||||
   state: {
 | 
			
		||||
      address: {},
 | 
			
		||||
      errorMsg: {}
 | 
			
		||||
   },
 | 
			
		||||
   getters: {
 | 
			
		||||
   },
 | 
			
		||||
   mutations: {
 | 
			
		||||
      addAddress(state, address) {
 | 
			
		||||
         console.log('@M addAddress address', address);
 | 
			
		||||
         state.address = address;
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   actions: {
 | 
			
		||||
      addAddress({ commit }, payload) {
 | 
			
		||||
         console.log('@A addAddress payload', payload);
 | 
			
		||||
         commit('addAddress', payload); // à remplacer par 
 | 
			
		||||
         
 | 
			
		||||
         // fetch POST qui envoie l'adresse, et récupère la confirmation que c'est ok. 
 | 
			
		||||
         // La confirmation est l'adresse elle-même.
 | 
			
		||||
         //
 | 
			
		||||
         //   postAddress(payload) 
 | 
			
		||||
         //   .fetch(address => new Promise((resolve, reject) => {
 | 
			
		||||
         //      commit('addAddress', address);
 | 
			
		||||
         //      resolve();
 | 
			
		||||
         //   }))
 | 
			
		||||
         //   .catch((error) => { 
 | 
			
		||||
         //      state.errorMsg.push(error.message); 
 | 
			
		||||
         //   }); 
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export { store };
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
* Endpoint countries GET
 | 
			
		||||
* TODO
 | 
			
		||||
*/
 | 
			
		||||
const fetchCountries = () => {
 | 
			
		||||
   console.log('<<< fetching countries');
 | 
			
		||||
   return [
 | 
			
		||||
      {id: 1, name: 'France', countryCode: 'FR'},
 | 
			
		||||
      {id: 2, name: 'Belgium', countryCode: 'BE'}
 | 
			
		||||
   ];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Endpoint cities GET 
 | 
			
		||||
* TODO
 | 
			
		||||
*/
 | 
			
		||||
const fetchCities = (country) => {   
 | 
			
		||||
   console.log('<<< fetching cities for', country);
 | 
			
		||||
   return [
 | 
			
		||||
      {id: 1, name: 'Bruxelles', code: '1000', country: 'BE'},
 | 
			
		||||
      {id: 2, name: 'Aisne', code: '85045', country: 'FR'},
 | 
			
		||||
      {id: 3, name: 'Saint-Gervais', code: '85230', country: 'FR'}
 | 
			
		||||
   ];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Endpoint chill_main_address_reference_api_show
 | 
			
		||||
* method GET, get AddressReference Object
 | 
			
		||||
* @returns {Promise} a promise containing all AddressReference object
 | 
			
		||||
*/
 | 
			
		||||
const fetchReferenceAddresses = (city) => {
 | 
			
		||||
    console.log('<<< fetching references addresses for', city); // city n'est pas utilisé pour le moment
 | 
			
		||||
    
 | 
			
		||||
    const url = `/api/1.0/main/address-reference.json`;
 | 
			
		||||
    return fetch(url)
 | 
			
		||||
       .then(response => {
 | 
			
		||||
          if (response.ok) { return response.json(); }
 | 
			
		||||
          throw Error('Error with request resource response');
 | 
			
		||||
       });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
   fetchCountries,
 | 
			
		||||
   fetchCities,
 | 
			
		||||
   fetchReferenceAddresses
 | 
			
		||||
};
 | 
			
		||||
@@ -1,219 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <button class="sc-button bt-create centered mt-4" @click="openModal">
 | 
			
		||||
      {{ $t('add_an_address') }}
 | 
			
		||||
   </button>
 | 
			
		||||
 | 
			
		||||
   <teleport to="body">
 | 
			
		||||
      <modal v-if="modal.showModal"
 | 
			
		||||
         v-bind:modalDialogClass="modal.modalDialogClass"
 | 
			
		||||
         @close="modal.showModal = false">
 | 
			
		||||
 | 
			
		||||
         <template v-slot:header>
 | 
			
		||||
            <h3 class="modal-title">{{ $t('add_an_address') }}</h3>
 | 
			
		||||
         </template>
 | 
			
		||||
 | 
			
		||||
         <template v-slot:body>
 | 
			
		||||
            
 | 
			
		||||
            <h4>{{ $t('select_an_address') }}</h4>
 | 
			
		||||
            
 | 
			
		||||
            <label for="isNoAddress">
 | 
			
		||||
               <input type="checkbox" 
 | 
			
		||||
                  name="isNoAddress" 
 | 
			
		||||
                  v-bind:placeholder="$t('isNoAddress')" 
 | 
			
		||||
                  v-model="isNoAddress" 
 | 
			
		||||
                  v-bind:value="value"/>
 | 
			
		||||
               {{ $t('isNoAddress') }}
 | 
			
		||||
            </label>
 | 
			
		||||
 | 
			
		||||
            <country-selection
 | 
			
		||||
               v-bind:address="address"
 | 
			
		||||
               v-bind:getCities="getCities">
 | 
			
		||||
            </country-selection>
 | 
			
		||||
            
 | 
			
		||||
            <city-selection
 | 
			
		||||
               v-bind:address="address"
 | 
			
		||||
               v-bind:getReferenceAddresses="getReferenceAddresses">
 | 
			
		||||
            </city-selection>
 | 
			
		||||
            
 | 
			
		||||
            <address-selection
 | 
			
		||||
               v-bind:address="address"
 | 
			
		||||
               v-bind:updateMapCenter="updateMapCenter">
 | 
			
		||||
            </address-selection>
 | 
			
		||||
 | 
			
		||||
            <address-map
 | 
			
		||||
               v-bind:address="address"
 | 
			
		||||
               ref="addressMap">
 | 
			
		||||
            </address-map>
 | 
			
		||||
            
 | 
			
		||||
            <address-more 
 | 
			
		||||
               v-if="!isNoAddress"
 | 
			
		||||
               v-bind:address="address">
 | 
			
		||||
            </address-more>
 | 
			
		||||
                        
 | 
			
		||||
            <!--
 | 
			
		||||
            <div class="address_form__fields__isNoAddress"></div>
 | 
			
		||||
            <div class="address_form__select">
 | 
			
		||||
               <div class="address_form__select__header"></div>
 | 
			
		||||
               <div class="address_form__select__left"></div>
 | 
			
		||||
               <div class="address_form__map"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="address_form__fields">
 | 
			
		||||
               <div class="address_form__fields__header"></div>
 | 
			
		||||
               <div class="address_form__fields__left"></div>
 | 
			
		||||
               <div class="address_form__fields__right"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
         
 | 
			
		||||
            à discuter, 
 | 
			
		||||
            mais je pense qu'il est préférable de profiter de l'imbriquation des classes css 
 | 
			
		||||
            
 | 
			
		||||
            div.address_form {
 | 
			
		||||
               div.select {
 | 
			
		||||
                  div.header {}
 | 
			
		||||
                  div.left {}
 | 
			
		||||
                  div.map {}
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
         
 | 
			
		||||
            -->
 | 
			
		||||
         </template>
 | 
			
		||||
 | 
			
		||||
         <template v-slot:footer>
 | 
			
		||||
            <button class="sc-button green" 
 | 
			
		||||
               @click.prevent="$emit('addNewAddress', { address, modal })">
 | 
			
		||||
               <i class="fa fa-plus fa-fw"></i>{{ $t('action.add')}}
 | 
			
		||||
            </button>
 | 
			
		||||
         </template>
 | 
			
		||||
 | 
			
		||||
      </modal>
 | 
			
		||||
   </teleport>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Modal from './Modal';
 | 
			
		||||
import { fetchCountries, fetchCities, fetchReferenceAddresses } from '../_api/AddAddress'
 | 
			
		||||
import CountrySelection from './AddAddress/CountrySelection';
 | 
			
		||||
import CitySelection from './AddAddress/CitySelection';
 | 
			
		||||
import AddressSelection from './AddAddress/AddressSelection';
 | 
			
		||||
import AddressMap from './AddAddress/AddressMap';
 | 
			
		||||
import AddressMore from './AddAddress/AddressMore'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'AddAddresses',
 | 
			
		||||
   components: {
 | 
			
		||||
      Modal,
 | 
			
		||||
      CountrySelection,
 | 
			
		||||
      CitySelection,
 | 
			
		||||
      AddressSelection,
 | 
			
		||||
      AddressMap,
 | 
			
		||||
      AddressMore
 | 
			
		||||
   },
 | 
			
		||||
   props: [
 | 
			
		||||
   ],
 | 
			
		||||
   emits: ['addNewAddress'],
 | 
			
		||||
   data() {
 | 
			
		||||
      return {
 | 
			
		||||
         modal: {
 | 
			
		||||
            showModal: false,
 | 
			
		||||
            modalDialogClass: "modal-dialog-scrollable modal-xl"
 | 
			
		||||
         },
 | 
			
		||||
         address: {
 | 
			
		||||
            loaded: {
 | 
			
		||||
               countries: [],
 | 
			
		||||
               cities: [],
 | 
			
		||||
               addresses: [],
 | 
			
		||||
            },
 | 
			
		||||
            selected: {
 | 
			
		||||
               country: {},
 | 
			
		||||
               city: {},
 | 
			
		||||
               address: {},
 | 
			
		||||
            },
 | 
			
		||||
            addressMap: {
 | 
			
		||||
               center : [48.8589, 2.3469], // Note: LeafletJs demands [lat, lon] cfr https://macwright.com/lonlat/
 | 
			
		||||
               zoom: 12
 | 
			
		||||
            },
 | 
			
		||||
            isNoAddress: false,
 | 
			
		||||
            floor: null,
 | 
			
		||||
            corridor: null,
 | 
			
		||||
            steps: null,
 | 
			
		||||
            floor: null,
 | 
			
		||||
            flat: null,
 | 
			
		||||
            buildingName: null,
 | 
			
		||||
            extra: null,
 | 
			
		||||
            distribution: null,
 | 
			
		||||
         },
 | 
			
		||||
         errorMsg: {}
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   computed: {
 | 
			
		||||
      isNoAddress: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.isNoAddress = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.isNoAddress;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   methods: {
 | 
			
		||||
      openModal() {
 | 
			
		||||
         this.modal.showModal = true;
 | 
			
		||||
         this.resetAll();
 | 
			
		||||
         this.getCountries();
 | 
			
		||||
         
 | 
			
		||||
         //this.$nextTick(function() {
 | 
			
		||||
         //   this.$refs.search.focus(); // positionner le curseur à l'ouverture de la modale
 | 
			
		||||
         //})
 | 
			
		||||
      },
 | 
			
		||||
      getCountries() {
 | 
			
		||||
         console.log('getCountries');
 | 
			
		||||
         this.address.loaded.countries = fetchCountries(); // à remplacer par
 | 
			
		||||
         //  fetchCountries().then(countries => new Promise((resolve, reject) => {
 | 
			
		||||
         //     this.address.loaded.countries = countries;
 | 
			
		||||
         //     resolve()
 | 
			
		||||
         //  }))
 | 
			
		||||
         //  .catch((error) => { 
 | 
			
		||||
         //     this.errorMsg.push(error.message); 
 | 
			
		||||
         //  }); 
 | 
			
		||||
      },
 | 
			
		||||
      getCities(country) {
 | 
			
		||||
         console.log('getCities for', country.name);
 | 
			
		||||
         this.address.loaded.cities = fetchCities(); // à remplacer par
 | 
			
		||||
         //  fetchCities(country).then(cities => new Promise((resolve, reject) => {
 | 
			
		||||
         //     this.address.loaded.cities = cities;
 | 
			
		||||
         //     resolve()
 | 
			
		||||
         //  }))
 | 
			
		||||
         //  .catch((error) => { 
 | 
			
		||||
         //     this.errorMsg.push(error.message); 
 | 
			
		||||
         //  }); 
 | 
			
		||||
      },
 | 
			
		||||
      getReferenceAddresses(city) {
 | 
			
		||||
         console.log('getReferenceAddresses for', city.name);
 | 
			
		||||
         fetchReferenceAddresses(city)  // il me semble que le paramètre city va limiter le poids des adresses de références reçues
 | 
			
		||||
            .then(addresses => new Promise((resolve, reject) => {
 | 
			
		||||
               console.log('addresses', addresses);
 | 
			
		||||
               this.address.loaded.addresses = addresses.results;
 | 
			
		||||
               resolve();
 | 
			
		||||
            }))
 | 
			
		||||
            .catch((error) => { 
 | 
			
		||||
               this.errorMsg.push(error.message); 
 | 
			
		||||
            }); 
 | 
			
		||||
      },
 | 
			
		||||
      updateMapCenter(point) {
 | 
			
		||||
         console.log('point', point);
 | 
			
		||||
         this.address.addressMap.center[0] = point.coordinates[1];  // TODO use reverse()
 | 
			
		||||
         this.address.addressMap.center[1] = point.coordinates[0];
 | 
			
		||||
         this.$refs.addressMap.update(); // cast child methods
 | 
			
		||||
      },
 | 
			
		||||
      resetAll() {
 | 
			
		||||
         console.log('reset all selected');
 | 
			
		||||
         this.address.loaded.addresses = [];
 | 
			
		||||
         this.address.selected.address = {}; 
 | 
			
		||||
         this.address.loaded.cities = [];
 | 
			
		||||
         this.address.selected.city = {};
 | 
			
		||||
         this.address.selected.country = {};
 | 
			
		||||
         console.log('cities and addresses', this.address.loaded.cities, this.address.loaded.addresses);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div class="container">
 | 
			
		||||
      <div id='address_map' style='height:400px; width:400px;'></div>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
import L from 'leaflet';
 | 
			
		||||
import markerIconPng from 'leaflet/dist/images/marker-icon.png'
 | 
			
		||||
import 'leaflet/dist/leaflet.css';
 | 
			
		||||
 | 
			
		||||
let map;
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'AddressMap',
 | 
			
		||||
   props: ['address'],
 | 
			
		||||
   computed: {
 | 
			
		||||
      center() {
 | 
			
		||||
         return this.address.addressMap.center;
 | 
			
		||||
      },
 | 
			
		||||
   },
 | 
			
		||||
   methods:{
 | 
			
		||||
      init() {
 | 
			
		||||
         map = L.map('address_map').setView([48.8589, 2.3469], 12);
 | 
			
		||||
 | 
			
		||||
         L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
 | 
			
		||||
            attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
 | 
			
		||||
         }).addTo(map);
 | 
			
		||||
 | 
			
		||||
         const markerIcon = L.icon({
 | 
			
		||||
            iconUrl: markerIconPng,
 | 
			
		||||
         });
 | 
			
		||||
 | 
			
		||||
         L.marker([48.8589, 2.3469], {icon: markerIcon}).addTo(map);
 | 
			
		||||
 | 
			
		||||
      },
 | 
			
		||||
      update() {
 | 
			
		||||
         console.log('update map with : ', this.address.addressMap.center)
 | 
			
		||||
         map.setView(this.address.addressMap.center, 12);
 | 
			
		||||
      }
 | 
			
		||||
   },
 | 
			
		||||
   mounted(){
 | 
			
		||||
      this.init()
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,112 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div>
 | 
			
		||||
      <h4>{{ $t('fill_an_address') }}</h4>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="floor"
 | 
			
		||||
         :placeholder="$t('floor')"
 | 
			
		||||
         v-model="floor"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="corridor"
 | 
			
		||||
         :placeholder="$t('corridor')"
 | 
			
		||||
         v-model="corridor"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="steps"
 | 
			
		||||
         :placeholder="$t('steps')"
 | 
			
		||||
         v-model="steps"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="flat"
 | 
			
		||||
         :placeholder="$t('flat')"
 | 
			
		||||
         v-model="flat"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="buildingName"
 | 
			
		||||
         :placeholder="$t('buildingName')"
 | 
			
		||||
         v-model="buildingName"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="extra"
 | 
			
		||||
         :placeholder="$t('extra')"
 | 
			
		||||
         v-model="extra"/>
 | 
			
		||||
      <input 
 | 
			
		||||
         type="text"
 | 
			
		||||
         name="distribution"
 | 
			
		||||
         :placeholder="$t('distribution')"
 | 
			
		||||
         v-model="distribution"/>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
   name: "AddressMore",
 | 
			
		||||
   props: ['address'],
 | 
			
		||||
   computed: {
 | 
			
		||||
      floor: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.floor = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.floor;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      corridor: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.corridor = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.corridor;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      steps: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.steps = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.steps;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      flat: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.flat = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.flat;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      buildingName: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.buildingName = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.buildingName;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      extra: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.extra = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.extra;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
      distribution: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('value', value);
 | 
			
		||||
            this.address.distribution = value;
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.distribution;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div class="container">
 | 
			
		||||
      <select 
 | 
			
		||||
         v-model="selected">
 | 
			
		||||
         <option :value="{}" disabled selected>{{ $t('select_address') }}</option>
 | 
			
		||||
         <option 
 | 
			
		||||
            v-for="item in this.addresses" 
 | 
			
		||||
            v-bind:item="item" 
 | 
			
		||||
            v-bind:key="item.id" 
 | 
			
		||||
            v-bind:value="item">
 | 
			
		||||
            {{ item.street }}, {{ item.streetNumber }}
 | 
			
		||||
         </option>
 | 
			
		||||
      </select>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'AddressSelection',
 | 
			
		||||
   props: ['address', 'updateMapCenter'],
 | 
			
		||||
   computed: {
 | 
			
		||||
      addresses() { 
 | 
			
		||||
         return this.address.loaded.addresses; 
 | 
			
		||||
      },
 | 
			
		||||
      selected: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('selected value', value);
 | 
			
		||||
            this.address.selected.address = value;
 | 
			
		||||
            this.updateMapCenter(value.point);
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.selected.address;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div class="container">
 | 
			
		||||
      <select 
 | 
			
		||||
         v-model="selected">
 | 
			
		||||
         <option :value="{}" disabled selected>{{ $t('select_city') }}</option>
 | 
			
		||||
         <option 
 | 
			
		||||
            v-for="item in this.cities" 
 | 
			
		||||
            v-bind:item="item" 
 | 
			
		||||
            v-bind:key="item.id" 
 | 
			
		||||
            v-bind:value="item">
 | 
			
		||||
            {{ item.code }}-{{ item.name }}
 | 
			
		||||
         </option>
 | 
			
		||||
      </select>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'CitySelection',
 | 
			
		||||
   props: ['address', 'getReferenceAddresses'],
 | 
			
		||||
   computed: {
 | 
			
		||||
      cities() { 
 | 
			
		||||
         return this.address.loaded.cities; 
 | 
			
		||||
      },
 | 
			
		||||
      selected: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('selected value', value.name);
 | 
			
		||||
            this.address.selected.city = value;
 | 
			
		||||
            this.getReferenceAddresses(value);
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.selected.city;
 | 
			
		||||
         }
 | 
			
		||||
      },
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <div class="container">
 | 
			
		||||
      <select 
 | 
			
		||||
         v-model="selected">
 | 
			
		||||
         <option :value="{}" disabled selected>{{ $t('select_country') }}</option>
 | 
			
		||||
         <option 
 | 
			
		||||
            v-for="item in this.countries" 
 | 
			
		||||
            v-bind:item="item" 
 | 
			
		||||
            v-bind:key="item.id" 
 | 
			
		||||
            v-bind:value="item">
 | 
			
		||||
            {{ item.name }}
 | 
			
		||||
         </option>
 | 
			
		||||
      </select>
 | 
			
		||||
   </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'CountrySelection',
 | 
			
		||||
   props: ['address', 'getCities'],
 | 
			
		||||
   computed: {
 | 
			
		||||
      countries() { 
 | 
			
		||||
         return this.address.loaded.countries; 
 | 
			
		||||
      },
 | 
			
		||||
      selected: {
 | 
			
		||||
         set(value) {
 | 
			
		||||
            console.log('selected value', value.name);
 | 
			
		||||
            this.address.selected.country = value;
 | 
			
		||||
            this.getCities(value);
 | 
			
		||||
         },
 | 
			
		||||
         get() {
 | 
			
		||||
            return this.address.selected.country;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,40 +1,41 @@
 | 
			
		||||
<template>
 | 
			
		||||
   <transition name="modal">
 | 
			
		||||
      <div class="modal-mask">
 | 
			
		||||
         <!-- :: styles bootstrap :: -->
 | 
			
		||||
         <div class="modal-dialog" :class="modalDialogClass">
 | 
			
		||||
            <div class="modal-content">
 | 
			
		||||
               <div class="modal-header">
 | 
			
		||||
                  <slot name="header"></slot>
 | 
			
		||||
                  <button class="close sc-button grey" @click="$emit('close')">
 | 
			
		||||
                     <i class="fa fa-times" aria-hidden="true"></i></button>
 | 
			
		||||
               </div>
 | 
			
		||||
               <div class="body-head">
 | 
			
		||||
                  <slot name="body-head"></slot>
 | 
			
		||||
               </div>
 | 
			
		||||
               <div class="modal-body">
 | 
			
		||||
                  <slot name="body"></slot>
 | 
			
		||||
               </div>
 | 
			
		||||
               <div class="modal-footer">
 | 
			
		||||
                  <button class="sc-button cancel" @click="$emit('close')">{{ $t('action.close') }}</button>
 | 
			
		||||
                  <slot name="footer"></slot>
 | 
			
		||||
               </div>
 | 
			
		||||
<transition name="modal">
 | 
			
		||||
   <div class="modal-mask">
 | 
			
		||||
      <!-- :: styles bootstrap :: -->
 | 
			
		||||
      <div class="modal-dialog" :class="modalDialogClass">
 | 
			
		||||
         <div class="modal-content">
 | 
			
		||||
            <div class="modal-header">
 | 
			
		||||
               <slot name="header"></slot>
 | 
			
		||||
               <button class="close sc-button grey" @click="$emit('close')">
 | 
			
		||||
                  <i class="fa fa-times" aria-hidden="true"></i></button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body up" style="overflow-y: unset;">
 | 
			
		||||
               <slot name="body-fixed"></slot>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body">
 | 
			
		||||
               <slot name="body"></slot>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-footer">
 | 
			
		||||
               <button class="sc-button cancel" @click="$emit('close')">{{ $t('action.close') }}</button>
 | 
			
		||||
               <slot name="footer"></slot>
 | 
			
		||||
            </div>
 | 
			
		||||
         </div>
 | 
			
		||||
         <!-- :: end styles bootstrap :: -->
 | 
			
		||||
      </div>
 | 
			
		||||
   </transition>
 | 
			
		||||
      <!-- :: end styles bootstrap :: -->
 | 
			
		||||
   </div>
 | 
			
		||||
</transition>
 | 
			
		||||
</template> 
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
/*
 | 
			
		||||
 *    This Modal component is a mix between Vue3 modal implementation 
 | 
			
		||||
 *    [+] with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
 | 
			
		||||
 *    [+] with slot we can pass content from parent component
 | 
			
		||||
 *    [+] some classes are passed from parent component
 | 
			
		||||
 *    and Bootstrap 4.6 _modal.scss module
 | 
			
		||||
 *    [+] using bootstrap css classes, the modal have a responsive behaviour, 
 | 
			
		||||
 *    [+] modal design can be configured using css classes (size, scroll)
 | 
			
		||||
 *    This Modal component is a mix between :
 | 
			
		||||
 *    - Vue3 modal implementation 
 | 
			
		||||
 *      => with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
 | 
			
		||||
 *      => with slot we can pass content from parent component
 | 
			
		||||
 *      => some classes are passed from parent component
 | 
			
		||||
 *    - Bootstrap 4.6 _modal.scss module
 | 
			
		||||
 *      => using bootstrap css classes, the modal have a responsive behaviour, 
 | 
			
		||||
 *      => modal design can be configured using css classes (size, scroll)
 | 
			
		||||
 */
 | 
			
		||||
export default {
 | 
			
		||||
   name: 'Modal',
 | 
			
		||||
@@ -42,39 +43,3 @@ export default {
 | 
			
		||||
   emits: ['close']
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
   .modal-mask {
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      z-index: 9998;
 | 
			
		||||
      top: 0;
 | 
			
		||||
      left: 0;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      background-color: rgba(0, 0, 0, 0.75);
 | 
			
		||||
      display: table;
 | 
			
		||||
      transition: opacity 0.3s ease;
 | 
			
		||||
   }
 | 
			
		||||
   .modal-header .close { // bootstrap classes, override sc-button 0 radius
 | 
			
		||||
      border-top-right-radius: 0.3rem;
 | 
			
		||||
   }
 | 
			
		||||
   /*
 | 
			
		||||
   * The following styles are auto-applied to elements with
 | 
			
		||||
   * transition="modal" when their visibility is toggled
 | 
			
		||||
   * by Vue.js.
 | 
			
		||||
   *
 | 
			
		||||
   * You can easily play with the modal transition by editing
 | 
			
		||||
   * these styles.
 | 
			
		||||
   */
 | 
			
		||||
   .modal-enter {
 | 
			
		||||
      opacity: 0;
 | 
			
		||||
   }
 | 
			
		||||
   .modal-leave-active {
 | 
			
		||||
      opacity: 0;
 | 
			
		||||
   }
 | 
			
		||||
   .modal-enter .modal-container,
 | 
			
		||||
   .modal-leave-active .modal-container {
 | 
			
		||||
      -webkit-transform: scale(1.1);
 | 
			
		||||
      transform: scale(1.1);
 | 
			
		||||
   }
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,15 +7,11 @@ const datetimeFormats = {
 | 
			
		||||
         month: "numeric",
 | 
			
		||||
         day: "numeric"
 | 
			
		||||
      },
 | 
			
		||||
      text: {
 | 
			
		||||
         year: "numeric",
 | 
			
		||||
         month: "long",
 | 
			
		||||
         day: "numeric",
 | 
			
		||||
      },
 | 
			
		||||
      long: {
 | 
			
		||||
         year: "numeric",
 | 
			
		||||
         month: "numeric",
 | 
			
		||||
         month: "short",
 | 
			
		||||
         day: "numeric",
 | 
			
		||||
         weekday: "short",
 | 
			
		||||
         hour: "numeric",
 | 
			
		||||
         minute: "numeric",
 | 
			
		||||
         hour12: false
 | 
			
		||||
@@ -37,16 +33,12 @@ const messages = {
 | 
			
		||||
         ok: "OK",
 | 
			
		||||
         cancel: "Annuler",
 | 
			
		||||
         close: "Fermer",
 | 
			
		||||
         next: "Suivant",
 | 
			
		||||
         previous: "Précédent",
 | 
			
		||||
         back: "Retour",
 | 
			
		||||
         check_all: "cocher tout",
 | 
			
		||||
         reset: "réinitialiser"
 | 
			
		||||
      },
 | 
			
		||||
      nav: {
 | 
			
		||||
         next: "Suivant",
 | 
			
		||||
         previous: "Précédent",
 | 
			
		||||
         top: "Haut",
 | 
			
		||||
         bottom: "Bas",
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<footer class="footer">
 | 
			
		||||
    <p>{{ 'This program is free software: you can redistribute it and/or modify it under the terms of the <strong>GNU Affero General Public License</strong>'|trans|raw }}
 | 
			
		||||
        <br/> <a name="bottom" href="https://{{ app.request.locale }}.wikibooks.org/wiki/Chill" target="_blank">{{ 'User manual'|trans }}</a></p>
 | 
			
		||||
</footer>
 | 
			
		||||
        <br/> <a href="https://{{ app.request.locale }}.wikibooks.org/wiki/Chill" target="_blank">{{ 'User manual'|trans }}</a></p>
 | 
			
		||||
</footer>
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
<img name="top" class="logo" src="{{ asset('build/images/logo-chill-sans-slogan_white.png') }}">
 | 
			
		||||
<img class="logo" src="{{ asset('build/images/logo-chill-sans-slogan_white.png') }}">
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Search\Model;
 | 
			
		||||
 | 
			
		||||
class Result
 | 
			
		||||
{
 | 
			
		||||
    private float $relevance;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * mixed an arbitrary result
 | 
			
		||||
     */
 | 
			
		||||
    private $result;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param float $relevance
 | 
			
		||||
     * @param $result
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(float $relevance, $result)
 | 
			
		||||
    {
 | 
			
		||||
        $this->relevance = $relevance;
 | 
			
		||||
        $this->result = $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getRelevance(): float
 | 
			
		||||
    {
 | 
			
		||||
        return $this->relevance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getResult()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Search;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Chill\MainBundle\Search\SearchProvider;
 | 
			
		||||
use Symfony\Component\VarDumper\Resources\functions\dump;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  ***Warning*** This is an incomplete implementation ***Warning***
 | 
			
		||||
 */
 | 
			
		||||
class SearchApi
 | 
			
		||||
{
 | 
			
		||||
    private EntityManagerInterface $em;
 | 
			
		||||
    private SearchProvider $search;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $em, SearchProvider $search)
 | 
			
		||||
    {
 | 
			
		||||
        $this->em = $em;
 | 
			
		||||
        $this->search = $search;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return Model/Result[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getResults(string $query, int $offset, int $maxResult): array
 | 
			
		||||
    {
 | 
			
		||||
        // **warning again**: this is an incomplete implementation 
 | 
			
		||||
        $results = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->getPersons($query) as $p) {
 | 
			
		||||
            $results[] = new Model\Result((float)\rand(0, 100) / 100, $p);
 | 
			
		||||
        }
 | 
			
		||||
        foreach ($this->getThirdParties($query) as $t) {
 | 
			
		||||
            $results[] = new Model\Result((float)\rand(0, 100) / 100, $t);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \usort($results, function(Model\Result $a, Model\Result $b) {
 | 
			
		||||
            return ($a->getRelevance() <=> $b->getRelevance()) * -1;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return $results;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function countResults(string $query): int
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getThirdParties(string $query)
 | 
			
		||||
    {
 | 
			
		||||
        $thirdPartiesIds = $this->em->createQuery('SELECT t.id FROM '.ThirdParty::class.' t')
 | 
			
		||||
            ->getScalarResult();
 | 
			
		||||
        $nbResults = rand(0, 15);
 | 
			
		||||
 | 
			
		||||
        if ($nbResults === 1) {
 | 
			
		||||
            $nbResults++;
 | 
			
		||||
        } elseif ($nbResults === 0) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
        $ids = \array_map(function ($e) use ($thirdPartiesIds) { return $thirdPartiesIds[$e]['id'];}, 
 | 
			
		||||
            \array_rand($thirdPartiesIds, $nbResults));
 | 
			
		||||
 | 
			
		||||
        $a = $this->em->getRepository(ThirdParty::class)
 | 
			
		||||
            ->findById($ids);
 | 
			
		||||
        return $a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getPersons(string $query)
 | 
			
		||||
    {
 | 
			
		||||
        $params = [
 | 
			
		||||
            SearchInterface::SEARCH_PREVIEW_OPTION => false
 | 
			
		||||
            ];
 | 
			
		||||
        $search = $this->search->getResultByName($query, 'person_regular', 0, 50, $params, 'json');
 | 
			
		||||
        $ids = \array_map(function($r) { return $r['id']; }, $search['results']);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (count($ids) === 0) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->em->getRepository(Person::class)
 | 
			
		||||
            ->findById($ids)
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\Address;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 | 
			
		||||
 | 
			
		||||
class AddressNormalizer implements NormalizerAwareInterface, NormalizerInterface
 | 
			
		||||
{
 | 
			
		||||
    use NormalizerAwareTrait;
 | 
			
		||||
 | 
			
		||||
    public function normalize($address, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        $data['address_id'] = $address->getId();
 | 
			
		||||
        $data['text'] = $address->getStreet().', '.$address->getBuildingName();
 | 
			
		||||
        $data['postcode']['name'] = $address->getPostCode()->getName();
 | 
			
		||||
 | 
			
		||||
        return $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function supportsNormalization($data, string $format = null)
 | 
			
		||||
    {
 | 
			
		||||
        return $data instanceof Address;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -20,32 +20,19 @@
 | 
			
		||||
namespace Chill\MainBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\Center;
 | 
			
		||||
use Chill\MainBundle\Repository\CenterRepository;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
 | 
			
		||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class CenterNormalizer implements NormalizerInterface, DenormalizerInterface
 | 
			
		||||
class CenterNormalizer implements NormalizerInterface
 | 
			
		||||
{
 | 
			
		||||
    private CenterRepository $repository;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function __construct(CenterRepository $repository)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $repository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function normalize($center, string $format = null, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        /** @var Center $center */
 | 
			
		||||
        return [
 | 
			
		||||
            'id' => $center->getId(),
 | 
			
		||||
            'type' => 'center',
 | 
			
		||||
            'name' => $center->getName()
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
@@ -54,30 +41,4 @@ class CenterNormalizer implements NormalizerInterface, DenormalizerInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $data instanceof Center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function denormalize($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        if (FALSE === \array_key_exists('type', $data)) {
 | 
			
		||||
            throw new InvalidArgumentException('missing "type" key in data');
 | 
			
		||||
        }
 | 
			
		||||
        if ('center' !== $data['type']) {
 | 
			
		||||
            throw new InvalidArgumentException('type should be equal to "center"');
 | 
			
		||||
        }
 | 
			
		||||
        if (FALSE === \array_key_exists('id', $data)) {
 | 
			
		||||
            throw new InvalidArgumentException('missing "id" key in data');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $center = $this->repository->find($data['id']);
 | 
			
		||||
 | 
			
		||||
        if (null === $center) {
 | 
			
		||||
            throw new UnexpectedValueException("The type with id {$data['id']} does not exists");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function supportsDenormalization($data, string $type, string $format = null)
 | 
			
		||||
    {
 | 
			
		||||
        return $type === Center::class;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,16 +20,15 @@
 | 
			
		||||
namespace Chill\MainBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
 | 
			
		||||
 | 
			
		||||
class DateNormalizer implements NormalizerInterface, DenormalizerInterface
 | 
			
		||||
class DateNormalizer implements NormalizerInterface
 | 
			
		||||
{
 | 
			
		||||
    public function normalize($date, string $format = null, array $context = array())
 | 
			
		||||
    {
 | 
			
		||||
        /** @var \DateTimeInterface $date */
 | 
			
		||||
        return [
 | 
			
		||||
            'datetime' => $date->format(\DateTimeInterface::ISO8601)
 | 
			
		||||
            'datetime' => $date->format(\DateTimeInterface::ISO8601),
 | 
			
		||||
            'u' => $date->getTimestamp()
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -37,24 +36,4 @@ class DateNormalizer implements NormalizerInterface, DenormalizerInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $data instanceof \DateTimeInterface;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function denormalize($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        switch ($type) {
 | 
			
		||||
            case \DateTime::class:
 | 
			
		||||
                return \DateTime::createFromFormat(\DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
            case \DateTimeInterface::class:
 | 
			
		||||
            case \DateTimeImmutable::class:
 | 
			
		||||
            default:
 | 
			
		||||
                return \DateTimeImmutable::createFromFormat(\DateTimeInterface::ISO8601, $data['datetime']);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function supportsDenormalization($data, string $type, string $format = null): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $type === \DateTimeInterface::class ||
 | 
			
		||||
            $type === \DateTime::class ||
 | 
			
		||||
            $type === \DateTimeImmutable::class ||
 | 
			
		||||
            (\is_array($data) && array_key_exists('datetime', $data));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
 | 
			
		||||
use Symfony\Component\Serializer\Exception\RuntimeException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Denormalize an object given a list of supported class
 | 
			
		||||
 */
 | 
			
		||||
class DiscriminatedObjectDenormalizer implements ContextAwareDenormalizerInterface, DenormalizerAwareInterface
 | 
			
		||||
{
 | 
			
		||||
    use DenormalizerAwareTrait;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The type to set for enabling this type
 | 
			
		||||
     */
 | 
			
		||||
    public const TYPE = '@multi';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Should be present in context and contains an array of
 | 
			
		||||
     * allowed types. 
 | 
			
		||||
     */
 | 
			
		||||
    public const ALLOWED_TYPES = 'denormalize_multi.allowed_types';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    public function denormalize($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($context[self::ALLOWED_TYPES] as $localType) {
 | 
			
		||||
            if ($this->denormalizer->supportsDenormalization($data, $localType, $format)) {
 | 
			
		||||
                try {
 | 
			
		||||
                    return $this->denormalizer->denormalize($data, $localType, $format, $context);               } catch (RuntimeException $e) {
 | 
			
		||||
                    $lastException = $e;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new RuntimeException(sprintf("Could not find any denormalizer for those ".
 | 
			
		||||
            "ALLOWED_TYPES: %s", \implode(", ", $context[self::ALLOWED_TYPES])));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    public function supportsDenormalization($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        if (self::TYPE !== $type) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (0 === count($context[self::ALLOWED_TYPES] ?? [])) {
 | 
			
		||||
            throw new \LogicException("The context should contains a list of 
 | 
			
		||||
                allowed types");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($context[self::ALLOWED_TYPES] as $localType) {
 | 
			
		||||
            if ($this->denormalizer->supportsDenormalization($data, $localType, $format)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
 | 
			
		||||
use Doctrine\ORM\Mapping\ClassMetadata;
 | 
			
		||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface as SerializerMetadata;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DoctrineExistingEntityNormalizer implements DenormalizerInterface
 | 
			
		||||
{
 | 
			
		||||
    private EntityManagerInterface $em;
 | 
			
		||||
 | 
			
		||||
    private ClassMetadataFactoryInterface $serializerMetadataFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $em, ClassMetadataFactoryInterface $serializerMetadataFactory)
 | 
			
		||||
    {
 | 
			
		||||
        $this->em = $em;
 | 
			
		||||
        $this->serializerMetadataFactory = $serializerMetadataFactory;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function denormalize($data, string $type, string $format = null, array $context = [])
 | 
			
		||||
    {
 | 
			
		||||
        if (\array_key_exists(AbstractNormalizer::OBJECT_TO_POPULATE, $context)) {
 | 
			
		||||
            return $context[AbstractNormalizer::OBJECT_TO_POPULATE];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->em->getRepository($type)
 | 
			
		||||
            ->find($data['id']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function supportsDenormalization($data, string $type, string $format = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (FALSE === \is_array($data)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (FALSE === \array_key_exists('id', $data)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        if (FALSE === $this->em->getClassMetadata($type) instanceof ClassMetadata) {
 | 
			
		||||
            return false; 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // does have serializer metadata, and class discriminator ?
 | 
			
		||||
        if ($this->serializerMetadataFactory->hasMetadataFor($type)) {
 | 
			
		||||
 | 
			
		||||
            $classDiscriminator = $this->serializerMetadataFactory
 | 
			
		||||
                ->getMetadataFor($type)->getClassDiscriminatorMapping();
 | 
			
		||||
 | 
			
		||||
            if ($classDiscriminator) {
 | 
			
		||||
                $typeProperty = $classDiscriminator->getTypeProperty();
 | 
			
		||||
 | 
			
		||||
                // check that only 2 keys
 | 
			
		||||
                // that the second key is property
 | 
			
		||||
                // and that the type match the class for given type property 
 | 
			
		||||
                return count($data) === 2
 | 
			
		||||
                    && \array_key_exists($typeProperty, $data) 
 | 
			
		||||
                    && $type === $classDiscriminator->getClassForType($data[$typeProperty]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // we do not have any class discriminator. Check that the id is the only one key
 | 
			
		||||
        return count($data) === 1;
 | 
			
		||||
    }
 | 
			
		||||
}    
 | 
			
		||||
@@ -24,7 +24,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @internal we keep this normalizer, because the property 'text' may be replace by a rendering in the future
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class UserNormalizer implements NormalizerInterface
 | 
			
		||||
{
 | 
			
		||||
@@ -32,10 +32,8 @@ class UserNormalizer implements NormalizerInterface
 | 
			
		||||
    {
 | 
			
		||||
        /** @var User $user */
 | 
			
		||||
        return [
 | 
			
		||||
            'type' => 'user',
 | 
			
		||||
            'id' => $user->getId(),
 | 
			
		||||
            'username' => $user->getUsername(),
 | 
			
		||||
            'text' => $user->getUsername()
 | 
			
		||||
            'username' => $user->getUsername()
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -172,7 +172,6 @@ abstract class AbstractExportTest extends WebTestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testInitiateQuery($modifiers, $acl, $data)
 | 
			
		||||
    {
 | 
			
		||||
        var_dump($data);
 | 
			
		||||
        $query = $this->getExport()->initiateQuery($modifiers, $acl, $data);
 | 
			
		||||
        
 | 
			
		||||
        $this->assertTrue($query instanceof QueryBuilder || $query instanceof NativeQuery,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Tests\Serializer\Normalizer;
 | 
			
		||||
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
 | 
			
		||||
use Chill\MainBundle\Serializer\Normalizer\DoctrineExistingEntityNormalizer;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DoctrineExistingEntityNormalizerTest extends KernelTestCase
 | 
			
		||||
{
 | 
			
		||||
    protected DoctrineExistingEntityNormalizer $normalizer;
 | 
			
		||||
 | 
			
		||||
    protected function setUp()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
        $em = self::$container->get(EntityManagerInterface::class); 
 | 
			
		||||
        $serializerFactory = self::$container->get(ClassMetadataFactoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        $this->normalizer = new DoctrineExistingEntityNormalizer($em, $serializerFactory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider dataProviderUserId
 | 
			
		||||
     */
 | 
			
		||||
    public function testGetMappedClass($userId)
 | 
			
		||||
    {
 | 
			
		||||
        $data = [ 'type' => 'user', 'id' => $userId]; 
 | 
			
		||||
        $supports = $this->normalizer->supportsDenormalization($data, User::class);
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue($supports);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function dataProviderUserId()
 | 
			
		||||
    {
 | 
			
		||||
        self::bootKernel();
 | 
			
		||||
 | 
			
		||||
        $userIds = self::$container->get(EntityManagerInterface::class)
 | 
			
		||||
            ->getRepository(User::class)
 | 
			
		||||
            ->createQueryBuilder('u')
 | 
			
		||||
            ->select('u.id')
 | 
			
		||||
            ->setMaxResults(1)
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getResult()
 | 
			
		||||
            ;
 | 
			
		||||
 | 
			
		||||
        yield [ $userIds[0]['id'] ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
openapi: "3.0.0"
 | 
			
		||||
info:
 | 
			
		||||
  version: "1.0.0"
 | 
			
		||||
  title: "Chill api"
 | 
			
		||||
  description: "Api documentation for chill. Currently, work in progress"
 | 
			
		||||
servers:
 | 
			
		||||
  - url: "/api"
 | 
			
		||||
    description: "Your current dev server"
 | 
			
		||||
 | 
			
		||||
components:
 | 
			
		||||
  schemas:
 | 
			
		||||
    Center:
 | 
			
		||||
      type: object
 | 
			
		||||
      properties:
 | 
			
		||||
        id:
 | 
			
		||||
          type: integer
 | 
			
		||||
        name:
 | 
			
		||||
          type: string
 | 
			
		||||
 | 
			
		||||
paths:
 | 
			
		||||
  /1.0/search.json:
 | 
			
		||||
    get:
 | 
			
		||||
      summary: perform a search across multiple entities
 | 
			
		||||
      tags:
 | 
			
		||||
        - search
 | 
			
		||||
        - person
 | 
			
		||||
        - thirdparty
 | 
			
		||||
      description: >
 | 
			
		||||
        **Warning**: This is currently a stub (not really implemented
 | 
			
		||||
 | 
			
		||||
        The search is performed across multiple entities. The entities must be listed into 
 | 
			
		||||
        `type` parameters.
 | 
			
		||||
 | 
			
		||||
        The results are ordered by relevance, from the most to the lowest relevant.
 | 
			
		||||
 | 
			
		||||
      parameters:
 | 
			
		||||
        - name: q
 | 
			
		||||
          in: query
 | 
			
		||||
          required: true
 | 
			
		||||
          description: the pattern to search
 | 
			
		||||
          schema:
 | 
			
		||||
            type: string
 | 
			
		||||
        - name: type[]
 | 
			
		||||
          in: query
 | 
			
		||||
          required: true
 | 
			
		||||
          description: the type entities amongst the search is performed
 | 
			
		||||
          schema:
 | 
			
		||||
            type: array
 | 
			
		||||
            items:
 | 
			
		||||
              type: string
 | 
			
		||||
              enum:
 | 
			
		||||
                - person
 | 
			
		||||
                - thirdparty
 | 
			
		||||
      responses:
 | 
			
		||||
        200:
 | 
			
		||||
          description: "OK"
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +62,5 @@ module.exports = function(encore, entries)
 | 
			
		||||
    buildCKEditor(encore);
 | 
			
		||||
    encore.addEntry('ckeditor5', __dirname + '/Resources/public/modules/ckeditor5/index.js');
 | 
			
		||||
 | 
			
		||||
    // Address
 | 
			
		||||
    encore.addEntry('address', __dirname + '/Resources/public/vuejs/Address/index.js');
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -69,13 +69,6 @@ chill_main_search:
 | 
			
		||||
    requirements:
 | 
			
		||||
        _format: html|json
 | 
			
		||||
 | 
			
		||||
chill_main_search_global:
 | 
			
		||||
    path: '/api/1.0/search.{_format}'
 | 
			
		||||
    controller: Chill\MainBundle\Controller\SearchController::searchApi
 | 
			
		||||
    format: 'json'
 | 
			
		||||
    requirements:
 | 
			
		||||
        _format: 'json'
 | 
			
		||||
 | 
			
		||||
chill_main_advanced_search:
 | 
			
		||||
    path: /{_locale}/search/advanced/{name}
 | 
			
		||||
    controller: Chill\MainBundle\Controller\SearchController::advancedSearchAction
 | 
			
		||||
 
 | 
			
		||||
@@ -3,18 +3,6 @@ parameters:
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\:
 | 
			
		||||
        resource: '../Serializer/Normalizer'
 | 
			
		||||
        autowire: true
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 64 }
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Doctrine\Event\:
 | 
			
		||||
        resource: '../Doctrine/Event/'
 | 
			
		||||
        autowire: true
 | 
			
		||||
        tags: 
 | 
			
		||||
            - { name: 'doctrine.event_subscriber' }
 | 
			
		||||
 | 
			
		||||
    chill.main.helper.translatable_string:
 | 
			
		||||
        class: Chill\MainBundle\Templating\TranslatableStringHelper
 | 
			
		||||
        arguments:
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ services:
 | 
			
		||||
            $searchProvider: '@chill_main.search_provider'
 | 
			
		||||
            $translator: '@Symfony\Contracts\Translation\TranslatorInterface'
 | 
			
		||||
            $paginatorFactory: '@Chill\MainBundle\Pagination\PaginatorFactory'
 | 
			
		||||
            $searchApi: '@Chill\MainBundle\Search\SearchApi'
 | 
			
		||||
        tags: ['controller.service_arguments']
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Controller\PermissionsGroupController:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,3 @@
 | 
			
		||||
services:
 | 
			
		||||
    chill_main.search_provider:
 | 
			
		||||
        class: Chill\MainBundle\Search\SearchProvider
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Search\SearchProvider: '@chill_main.search_provider'
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Search\SearchApi:
 | 
			
		||||
        arguments:
 | 
			
		||||
          $em: '@Doctrine\ORM\EntityManagerInterface'
 | 
			
		||||
          $search: '@Chill\MainBundle\Search\SearchProvider'
 | 
			
		||||
        class: Chill\MainBundle\Search\SearchProvider
 | 
			
		||||
@@ -1,11 +1,17 @@
 | 
			
		||||
---
 | 
			
		||||
services:
 | 
			
		||||
    
 | 
			
		||||
    # note: the autowiring for serializers and normalizers is declared 
 | 
			
		||||
    # into ../services.yaml
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\DoctrineExistingEntityNormalizer:
 | 
			
		||||
        autowire: true
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\CenterNormalizer:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 8 }
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 64 }
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\DateNormalizer:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 64 }
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\UserNormalizer:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 64 }
 | 
			
		||||
 | 
			
		||||
    Chill\MainBundle\Serializer\Normalizer\CollectionNormalizer:
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: 'serializer.normalizer', priority: 64 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\Migrations\Main;
 | 
			
		||||
 | 
			
		||||
use Doctrine\DBAL\Schema\Schema;
 | 
			
		||||
use Doctrine\Migrations\AbstractMigration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Specify ON DELETE behaviour to handle deletion of parents in associated tables
 | 
			
		||||
 */
 | 
			
		||||
final class Version20210525144016 extends AbstractMigration
 | 
			
		||||
{
 | 
			
		||||
    public function getDescription(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'Specify ON DELETE behaviour to handle deletion of parents in associated tables';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function up(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT FK_165051F6114B8DD9');
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F6114B8DD9 FOREIGN KEY (linkedToThirdParty_id) REFERENCES chill_3party.third_party (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function down(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT fk_165051f6114b8dd9');
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT fk_165051f6114b8dd9 FOREIGN KEY (linkedtothirdparty_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -5,19 +5,13 @@ namespace Chill\PersonBundle\Controller;
 | 
			
		||||
use Chill\MainBundle\CRUD\Controller\ApiController;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Symfony\Component\Serializer\Exception\RuntimeException;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
 | 
			
		||||
use Chill\MainBundle\Entity\Scope;
 | 
			
		||||
use Symfony\Component\Workflow\Registry;
 | 
			
		||||
 | 
			
		||||
class AccompanyingCourseApiController extends ApiController
 | 
			
		||||
{
 | 
			
		||||
@@ -25,37 +19,10 @@ class AccompanyingCourseApiController extends ApiController
 | 
			
		||||
 | 
			
		||||
    protected ValidatorInterface $validator;
 | 
			
		||||
 | 
			
		||||
    private Registry $registry;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        ValidatorInterface $validator,
 | 
			
		||||
        Registry $registry
 | 
			
		||||
    ) {
 | 
			
		||||
    public function __construct(EventDispatcherInterface $eventDispatcher, $validator)
 | 
			
		||||
    {
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
        $this->validator = $validator;
 | 
			
		||||
        $this->registry = $registry;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function confirmApi($id, Request $request, $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        /** @var AccompanyingPeriod $accompanyingPeriod */ 
 | 
			
		||||
        $accompanyingPeriod = $this->getEntity('participation', $id, $request);
 | 
			
		||||
 | 
			
		||||
        $this->checkACL('confirm', $request, $_format, $accompanyingPeriod);
 | 
			
		||||
$workflow = $this->registry->get($accompanyingPeriod);
 | 
			
		||||
 | 
			
		||||
        if (FALSE === $workflow->can($accompanyingPeriod, 'confirm')) {
 | 
			
		||||
            throw new BadRequestException('It is not possible to confirm this period');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $workflow->apply($accompanyingPeriod, 'confirm');
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        return $this->json($accompanyingPeriod, Response::HTTP_OK, [], [
 | 
			
		||||
            'groups' => [ 'read' ]
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function participationApi($id, Request $request, $_format)
 | 
			
		||||
@@ -75,10 +42,11 @@ $workflow = $this->registry->get($accompanyingPeriod);
 | 
			
		||||
 | 
			
		||||
        switch ($request->getMethod()) {
 | 
			
		||||
            case Request::METHOD_POST:
 | 
			
		||||
                $participation = $accompanyingPeriod->createParticipationFor($person);
 | 
			
		||||
                $participation = $accompanyingPeriod->addPerson($person);
 | 
			
		||||
                break;
 | 
			
		||||
            case Request::METHOD_DELETE:
 | 
			
		||||
                $participation = $accompanyingPeriod->closeParticipationFor($person);
 | 
			
		||||
                $participation = $accompanyingPeriod->removePerson($person);
 | 
			
		||||
                $participation->setEndDate(new \DateTimeImmutable('now'));
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException("This method is not supported");
 | 
			
		||||
@@ -88,76 +56,12 @@ $workflow = $this->registry->get($accompanyingPeriod);
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            // only format accepted
 | 
			
		||||
            return $this->json($errors, 422);
 | 
			
		||||
            return $this->json($errors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        return $this->json($participation, 200, [], ['groups' => [ 'read' ]]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function resourceApi($id, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function scopeApi($id, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, [ 'groups' => [ 'read' ] ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function commentApi($id, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function socialIssueApi($id, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function requestorApi($id, Request $request, string $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        /** @var AccompanyingPeriod $accompanyingPeriod */
 | 
			
		||||
        $action = 'requestor';
 | 
			
		||||
        $accompanyingPeriod = $this->getEntity($action, $id, $request);
 | 
			
		||||
        // a requestor may be a person or a thirdParty
 | 
			
		||||
 | 
			
		||||
        $this->checkACL($action, $request, $_format, $accompanyingPeriod);
 | 
			
		||||
        $this->onPostCheckACL($action, $request, $_format, $accompanyingPeriod);
 | 
			
		||||
 | 
			
		||||
        if (Request::METHOD_DELETE === $request->getMethod()) {
 | 
			
		||||
            $accompanyingPeriod->setRequestor(NULL);
 | 
			
		||||
        } elseif (Request::METHOD_POST === $request->getMethod()) {
 | 
			
		||||
            $requestor = null;
 | 
			
		||||
            $exceptions = [];
 | 
			
		||||
            foreach ([Person::class, ThirdParty::class] as $class) {
 | 
			
		||||
                try {
 | 
			
		||||
                    $requestor = $this->getSerializer()
 | 
			
		||||
                        ->deserialize($request->getContent(), $class, $_format, []);
 | 
			
		||||
                } catch (RuntimeException $e) {
 | 
			
		||||
                    $exceptions[] = $e;
 | 
			
		||||
                } 
 | 
			
		||||
            }
 | 
			
		||||
            if ($requestor === null) {
 | 
			
		||||
                throw new BadRequestException('Could not find any person or requestor', 0, $exceptions[0]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $accompanyingPeriod->setRequestor($requestor);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new BadRequestException('method not supported');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $errors = $this->validator->validate($accompanyingPeriod);
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            // only format accepted
 | 
			
		||||
            return $this->json($errors, 422);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        return $this->json($accompanyingPeriod->getRequestor(), 200, [], ['groups' => [ 'read']]);
 | 
			
		||||
        return $this->json($participation);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
 | 
			
		||||
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
 | 
			
		||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 | 
			
		||||
use Symfony\Component\HttpFoundation\JsonResponse;
 | 
			
		||||
@@ -43,41 +42,6 @@ class AccompanyingCourseController extends Controller
 | 
			
		||||
        $this->dispatcher = $dispatcher;
 | 
			
		||||
        $this->validator = $validator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Route("/{_locale}/person/parcours/new", name="chill_person_accompanying_course_new")
 | 
			
		||||
     */
 | 
			
		||||
    public function newAction(Request $request): Response
 | 
			
		||||
    {
 | 
			
		||||
        $period = new AccompanyingPeriod();
 | 
			
		||||
        $em = $this->getDoctrine()->getManager();
 | 
			
		||||
 | 
			
		||||
        if ($request->query->has('person_id')) {
 | 
			
		||||
            $personIds = $request->query->get('person_id');
 | 
			
		||||
 | 
			
		||||
            if (FALSE === \is_array($personIds)) {
 | 
			
		||||
                throw new BadRequestException("person_id parameter should be an array");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach ($personIds as $personId) {
 | 
			
		||||
                $person = $em->getRepository(Person::class)->find($personId);
 | 
			
		||||
                if (NULL !== $person) {
 | 
			
		||||
                    $period->addPerson($person);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $period);
 | 
			
		||||
 | 
			
		||||
        $em->persist($period);
 | 
			
		||||
        $em->flush();
 | 
			
		||||
 | 
			
		||||
        return $this->redirectToRoute('chill_person_accompanying_course_show', [
 | 
			
		||||
            'accompanying_period_id' => $period->getId()
 | 
			
		||||
        ]);
 | 
			
		||||
         
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Homepage of Accompanying Course section
 | 
			
		||||
     *
 | 
			
		||||
@@ -122,4 +86,78 @@ class AccompanyingCourseController extends Controller
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get API Data for showing endpoint
 | 
			
		||||
     *
 | 
			
		||||
     * @Route(
 | 
			
		||||
     *     "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/show.{_format}",
 | 
			
		||||
     *     name="chill_person_accompanying_course_api_show"
 | 
			
		||||
     * )
 | 
			
		||||
     * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
 | 
			
		||||
     */
 | 
			
		||||
    public function showAPI(AccompanyingPeriod $accompanyingCourse, $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        // TODO check ACL on AccompanyingPeriod
 | 
			
		||||
 | 
			
		||||
        $this->dispatcher->dispatch(
 | 
			
		||||
            AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
 | 
			
		||||
            new AccompanyingPeriodPrivacyEvent($accompanyingCourse, [
 | 
			
		||||
            'action' => 'showApi'
 | 
			
		||||
            ])
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        switch ($_format) {
 | 
			
		||||
            case 'json':
 | 
			
		||||
                return $this->json($accompanyingCourse);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException('Unsupported format');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get API Data for showing endpoint
 | 
			
		||||
     *
 | 
			
		||||
     * @Route(
 | 
			
		||||
     *     "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}",
 | 
			
		||||
     *     name="chill_person_accompanying_course_api_add_participation",
 | 
			
		||||
     *     methods={"POST","DELETE"},
 | 
			
		||||
     *     format="json",
 | 
			
		||||
     *     requirements={
 | 
			
		||||
     *         "_format": "json",
 | 
			
		||||
     *     }
 | 
			
		||||
     * )
 | 
			
		||||
     * @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
 | 
			
		||||
     */
 | 
			
		||||
    public function participationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
 | 
			
		||||
    {
 | 
			
		||||
        switch ($_format) {
 | 
			
		||||
            case 'json':
 | 
			
		||||
                $person = $this->serializer->deserialize($request->getContent(), Person::class, $_format, [
 | 
			
		||||
 | 
			
		||||
                ]);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException('Unsupported format');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (NULL === $person) {
 | 
			
		||||
            throw new BadRequestException('person id not found');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO add acl
 | 
			
		||||
        $participation = ($request->getMethod() === 'POST') ?
 | 
			
		||||
            $accompanyingCourse->addPerson($person) : $accompanyingCourse->removePerson($person);
 | 
			
		||||
 | 
			
		||||
        $errors = $this->validator->validate($accompanyingCourse);
 | 
			
		||||
 | 
			
		||||
        if ($errors->count() > 0) {
 | 
			
		||||
            // only format accepted
 | 
			
		||||
            return $this->json($errors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->getDoctrine()->getManager()->flush();
 | 
			
		||||
 | 
			
		||||
        return $this->json($participation);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
<?php
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015-2021 Champs-Libres Coopérative <info@champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
namespace Chill\PersonBundle\Controller;
 | 
			
		||||
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 | 
			
		||||
use Symfony\Component\HttpFoundation\JsonResponse;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ApiPersonController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function viewAction($id, $_format) 
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,50 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015-2021 Champs-Libres Coopérative <info@champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
namespace Chill\PersonBundle\Controller;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
 | 
			
		||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
 | 
			
		||||
use Symfony\Component\Security\Core\Role\Role;
 | 
			
		||||
use Chill\MainBundle\CRUD\Controller\ApiController;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PersonApiController extends ApiController
 | 
			
		||||
{
 | 
			
		||||
    private AuthorizationHelper $authorizationHelper;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param AuthorizationHelper $authorizationHelper
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(AuthorizationHelper $authorizationHelper)
 | 
			
		||||
    {
 | 
			
		||||
        $this->authorizationHelper = $authorizationHelper;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function createEntity(string $action, Request $request): object
 | 
			
		||||
    {
 | 
			
		||||
        $person = parent::createEntity($action, $request);
 | 
			
		||||
 | 
			
		||||
        // TODO temporary hack to allow creation of person with fake center
 | 
			
		||||
        $centers = $this->authorizationHelper->getReachableCenters($this->getUser(),
 | 
			
		||||
            new Role(PersonVoter::CREATE));
 | 
			
		||||
        $person->setCenter($centers[0]);
 | 
			
		||||
 | 
			
		||||
        return $person;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -38,7 +38,6 @@ use Symfony\Component\Translation\TranslatorInterface;
 | 
			
		||||
use Chill\MainBundle\Search\SearchProvider;
 | 
			
		||||
use Chill\PersonBundle\Repository\PersonRepository;
 | 
			
		||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
 | 
			
		||||
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
 | 
			
		||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
 | 
			
		||||
@@ -291,7 +290,7 @@ final class PersonController extends AbstractController
 | 
			
		||||
        return $errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reviewAction(Request $request, PersonNotDuplicateRepository $personNotDuplicateRepository)
 | 
			
		||||
    public function reviewAction(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        if ($request->getMethod() !== 'POST') {
 | 
			
		||||
            $r = new Response("You must send something to review the creation of a new Person");
 | 
			
		||||
@@ -300,6 +299,7 @@ final class PersonController extends AbstractController
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $form = $this->createForm(
 | 
			
		||||
                //CreationPersonType::NAME,
 | 
			
		||||
                CreationPersonType::class,
 | 
			
		||||
                new Person(),
 | 
			
		||||
                array(
 | 
			
		||||
@@ -326,7 +326,7 @@ final class PersonController extends AbstractController
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $form = $this->createForm(
 | 
			
		||||
                CreationPersonType::class,
 | 
			
		||||
                CreationPersonType::NAME,
 | 
			
		||||
                $person,
 | 
			
		||||
                array(
 | 
			
		||||
                   'action' => $this->generateUrl('chill_person_review'),
 | 
			
		||||
@@ -342,7 +342,8 @@ final class PersonController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        $this->em->persist($person);
 | 
			
		||||
 | 
			
		||||
        $alternatePersons = $this->similarPersonMatcher->matchPerson($person, $personNotDuplicateRepository);
 | 
			
		||||
        $alternatePersons = $this->similarPersonMatcher
 | 
			
		||||
            ->matchPerson($person);
 | 
			
		||||
 | 
			
		||||
        if (count($alternatePersons) === 0) {
 | 
			
		||||
            return $this->forward('ChillPersonBundle:Person:create');
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ use Symfony\Component\Translation\TranslatorInterface;
 | 
			
		||||
use Chill\ActivityBundle\Entity\Activity;
 | 
			
		||||
use Chill\DocStoreBundle\Entity\PersonDocument;
 | 
			
		||||
use Chill\EventBundle\Entity\Participation;
 | 
			
		||||
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
 | 
			
		||||
use Chill\TaskBundle\Entity\SingleTask;
 | 
			
		||||
 | 
			
		||||
class PersonDuplicateController extends Controller
 | 
			
		||||
@@ -63,7 +62,7 @@ class PersonDuplicateController extends Controller
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function viewAction($person_id, PersonNotDuplicateRepository $personNotDuplicateRepository)
 | 
			
		||||
    public function viewAction($person_id)
 | 
			
		||||
    {
 | 
			
		||||
        $person = $this->_getPerson($person_id);
 | 
			
		||||
        if ($person === null) {
 | 
			
		||||
@@ -75,9 +74,10 @@ class PersonDuplicateController extends Controller
 | 
			
		||||
          "You are not allowed to see this person.");
 | 
			
		||||
 | 
			
		||||
        $duplicatePersons = $this->similarPersonMatcher->
 | 
			
		||||
            matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
 | 
			
		||||
            matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
 | 
			
		||||
 | 
			
		||||
        $notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
 | 
			
		||||
        $notDuplicatePersons = $this->getDoctrine()->getRepository(PersonNotDuplicate::class)
 | 
			
		||||
            ->findNotDuplicatePerson($person);
 | 
			
		||||
 | 
			
		||||
        return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
 | 
			
		||||
            'person' => $person,
 | 
			
		||||
@@ -97,7 +97,7 @@ class PersonDuplicateController extends Controller
 | 
			
		||||
 | 
			
		||||
        $person1->counters = $this->_getCounters($person1_id);
 | 
			
		||||
        $person2->counters = $this->_getCounters($person2_id);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        if ($person1 === null) {
 | 
			
		||||
            throw $this->createNotFoundException("Person with id $person1_id not"
 | 
			
		||||
                . " found on this server");
 | 
			
		||||
@@ -264,17 +264,17 @@ class PersonDuplicateController extends Controller
 | 
			
		||||
 | 
			
		||||
        return [$person1, $person2];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    private function _getCounters($id): ?array
 | 
			
		||||
    {
 | 
			
		||||
        $em = $this->getDoctrine()->getManager();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        $nb_activity = $em->getRepository(Activity::class)->findBy(['person'=>$id]);
 | 
			
		||||
        $nb_document = $em->getRepository(PersonDocument::class)->findBy(['person'=>$id]);
 | 
			
		||||
        $nb_event = $em->getRepository(Participation::class)->findBy(['person'=>$id]);
 | 
			
		||||
        $nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person'=>$id]);
 | 
			
		||||
        $person = $em->getRepository(Person::class)->findOneBy(['id'=>$id]);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        return [
 | 
			
		||||
            'nb_activity' => count($nb_activity),
 | 
			
		||||
            'nb_document' => count($nb_document),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a suite of a modules, Chill is a software for social workers
 | 
			
		||||
 * Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 *  License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\DataFixtures\ORM;
 | 
			
		||||
 | 
			
		||||
use Doctrine\Common\DataFixtures\AbstractFixture;
 | 
			
		||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 | 
			
		||||
use Doctrine\Persistence\ObjectManager;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create social actions
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class LoadSocialActions extends AbstractFixture implements OrderedFixtureInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getOrder()
 | 
			
		||||
    {
 | 
			
		||||
        return 10020;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static $socialActions = [
 | 
			
		||||
        'social_action_info_conseil' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Informer, conseiller'
 | 
			
		||||
            ],
 | 
			
		||||
            'issue' => 'social_issue_prev_prot'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_action_instruire' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Instruire l\'imprime unique pour des impayés'
 | 
			
		||||
            ],
 | 
			
		||||
            'issue' => 'social_issue_prev_prot'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_action_MASP' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'MASP'
 | 
			
		||||
            ],
 | 
			
		||||
            'issue' => 'social_issue_diff_fin'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_action_protection_enfant' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Protection Enfant confié dans le cadre judiciaire'
 | 
			
		||||
            ],
 | 
			
		||||
            'issue' => 'social_issue_enfant_protection'
 | 
			
		||||
        ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public function load(ObjectManager $manager)
 | 
			
		||||
    {
 | 
			
		||||
        foreach (static::$socialActions as $ref => $new) {
 | 
			
		||||
            $socialAction = new SocialAction();
 | 
			
		||||
            $socialAction->setTitle($new['title']);
 | 
			
		||||
            $socialAction->setIssue($this->getReference($new['issue']));
 | 
			
		||||
            $socialAction->setDefaultNotificationDelay(new \DateInterval('P5D'));
 | 
			
		||||
 | 
			
		||||
            $manager->persist($socialAction);
 | 
			
		||||
            $this->addReference($ref, $socialAction);
 | 
			
		||||
            print("Adding SocialAction '".$new['title']['fr']."'\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $manager->flush();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a suite of a modules, Chill is a software for social workers
 | 
			
		||||
 * Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 *  License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\DataFixtures\ORM;
 | 
			
		||||
 | 
			
		||||
use Doctrine\Common\DataFixtures\AbstractFixture;
 | 
			
		||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 | 
			
		||||
use Doctrine\Persistence\ObjectManager;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create social goals
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class LoadSocialGoals extends AbstractFixture implements OrderedFixtureInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getOrder()
 | 
			
		||||
    {
 | 
			
		||||
        return 10030;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static $socialGoals = [
 | 
			
		||||
        'social_goal_instuire_dossier' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Instruire le dossier de surendettement'
 | 
			
		||||
            ],
 | 
			
		||||
            'action' => 'social_action_MASP'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_goal_proteger' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Protéger via une assistance educative placement'
 | 
			
		||||
            ],
 | 
			
		||||
            'action' => 'social_action_protection_enfant'
 | 
			
		||||
        ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public function load(ObjectManager $manager)
 | 
			
		||||
    {
 | 
			
		||||
        foreach (static::$socialGoals as $ref => $new) {
 | 
			
		||||
            $socialGoal = new Goal();
 | 
			
		||||
            $socialGoal->setTitle($new['title']);
 | 
			
		||||
            $socialGoal->addSocialAction($this->getReference($new['action']));
 | 
			
		||||
 | 
			
		||||
            $manager->persist($socialGoal);
 | 
			
		||||
            $this->addReference($ref, $socialGoal);
 | 
			
		||||
            print("Adding SocialGoal '".$new['title']['fr']."'\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $manager->flush();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,90 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a suite of a modules, Chill is a software for social workers
 | 
			
		||||
 * Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 *  License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\DataFixtures\ORM;
 | 
			
		||||
 | 
			
		||||
use Doctrine\Common\DataFixtures\AbstractFixture;
 | 
			
		||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 | 
			
		||||
use Doctrine\Persistence\ObjectManager;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create social issues
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class LoadSocialIssues extends AbstractFixture implements OrderedFixtureInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getOrder()
 | 
			
		||||
    {
 | 
			
		||||
        return 10010;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static $socialIssues = [
 | 
			
		||||
        'social_issue_diff_fin_or_admin' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'ADULTE - DIFFICULTES FINANCIERES ET/OU ADMINISTRATIVES'
 | 
			
		||||
            ]
 | 
			
		||||
        ],
 | 
			
		||||
        'social_issue_prev_prot' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'ADULTE PREVENTION/PROTECTION'
 | 
			
		||||
            ],
 | 
			
		||||
            'parent' => 'social_issue_diff_fin_or_admin'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_issue_diff_fin' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Difficulté financière'
 | 
			
		||||
            ],
 | 
			
		||||
            'parent' => 'social_issue_diff_fin_or_admin'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_issue_enfant_famille' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Enfant / famille'
 | 
			
		||||
            ]
 | 
			
		||||
        ],
 | 
			
		||||
        'social_issue_enfant_protection' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'enfant - protection'
 | 
			
		||||
            ],
 | 
			
		||||
            'parent' => 'social_issue_enfant_famille'
 | 
			
		||||
        ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public function load(ObjectManager $manager)
 | 
			
		||||
    {
 | 
			
		||||
        foreach (static::$socialIssues as $ref => $new) {
 | 
			
		||||
            $socialIssue = new SocialIssue();
 | 
			
		||||
            $socialIssue->setTitle($new['title']);
 | 
			
		||||
 | 
			
		||||
            if ( array_key_exists('parent', $new)) {
 | 
			
		||||
                $parentRef = $new['parent'];
 | 
			
		||||
                $parent = $this->getReference($parentRef);
 | 
			
		||||
                $socialIssue->setParent($parent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $manager->persist($socialIssue);
 | 
			
		||||
            $this->addReference($ref, $socialIssue);
 | 
			
		||||
            print("Adding SocialIssue '".$new['title']['fr']."'\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $manager->flush();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,94 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Chill is a suite of a modules, Chill is a software for social workers
 | 
			
		||||
 * Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 *  License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\DataFixtures\ORM;
 | 
			
		||||
 | 
			
		||||
use Doctrine\Common\DataFixtures\AbstractFixture;
 | 
			
		||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 | 
			
		||||
use Doctrine\Persistence\ObjectManager;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\Result;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create social results
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class LoadSocialResults extends AbstractFixture implements OrderedFixtureInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getOrder()
 | 
			
		||||
    {
 | 
			
		||||
        return 10040;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static $socialResults = [
 | 
			
		||||
        'social_result_FSL_acces' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'FSL - accès cautionnement'
 | 
			
		||||
            ],
 | 
			
		||||
            'action' => 'social_action_instruire'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_result_FSL_maintien' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'FSL maintien - impayés de loyer'
 | 
			
		||||
            ],
 | 
			
		||||
            'action' => 'social_action_MASP'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_result_soutien_parental' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Soutien parental'
 | 
			
		||||
            ],
 | 
			
		||||
            // 'action' => 'social_action_protection_enfant', (via le goal)
 | 
			
		||||
            'goal' => 'social_goal_proteger'
 | 
			
		||||
        ],
 | 
			
		||||
        'social_result_accompagnement_mineur' => [
 | 
			
		||||
            'title' => [
 | 
			
		||||
                'fr' => 'Accompagnement du mineur'
 | 
			
		||||
            ],
 | 
			
		||||
            // 'action' => 'social_action_protection_enfant', (via le goal)
 | 
			
		||||
            'goal' => 'social_goal_proteger',
 | 
			
		||||
        ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public function load(ObjectManager $manager)
 | 
			
		||||
    {
 | 
			
		||||
        foreach (static::$socialResults as $ref => $new) {
 | 
			
		||||
            $socialResult = new Result();
 | 
			
		||||
            $socialResult->setTitle($new['title']);
 | 
			
		||||
 | 
			
		||||
            if ( array_key_exists('action', $new)) {
 | 
			
		||||
                $action = $this->getReference($new['action']);
 | 
			
		||||
                $socialResult->addSocialAction($action);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( array_key_exists('goal', $new)) {
 | 
			
		||||
                $goal = $this->getReference($new['goal']);
 | 
			
		||||
                $socialResult->addGoal($goal);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            $manager->persist($socialResult);
 | 
			
		||||
            $this->addReference($ref, $socialResult);
 | 
			
		||||
            print("Adding SocialResult '".$new['title']['fr']."'\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $manager->flush();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014-2016 Julien Fastré <julien.fastre@champs-libres.coop>
 | 
			
		||||
 *
 | 
			
		||||
@@ -72,11 +73,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
        $loader->load('services/command.yaml');
 | 
			
		||||
        $loader->load('services/actions.yaml');
 | 
			
		||||
        $loader->load('services/form.yaml');
 | 
			
		||||
        $loader->load('services/repository.yaml');
 | 
			
		||||
        $loader->load('services/templating.yaml');
 | 
			
		||||
        $loader->load('services/alt_names.yaml');
 | 
			
		||||
        // We can get rid of this file when the service 'chill.person.repository.person' is no more used.
 | 
			
		||||
        // We should use the PersonRepository service instead of a custom service name.
 | 
			
		||||
        $loader->load('services/repository.yaml');
 | 
			
		||||
        $loader->load('services/serializer.yaml');
 | 
			
		||||
        $loader->load('services/security.yaml');
 | 
			
		||||
 | 
			
		||||
@@ -165,7 +164,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
        $this->prependHomepageWidget($container);
 | 
			
		||||
        $this->prependDoctrineDQL($container);
 | 
			
		||||
        $this->prependCruds($container);
 | 
			
		||||
        $this->prependWorkflows($container);
 | 
			
		||||
 | 
			
		||||
        //add person_fields parameter as global
 | 
			
		||||
        $chillPersonConfig = $container->getExtensionConfig($this->getAlias());
 | 
			
		||||
@@ -195,39 +193,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function prependWorkflows(ContainerBuilder $container)
 | 
			
		||||
    {
 | 
			
		||||
         $container->prependExtensionConfig('framework', [
 | 
			
		||||
           'workflows' => [
 | 
			
		||||
                'accompanying_period_lifecycle' => [
 | 
			
		||||
                    'type' =>  'state_machine',
 | 
			
		||||
                    'audit_trail' => [ 
 | 
			
		||||
                        'enabled' =>  true
 | 
			
		||||
                    ],
 | 
			
		||||
                    'marking_store' => [
 | 
			
		||||
                        'type' =>  'method',
 | 
			
		||||
                        'property' =>  'step',
 | 
			
		||||
                    ],
 | 
			
		||||
                    'supports' => [
 | 
			
		||||
                        'Chill\PersonBundle\Entity\AccompanyingPeriod'
 | 
			
		||||
                    ],
 | 
			
		||||
                    'initial_marking' =>  'DRAFT',
 | 
			
		||||
                    'places' => [
 | 
			
		||||
                        'DRAFT',
 | 
			
		||||
                        'CONFIRMED',
 | 
			
		||||
                    ],
 | 
			
		||||
                    'transitions' => [
 | 
			
		||||
                        'confirm' => [
 | 
			
		||||
                            'from' =>  'DRAFT',
 | 
			
		||||
                            'to' =>  'CONFIRMED'
 | 
			
		||||
                        ],
 | 
			
		||||
                    ],
 | 
			
		||||
                ],
 | 
			
		||||
            ]
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a widget "add a person" on the homepage, automatically
 | 
			
		||||
     *
 | 
			
		||||
@@ -354,15 +319,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
                    'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_PATCH => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_PUT => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true, 
 | 
			
		||||
                                Request::METHOD_PUT => true, 
 | 
			
		||||
                                Request::METHOD_PATCH => true, 
 | 
			
		||||
                            'roles' => [
 | 
			
		||||
                                Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'participation' => [
 | 
			
		||||
@@ -376,79 +334,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'resource' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_DELETE => true,
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'comment' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_DELETE => true,
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'requestor' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_DELETE => true,
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'scope' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_DELETE => true,
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        'socialissue' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_DELETE => true,
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'controller_action' => 'socialIssueApi',
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                                Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        ]
 | 
			
		||||
 | 
			
		||||
                        'confirm' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_POST => true, 
 | 
			
		||||
                                Request::METHOD_GET => false,
 | 
			
		||||
                                Request::METHOD_HEAD => false,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [ 
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
@@ -471,49 +358,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
 | 
			
		||||
                    'name' => 'social_work_social_issue',
 | 
			
		||||
                    'base_path' => '/api/1.0/person/social-work/social-issue',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\PersonBundle\Entity\Person::class,
 | 
			
		||||
                    'name' => 'person',
 | 
			
		||||
                    'base_path' => '/api/1.0/person/person',
 | 
			
		||||
                    'base_role' => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
 | 
			
		||||
                    'controller' => \Chill\PersonBundle\Controller\PersonApiController::class,
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_entity' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true,
 | 
			
		||||
                                Request::METHOD_POST=> true,
 | 
			
		||||
                            ],
 | 
			
		||||
                            'roles' => [
 | 
			
		||||
                                Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
 | 
			
		||||
                                Request::METHOD_HEAD => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
 | 
			
		||||
                                Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\PersonVoter::CREATE,
 | 
			
		||||
 | 
			
		||||
                            ]
 | 
			
		||||
                        ],
 | 
			
		||||
                    ]
 | 
			
		||||
                ],
 | 
			
		||||
                ]
 | 
			
		||||
            ]
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,34 +22,25 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
 | 
			
		||||
use Chill\MainBundle\Entity\Scope;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use DateTimeInterface;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccompanyingPeriod Class
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriodRepository")
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *  "accompanying_period"=AccompanyingPeriod::class
 | 
			
		||||
 *  })
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
class AccompanyingPeriod
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Mark an accompanying period as "occasional"
 | 
			
		||||
@@ -89,7 +80,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\Column(name="id", type="integer")
 | 
			
		||||
     * @ORM\GeneratedValue(strategy="AUTO")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
 | 
			
		||||
@@ -97,7 +87,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @var \DateTime
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="date")
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $openingDate;
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +94,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @var \DateTime
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="date", nullable=true)
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $closingDate = null;
 | 
			
		||||
 | 
			
		||||
@@ -113,7 +101,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @var string
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\Column(type="text")
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $remark = '';
 | 
			
		||||
 | 
			
		||||
@@ -121,28 +108,17 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @var Collection
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\OneToMany(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Comment",
 | 
			
		||||
     *       mappedBy="accompanyingPeriod",
 | 
			
		||||
     *       cascade={"persist", "remove"},
 | 
			
		||||
     *       orphanRemoval=true
 | 
			
		||||
     *       mappedBy="accompanyingPeriod"
 | 
			
		||||
     *     )
 | 
			
		||||
     */
 | 
			
		||||
    private $comments;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(
 | 
			
		||||
     *    targetEntity=Comment::class
 | 
			
		||||
     * )
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private ?Comment $initialComment = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Collection
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
 | 
			
		||||
     *     mappedBy="accompanyingPeriod",
 | 
			
		||||
     *     cascade={"persist", "refresh", "remove", "merge", "detach"})
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $participations;
 | 
			
		||||
 | 
			
		||||
@@ -152,42 +128,36 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @ORM\ManyToOne(
 | 
			
		||||
     *     targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive")
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $closingMotive = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=User::class)
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $user;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=User::class)
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $createdBy;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     * @ORM\Column(type="string", length=32, nullable=true)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $step = self::STEP_DRAFT;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=Origin::class)
 | 
			
		||||
     * @ORM\JoinColumn(nullable=true)
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $origin;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     * @ORM\Column(type="string", nullable=true)
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $intensity;
 | 
			
		||||
 | 
			
		||||
@@ -202,7 +172,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     *     joinColumns={@ORM\JoinColumn(name="accompanying_period_id", referencedColumnName="id")},
 | 
			
		||||
     *     inverseJoinColumns={@ORM\JoinColumn(name="scope_id", referencedColumnName="id")}
 | 
			
		||||
     * )
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $scopes;
 | 
			
		||||
 | 
			
		||||
@@ -220,22 +189,19 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var bool
 | 
			
		||||
     * @ORM\Column(type="boolean", options={"default": false} )
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     * @ORM\Column(type="boolean")
 | 
			
		||||
     */
 | 
			
		||||
    private $requestorAnonymous = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var bool
 | 
			
		||||
     * @ORM\Column(type="boolean", options={"default": false} )
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     * @ORM\Column(type="boolean")
 | 
			
		||||
     */
 | 
			
		||||
    private $emergency = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var bool
 | 
			
		||||
     * @ORM\Column(type="boolean", options={"default": false} )
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     * @ORM\Column(type="boolean")
 | 
			
		||||
     */
 | 
			
		||||
    private $confidential = false;
 | 
			
		||||
 | 
			
		||||
@@ -244,54 +210,21 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     *
 | 
			
		||||
     * @ORM\OneToMany(
 | 
			
		||||
     *     targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Resource",
 | 
			
		||||
     *     mappedBy="accompanyingPeriod",
 | 
			
		||||
     *     cascade={"persist", "remove"},
 | 
			
		||||
     *     orphanRemoval=true
 | 
			
		||||
     *     mappedBy="accompanyingPeriod"
 | 
			
		||||
     * )
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $resources;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToMany(
 | 
			
		||||
     *     targetEntity=SocialIssue::class
 | 
			
		||||
     * )
 | 
			
		||||
     * @ORM\JoinTable(
 | 
			
		||||
     *     name="chill_person_accompanying_period_social_issues"
 | 
			
		||||
     *  )
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private Collection $socialIssues;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
 | 
			
		||||
     */
 | 
			
		||||
    private \DateTimeInterface $createdAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(
 | 
			
		||||
     *    targetEntity=User::class
 | 
			
		||||
     * )
 | 
			
		||||
     */
 | 
			
		||||
    private User $updatedBy;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
 | 
			
		||||
     */
 | 
			
		||||
    private \DateTimeInterface $updatedAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * AccompanyingPeriod constructor.
 | 
			
		||||
     *
 | 
			
		||||
     * @param \DateTime $dateOpening
 | 
			
		||||
     * @uses AccompanyingPeriod::setClosingDate()
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(\DateTime $dateOpening = null) {
 | 
			
		||||
        $this->setOpeningDate($dateOpening ?? new \DateTime('now'));
 | 
			
		||||
    public function __construct(\DateTime $dateOpening) {
 | 
			
		||||
        $this->setOpeningDate($dateOpening);
 | 
			
		||||
        $this->participations = new ArrayCollection();
 | 
			
		||||
        $this->scopes = new ArrayCollection();
 | 
			
		||||
        $this->socialIssues = new ArrayCollection();
 | 
			
		||||
        $this->comments = new ArrayCollection();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -385,55 +318,23 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this->remark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    public function getComments(): Collection
 | 
			
		||||
    {
 | 
			
		||||
        return $this->comments->filter(function (Comment $c) {
 | 
			
		||||
            return $c !== $this->initialComment;
 | 
			
		||||
        });
 | 
			
		||||
        return $this->comments;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addComment(Comment $comment): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->comments[] = $comment;
 | 
			
		||||
        $comment->setAccompanyingPeriod($this);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function removeComment(Comment $comment): void
 | 
			
		||||
    {
 | 
			
		||||
        $comment->setAccompanyingPeriod(null);
 | 
			
		||||
        $this->comments->removeElement($comment);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Groups({"write"})
 | 
			
		||||
     */
 | 
			
		||||
    public function setInitialComment(?Comment $comment = null): self
 | 
			
		||||
    {
 | 
			
		||||
        if (NULL !== $this->initialComment) {
 | 
			
		||||
            $this->removeComment($this->initialComment);
 | 
			
		||||
        } 
 | 
			
		||||
        if ($comment instanceof Comment) {
 | 
			
		||||
            $this->addComment($comment);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->initialComment = $comment;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    public function getInitialComment(): ?Comment
 | 
			
		||||
    {
 | 
			
		||||
        return $this->initialComment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Participations Collection
 | 
			
		||||
     */
 | 
			
		||||
@@ -483,9 +384,9 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Open a new participation for a person
 | 
			
		||||
     * Add Person
 | 
			
		||||
     */
 | 
			
		||||
    public function createParticipationFor(Person $person): AccompanyingPeriodParticipation
 | 
			
		||||
    public function addPerson(Person $person = null): AccompanyingPeriodParticipation
 | 
			
		||||
    {
 | 
			
		||||
        $participation = new AccompanyingPeriodParticipation($this, $person);
 | 
			
		||||
        $this->participations[] = $participation;
 | 
			
		||||
@@ -493,24 +394,10 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $participation;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addPerson(Person $person = null): self
 | 
			
		||||
    {
 | 
			
		||||
        if (NULL !== $person) {
 | 
			
		||||
            $this->createParticipationFor($person);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Close a participation for a person
 | 
			
		||||
     *
 | 
			
		||||
     * Search for the person's participation and set the end date at
 | 
			
		||||
     * 'now'.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     * Remove Person
 | 
			
		||||
     */
 | 
			
		||||
    public function closeParticipationFor($person): ?AccompanyingPeriodParticipation
 | 
			
		||||
    public function removePerson(Person $person): ?AccompanyingPeriodParticipation
 | 
			
		||||
    {
 | 
			
		||||
        $participation = $this->getOpenParticipationContainsPerson($person);
 | 
			
		||||
 | 
			
		||||
@@ -520,17 +407,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
 | 
			
		||||
        return $participation;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove Person
 | 
			
		||||
     */
 | 
			
		||||
    public function removePerson(Person $person): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->closeParticipationFor($person);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function getClosingMotive(): ?ClosingMotive
 | 
			
		||||
@@ -557,7 +433,7 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $participation = $this->getParticipationsContainsPerson($person);
 | 
			
		||||
        $participation = $this->participationsContainsPerson($person);
 | 
			
		||||
        if (!null === $participation)
 | 
			
		||||
        {
 | 
			
		||||
            $person = $participation->getPerson();
 | 
			
		||||
@@ -639,9 +515,9 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this->requestorPerson;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function setRequestorPerson(Person $requestorPerson = null): self
 | 
			
		||||
    public function setRequestorPerson(Person $requestorPerson): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->requestorPerson = $requestorPerson;
 | 
			
		||||
        $this->requestorPerson = ($this->requestorThirdParty === null) ? $requestorPerson : null;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -651,53 +527,21 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this->requestorThirdParty;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function setRequestorThirdParty(ThirdParty $requestorThirdParty = null): self
 | 
			
		||||
    public function setRequestorThirdParty(ThirdParty $requestorThirdParty): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->requestorThirdParty = $requestorThirdParty;
 | 
			
		||||
        $this->requestorThirdParty = ($this->requestorPerson === null) ? $requestorThirdParty : null;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return Person|ThirdParty
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    public function getRequestor()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->requestorPerson ?? $this->requestorThirdParty;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set a requestor
 | 
			
		||||
     *
 | 
			
		||||
     * The requestor is either an instance of ThirdParty, or an
 | 
			
		||||
     * instance of Person
 | 
			
		||||
     *
 | 
			
		||||
     * @param $requestor Person|ThirdParty
 | 
			
		||||
     * @return self
 | 
			
		||||
     * @throw UnexpectedValueException if the requestor is not a Person or ThirdParty
 | 
			
		||||
     * @Groups({"write"})
 | 
			
		||||
     */
 | 
			
		||||
    public function setRequestor($requestor): self
 | 
			
		||||
    {
 | 
			
		||||
        if ($requestor instanceof Person) {
 | 
			
		||||
            $this->setRequestorThirdParty(NULL);
 | 
			
		||||
            $this->setRequestorPerson($requestor);
 | 
			
		||||
        } elseif ($requestor instanceof ThirdParty) {
 | 
			
		||||
            $this->setRequestorThirdParty($requestor);
 | 
			
		||||
            $this->setRequestorPerson(NULL);
 | 
			
		||||
        } elseif (NULL === $requestor) {
 | 
			
		||||
            $this->setRequestorPerson(NULL);
 | 
			
		||||
            $this->setRequestorThirdParty(NULL);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \UnexpectedValueException("requestor is not an instance of Person or ThirdParty");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function isRequestorAnonymous(): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->requestorAnonymous;
 | 
			
		||||
@@ -794,7 +638,6 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
 | 
			
		||||
    public function addResource(Resource $resource): self
 | 
			
		||||
    {
 | 
			
		||||
        $resource->setAccompanyingPeriod($this);
 | 
			
		||||
        $this->resources[] = $resource;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
@@ -802,27 +645,9 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
 | 
			
		||||
    public function removeResource(Resource $resource): void
 | 
			
		||||
    {
 | 
			
		||||
        $resource->setAccompanyingPeriod(null);
 | 
			
		||||
        $this->resources->removeElement($resource);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSocialIssues(): Collection
 | 
			
		||||
    {
 | 
			
		||||
        return $this->socialIssues;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addSocialIssue(SocialIssue $socialIssue): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->socialIssues[] = $socialIssue;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function removeSocialIssue(SocialIssue $socialIssue): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->socialIssues->removeElement($socialIssue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of all persons which are participating to this course
 | 
			
		||||
     */
 | 
			
		||||
@@ -834,25 +659,4 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setCreatedAt(\DateTimeInterface $datetime): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->createdAt = $datetime;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setUpdatedBy(User $user): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->updatedBy = $user;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setUpdatedAt(\DateTimeInterface $datetime): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->updatedAt = $datetime;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\Result;
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
@@ -12,7 +13,7 @@ use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=AccompanyingPeriodWorkRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_work")
 | 
			
		||||
 */
 | 
			
		||||
 class AccompanyingPeriodWork
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,13 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
 | 
			
		||||
use Chill\PersonBundle\Entity\SocialWork\Result;
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkGoalRepository;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=AccompanyingPeriodWorkGoalRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_work_goal")
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriodWorkGoal
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,8 @@ use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
/**
 | 
			
		||||
 * ClosingMotive give an explanation why we closed the Accompanying period
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(
 | 
			
		||||
 *     repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository")
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_closingmotive")
 | 
			
		||||
 */
 | 
			
		||||
class ClosingMotive
 | 
			
		||||
 
 | 
			
		||||
@@ -22,28 +22,21 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\CommentRepository;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
 | 
			
		||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=CommentRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_comment")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *    "accompanying_period_comment"=Comment::class
 | 
			
		||||
 * })
 | 
			
		||||
 */
 | 
			
		||||
class Comment implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
class Comment
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\GeneratedValue
 | 
			
		||||
     * @ORM\Column(type="integer")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
 | 
			
		||||
@@ -51,39 +44,34 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
     * @ORM\ManyToOne(
 | 
			
		||||
     *     targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod",
 | 
			
		||||
     *     inversedBy="comments")
 | 
			
		||||
     * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
 | 
			
		||||
     * @ORM\JoinColumn(nullable=false)
 | 
			
		||||
     */
 | 
			
		||||
    private $accompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=User::class)
 | 
			
		||||
     * @ORM\JoinColumn(nullable=false)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $creator;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="datetime")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $createdAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="datetime")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $updatedAt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=User::class)
 | 
			
		||||
     * @ORM\JoinColumn(nullable=false)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $updatedBy;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="text")
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     */
 | 
			
		||||
    private $content;
 | 
			
		||||
 | 
			
		||||
@@ -116,11 +104,6 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setCreatedBy(User $user): self
 | 
			
		||||
    {
 | 
			
		||||
        return $this->setCreator($user);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getCreatedAt(): ?\DateTimeInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createdAt;
 | 
			
		||||
@@ -150,7 +133,7 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this->updatedBy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setUpdatedBy(User $updatedBy): self
 | 
			
		||||
    public function setUpdatedBy(?User $updatedBy): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->updatedBy = $updatedBy;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,11 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\OriginRepository;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=OriginRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_origin")
 | 
			
		||||
 */
 | 
			
		||||
class Origin
 | 
			
		||||
@@ -35,19 +35,16 @@ class Origin
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\GeneratedValue
 | 
			
		||||
     * @ORM\Column(type="integer")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="json")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $label;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="date_immutable", nullable=true)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $noActiveAfter;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,21 +22,16 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=ResourceRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_resource")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *   "accompanying_period_resource"=Resource::class
 | 
			
		||||
 *  })
 | 
			
		||||
 */
 | 
			
		||||
class Resource
 | 
			
		||||
{
 | 
			
		||||
@@ -44,7 +39,6 @@ class Resource
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\GeneratedValue
 | 
			
		||||
     * @ORM\Column(type="integer")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
 | 
			
		||||
@@ -97,7 +91,7 @@ class Resource
 | 
			
		||||
        return $this->thirdParty;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function setThirdParty(?ThirdParty $thirdParty): self
 | 
			
		||||
    public function setThirdParty(?ThirdParty $thirdParty): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->thirdParty = $thirdParty;
 | 
			
		||||
 | 
			
		||||
@@ -109,7 +103,7 @@ class Resource
 | 
			
		||||
        return $this->person;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function setPerson(?Person $person): self
 | 
			
		||||
    public function setPerson(?Person $person): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->person = $person;
 | 
			
		||||
 | 
			
		||||
@@ -127,35 +121,9 @@ class Resource
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @param $resource Person|ThirdParty
 | 
			
		||||
     */
 | 
			
		||||
    public function setResource($resource): self
 | 
			
		||||
    {
 | 
			
		||||
        if ($resource instanceof ThirdParty) {
 | 
			
		||||
            $this->setThirdParty($resource);
 | 
			
		||||
            $this->setPerson(NULL);
 | 
			
		||||
        } elseif ($resource instanceof Person) {
 | 
			
		||||
            $this->setPerson($resource);
 | 
			
		||||
            $this->setThirdParty(NULL);
 | 
			
		||||
        } elseif (NULL === $resource) {
 | 
			
		||||
            $this->setPerson(NULL);
 | 
			
		||||
            $this->setThirdParty(NULL);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \UnexpectedValueException(sprintf("the resource ".
 | 
			
		||||
                "should be an instance of %s or %s", Person::class,
 | 
			
		||||
                ThirdParty::class));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @return ThirdParty|Person
 | 
			
		||||
     * @Groups({"read", "write"})
 | 
			
		||||
     * @return Person|ThirdParty
 | 
			
		||||
     */
 | 
			
		||||
    public function getResource()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,21 +22,17 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\AccompanyingPeriodParticipationRepository;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AccompanyingPeriodParticipation Class
 | 
			
		||||
 *
 | 
			
		||||
 * @package Chill\PersonBundle\Entity
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=AccompanyingPeriodParticipationRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_accompanying_period_participation")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *  "accompanying_period_participation"=AccompanyingPeriodParticipation::class
 | 
			
		||||
 *  })
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriodParticipation
 | 
			
		||||
{
 | 
			
		||||
@@ -44,14 +40,12 @@ class AccompanyingPeriodParticipation
 | 
			
		||||
     * @ORM\Id
 | 
			
		||||
     * @ORM\GeneratedValue
 | 
			
		||||
     * @ORM\Column(type="integer")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $id;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity=Person::class, inversedBy="accompanyingPeriodParticipations")
 | 
			
		||||
     * @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $person;
 | 
			
		||||
    
 | 
			
		||||
@@ -63,13 +57,11 @@ class AccompanyingPeriodParticipation
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="date", nullable=false)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $startDate;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="date", nullable=true)
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $endDate = null;
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,13 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\Household;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Chill\MainBundle\Entity\Address;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=HouseholdRepository::class)
 | 
			
		||||
 */
 | 
			
		||||
class Household
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,12 @@
 | 
			
		||||
namespace Chill\PersonBundle\Entity\Household;
 | 
			
		||||
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Chill\PersonBundle\Repository\Household\HouseholdMembersRepository;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=HouseholdMembersRepository::class)
 | 
			
		||||
 */
 | 
			
		||||
class HouseholdMembers
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
/**
 | 
			
		||||
 * MaritalStatus
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity()
 | 
			
		||||
 * @ORM\Table(name="chill_person_marital_status")
 | 
			
		||||
 * @ORM\HasLifecycleCallbacks()
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -34,21 +34,17 @@ use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Criteria;
 | 
			
		||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Person Class
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonRepository")
 | 
			
		||||
 * @ORM\Table(name="chill_person_person",
 | 
			
		||||
 *     indexes={@ORM\Index(
 | 
			
		||||
 *          name="person_names",
 | 
			
		||||
 *          columns={"firstName", "lastName"}
 | 
			
		||||
 * )})
 | 
			
		||||
 * @ORM\HasLifecycleCallbacks()
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *   "person"=Person::class
 | 
			
		||||
 * })
 | 
			
		||||
 */
 | 
			
		||||
class Person implements HasCenterInterface
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 * PersonAltName
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Table(name="chill_person_alt_name")
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonAltNameRepository")
 | 
			
		||||
 */
 | 
			
		||||
class PersonAltName
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ use Chill\MainBundle\Entity\User;
 | 
			
		||||
 * PersonNotDuplicate
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Table(name="chill_person_not_duplicate")
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonNotDuplicateRepository")
 | 
			
		||||
 */
 | 
			
		||||
class PersonNotDuplicate
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
/**
 | 
			
		||||
 * Person Phones
 | 
			
		||||
 *
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity()
 | 
			
		||||
 * @ORM\Table(name="chill_person_phone")
 | 
			
		||||
 */
 | 
			
		||||
class PersonPhone
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,11 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\SocialWork;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=EvaluationRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_social_work_evaluation")
 | 
			
		||||
 */
 | 
			
		||||
class Evaluation
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,13 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\SocialWork;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=GoalRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_social_work_goal")
 | 
			
		||||
 */
 | 
			
		||||
class Goal
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,13 @@ namespace Chill\PersonBundle\Entity\SocialWork;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=ResultRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_social_work_result")
 | 
			
		||||
 */
 | 
			
		||||
class Result
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,13 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Entity\SocialWork;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=SocialActionRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_social_action")
 | 
			
		||||
 */
 | 
			
		||||
class SocialAction
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,15 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace Chill\PersonBundle\Entity\SocialWork;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
 | 
			
		||||
use Doctrine\Common\Collections\ArrayCollection;
 | 
			
		||||
use Doctrine\Common\Collections\Collection;
 | 
			
		||||
use Doctrine\ORM\Mapping as ORM;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\Groups;
 | 
			
		||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ORM\Entity
 | 
			
		||||
 * @ORM\Entity(repositoryClass=SocialIssueRepository::class)
 | 
			
		||||
 * @ORM\Table(name="chill_person_social_issue")
 | 
			
		||||
 * @DiscriminatorMap(typeProperty="type", mapping={
 | 
			
		||||
 *   "social_issue"=SocialIssue::class
 | 
			
		||||
 * })
 | 
			
		||||
 */
 | 
			
		||||
class SocialIssue
 | 
			
		||||
{
 | 
			
		||||
@@ -40,7 +37,6 @@ class SocialIssue
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(type="json")
 | 
			
		||||
     * @Groups({"read"})
 | 
			
		||||
     */
 | 
			
		||||
    private $title = [];
 | 
			
		||||
 | 
			
		||||
@@ -65,11 +61,6 @@ class SocialIssue
 | 
			
		||||
        return $this->parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function hasParent(): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->parent !== null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setParent(?self $parent): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->parent = $parent;
 | 
			
		||||
 
 | 
			
		||||
@@ -33,10 +33,9 @@ use Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer;
 | 
			
		||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
 | 
			
		||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
 | 
			
		||||
 | 
			
		||||
final class CreationPersonType extends AbstractType
 | 
			
		||||
class CreationPersonType extends AbstractType
 | 
			
		||||
{
 | 
			
		||||
    // TODO: This is only used in test.
 | 
			
		||||
    // TODO: See if this is still valid and update accordingly.
 | 
			
		||||
 | 
			
		||||
    const NAME = 'chill_personbundle_person_creation';
 | 
			
		||||
 | 
			
		||||
    const FORM_NOT_REVIEWED = 'not_reviewed';
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
namespace Chill\PersonBundle\Menu;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Knp\Menu\MenuItem;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
@@ -33,31 +32,24 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
 | 
			
		||||
    
 | 
			
		||||
    public function buildMenu($menuId, MenuItem $menu, array $parameters): void
 | 
			
		||||
    {
 | 
			
		||||
        $period = $parameters['accompanyingCourse'];
 | 
			
		||||
 | 
			
		||||
        $menu->addChild($this->translator->trans('Resume Accompanying Course'), [
 | 
			
		||||
            'route' => 'chill_person_accompanying_course_index',
 | 
			
		||||
            'routeParameters' => [
 | 
			
		||||
                'accompanying_period_id' => $period->getId()
 | 
			
		||||
                'accompanying_period_id' => $parameters['accompanyingCourse']->getId()
 | 
			
		||||
        ]])
 | 
			
		||||
        ->setExtras(['order' => 10]);
 | 
			
		||||
        
 | 
			
		||||
        $menu->addChild($this->translator->trans('Edit Accompanying Course'), [
 | 
			
		||||
            'route' => 'chill_person_accompanying_course_show',
 | 
			
		||||
            'routeParameters' => [
 | 
			
		||||
                'accompanying_period_id' => $period->getId()
 | 
			
		||||
                'accompanying_period_id' => $parameters['accompanyingCourse']->getId()
 | 
			
		||||
        ]])
 | 
			
		||||
        ->setExtras(['order' => 20]);
 | 
			
		||||
 | 
			
		||||
        if (AccompanyingPeriod::STEP_DRAFT === $period->getStep()) {
 | 
			
		||||
            // no more menu items if the period is draft
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $menu->addChild($this->translator->trans('Accompanying Course Details'), [
 | 
			
		||||
            'route' => 'chill_person_accompanying_course_history',
 | 
			
		||||
            'routeParameters' => [
 | 
			
		||||
                'accompanying_period_id' => $period->getId()
 | 
			
		||||
                'accompanying_period_id' => $parameters['accompanyingCourse']->getId()
 | 
			
		||||
        ]])
 | 
			
		||||
        ->setExtras(['order' => 30]);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -71,14 +71,6 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
 | 
			
		||||
                    'icons' => [ 'plus' ]
 | 
			
		||||
                ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $menu->addChild($this->translator->trans('Create an accompanying course'), [
 | 
			
		||||
                'route' => 'chill_person_accompanying_course_new'
 | 
			
		||||
            ])
 | 
			
		||||
            ->setExtras([
 | 
			
		||||
                'order' => 11,
 | 
			
		||||
                'icons' => [ 'plus' ]
 | 
			
		||||
            ]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @method AccompanyingPeriodWorkGoal|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
@@ -12,12 +12,10 @@ use Doctrine\ORM\EntityRepository;
 | 
			
		||||
 * @method AccompanyingPeriodWorkGoal[]    findAll()
 | 
			
		||||
 * @method AccompanyingPeriodWorkGoal[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
final class AccompanyingPeriodWorkGoalRepository
 | 
			
		||||
class AccompanyingPeriodWorkGoalRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(AccompanyingPeriodWorkGoal::class);
 | 
			
		||||
        parent::__construct($registry, AccompanyingPeriodWorkGoal::class);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @method AccompanyingPeriodWork|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
@@ -12,12 +12,10 @@ use Doctrine\ORM\EntityRepository;
 | 
			
		||||
 * @method AccompanyingPeriodWork[]    findAll()
 | 
			
		||||
 * @method AccompanyingPeriodWork[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
final class AccompanyingPeriodWorkRepository
 | 
			
		||||
class AccompanyingPeriodWorkRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class);
 | 
			
		||||
        parent::__construct($registry, AccompanyingPeriodWork::class);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,47 +22,43 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
 | 
			
		||||
 | 
			
		||||
final class ClosingMotiveRepository
 | 
			
		||||
/**
 | 
			
		||||
 * Class ClosingMotiveRepository
 | 
			
		||||
 * Entity repository for closing motives
 | 
			
		||||
 *
 | 
			
		||||
 * @package Chill\PersonBundle\Repository
 | 
			
		||||
 */
 | 
			
		||||
class ClosingMotiveRepository extends EntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    private EntityManagerInterface $entityManager;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    {
 | 
			
		||||
        $this->entityManager = $entityManager;
 | 
			
		||||
        $this->repository = $entityManager->getRepository(ClosingMotive::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param bool $onlyLeaf
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function getActiveClosingMotive(bool $onlyLeaf = true)
 | 
			
		||||
    {
 | 
			
		||||
        $rsm = new ResultSetMappingBuilder($this->entityManager);
 | 
			
		||||
        $rsm->addRootEntityFromClassMetadata($this->repository->getClassName(), 'cm');
 | 
			
		||||
 | 
			
		||||
        $sql = "SELECT " . (string) $rsm . "
 | 
			
		||||
        $rsm = new ResultSetMappingBuilder($this->getEntityManager());
 | 
			
		||||
        $rsm->addRootEntityFromClassMetadata($this->getClassName(), 'cm');
 | 
			
		||||
        
 | 
			
		||||
        $sql = "SELECT ".(string) $rsm."
 | 
			
		||||
            FROM chill_person_accompanying_period_closingmotive AS cm
 | 
			
		||||
            WHERE
 | 
			
		||||
                active IS TRUE ";
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        if ($onlyLeaf) {
 | 
			
		||||
            $sql .= "AND cm.id NOT IN (
 | 
			
		||||
                SELECT DISTINCT parent_id FROM chill_person_accompanying_period_closingmotive WHERE parent_id IS NOT NULL
 | 
			
		||||
            )";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        $sql .= " ORDER BY cm.ordering ASC";
 | 
			
		||||
 | 
			
		||||
        return $this
 | 
			
		||||
            ->entityManager
 | 
			
		||||
        
 | 
			
		||||
        return $this->_em
 | 
			
		||||
            ->createNativeQuery($sql, $rsm)
 | 
			
		||||
            ->getResult();
 | 
			
		||||
            ->getResult()
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,20 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class CommentRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method Comment|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method Comment|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method Comment[]    findAll()
 | 
			
		||||
 * @method Comment[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class CommentRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(Comment::class);
 | 
			
		||||
        parent::__construct($registry, Comment::class);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,20 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class OriginRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method Origin|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method Origin|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method Origin[]    findAll()
 | 
			
		||||
 * @method Origin[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class OriginRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(Origin::class);
 | 
			
		||||
        parent::__construct($registry, Origin::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,20 +23,20 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class ResourceRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method Resource|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method Resource|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method Resource[]    findAll()
 | 
			
		||||
 * @method Resource[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class ResourceRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(Resource::class);
 | 
			
		||||
        parent::__construct($registry, Resource::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function find($id, $lockMode = null, $lockVersion = null): ?Resource
 | 
			
		||||
    {
 | 
			
		||||
        return $this->repository->find($id, $lockMode, $lockVersion);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,20 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class AccompanyingPeriodParticipationRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method AccompanyingPeriodParticipation|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method AccompanyingPeriodParticipation|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method AccompanyingPeriodParticipation[]    findAll()
 | 
			
		||||
 * @method AccompanyingPeriodParticipation[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriodParticipationRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(AccompanyingPeriodParticipation::class);
 | 
			
		||||
        parent::__construct($registry, AccompanyingPeriodParticipation::class);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,20 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class AccompanyingPeriodRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method AccompanyingPeriod|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method AccompanyingPeriod|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method AccompanyingPeriod[]    findAll()
 | 
			
		||||
 * @method AccompanyingPeriod[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class AccompanyingPeriodRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(AccompanyingPeriod::class);
 | 
			
		||||
        parent::__construct($registry, AccompanyingPeriod::class);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,48 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\Household;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\HouseholdMembers;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class HouseholdMembersRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method HouseholdMembers|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method HouseholdMembers|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method HouseholdMembers[]    findAll()
 | 
			
		||||
 * @method HouseholdMembers[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class HouseholdMembersRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(HouseholdMembers::class);
 | 
			
		||||
        parent::__construct($registry, HouseholdMembers::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // /**
 | 
			
		||||
    //  * @return HouseholdMembers[] Returns an array of HouseholdMembers objects
 | 
			
		||||
    //  */
 | 
			
		||||
    /*
 | 
			
		||||
    public function findByExampleField($value)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createQueryBuilder('h')
 | 
			
		||||
            ->andWhere('h.exampleField = :val')
 | 
			
		||||
            ->setParameter('val', $value)
 | 
			
		||||
            ->orderBy('h.id', 'ASC')
 | 
			
		||||
            ->setMaxResults(10)
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getResult()
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    public function findOneBySomeField($value): ?HouseholdMembers
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createQueryBuilder('h')
 | 
			
		||||
            ->andWhere('h.exampleField = :val')
 | 
			
		||||
            ->setParameter('val', $value)
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getOneOrNullResult()
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,48 @@
 | 
			
		||||
namespace Chill\PersonBundle\Repository\Household;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 | 
			
		||||
use Doctrine\Persistence\ManagerRegistry;
 | 
			
		||||
 | 
			
		||||
final class HouseholdRepository
 | 
			
		||||
/**
 | 
			
		||||
 * @method Household|null find($id, $lockMode = null, $lockVersion = null)
 | 
			
		||||
 * @method Household|null findOneBy(array $criteria, array $orderBy = null)
 | 
			
		||||
 * @method Household[]    findAll()
 | 
			
		||||
 * @method Household[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 | 
			
		||||
 */
 | 
			
		||||
class HouseholdRepository extends ServiceEntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    public function __construct(ManagerRegistry $registry)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(Household::class);
 | 
			
		||||
        parent::__construct($registry, Household::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // /**
 | 
			
		||||
    //  * @return Household[] Returns an array of Household objects
 | 
			
		||||
    //  */
 | 
			
		||||
    /*
 | 
			
		||||
    public function findByExampleField($value)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createQueryBuilder('h')
 | 
			
		||||
            ->andWhere('h.exampleField = :val')
 | 
			
		||||
            ->setParameter('val', $value)
 | 
			
		||||
            ->orderBy('h.id', 'ASC')
 | 
			
		||||
            ->setMaxResults(10)
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getResult()
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    public function findOneBySomeField($value): ?Household
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createQueryBuilder('h')
 | 
			
		||||
            ->andWhere('h.exampleField = :val')
 | 
			
		||||
            ->setParameter('val', $value)
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getOneOrNullResult()
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,12 @@
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Repository;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\PersonAltName;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
 | 
			
		||||
final class PersonAltNameRepository
 | 
			
		||||
/**
 | 
			
		||||
 * PersonAltNameRepository
 | 
			
		||||
 *
 | 
			
		||||
 * This class was generated by the Doctrine ORM. Add your own custom
 | 
			
		||||
 * repository methods below.
 | 
			
		||||
 */
 | 
			
		||||
class PersonAltNameRepository extends \Doctrine\ORM\EntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(PersonAltName::class);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,21 +4,23 @@ namespace Chill\PersonBundle\Repository;
 | 
			
		||||
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Entity\PersonNotDuplicate;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
 | 
			
		||||
final class PersonNotDuplicateRepository
 | 
			
		||||
/**
 | 
			
		||||
 * Class PersonNotDuplicateRepository
 | 
			
		||||
 *
 | 
			
		||||
 * @package Chill\PersonBundle\Repository
 | 
			
		||||
 */
 | 
			
		||||
class PersonNotDuplicateRepository  extends EntityRepository
 | 
			
		||||
{
 | 
			
		||||
    private EntityRepository $repository;
 | 
			
		||||
 | 
			
		||||
    public function __construct(EntityManagerInterface $entityManager)
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Chill\PersonBundle\Entity\Person $person
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function findNotDuplicatePerson(Person $person)
 | 
			
		||||
    {
 | 
			
		||||
        $this->repository = $entityManager->getRepository(PersonNotDuplicate::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function findNotDuplicatePerson(Person $person): array
 | 
			
		||||
    {
 | 
			
		||||
        $qb = $this->repository->createQueryBuilder('pnd');
 | 
			
		||||
        $qb = $this->createQueryBuilder('pnd');
 | 
			
		||||
        $qb->select('pnd')
 | 
			
		||||
            ->where('pnd.person1 = :person OR pnd.person2 = :person')
 | 
			
		||||
        ;
 | 
			
		||||
@@ -26,7 +28,6 @@ final class PersonNotDuplicateRepository
 | 
			
		||||
        $result = $qb->getQuery()->getResult();
 | 
			
		||||
 | 
			
		||||
        $persons = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($result as $row) {
 | 
			
		||||
            if ($row->getPerson1() === $person) {
 | 
			
		||||
                $persons[] = $row->getPerson2();
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user