mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-30 02:25:00 +00:00
Compare commits
2 Commits
fix-timeli
...
fix-person
Author | SHA1 | Date | |
---|---|---|---|
7d130277d6 | |||
1b6aa7f1a1 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,8 +1,8 @@
|
|||||||
.composer/*
|
.composer/*
|
||||||
composer.phar
|
composer.phar
|
||||||
composer.lock
|
composer.lock
|
||||||
|
|
||||||
docs/build/
|
docs/build/
|
||||||
.php_cs.cache
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
/.env.local
|
/.env.local
|
||||||
@@ -19,4 +19,3 @@ docs/build/
|
|||||||
/phpunit.xml
|
/phpunit.xml
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
###< phpunit/phpunit ###
|
###< phpunit/phpunit ###
|
||||||
|
|
||||||
|
@@ -30,10 +30,6 @@ variables:
|
|||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
# fetch the chill-app using git submodules
|
# fetch the chill-app using git submodules
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
REDIS_HOST: redis
|
|
||||||
REDIS_PORT: 6379
|
|
||||||
REDIS_URL: redis://redis:6379
|
|
||||||
|
|
||||||
|
|
||||||
# Run our tests
|
# Run our tests
|
||||||
test:
|
test:
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
# Chill framework
|
|
||||||
|
|
||||||
Documentation of the Chill software.
|
|
||||||
|
|
||||||
The online documentation can be found at http://docs.chill.social
|
|
||||||
|
|
||||||
See the [`docs`][1] directory for more.
|
|
||||||
|
|
||||||
[1]: docs/README.md
|
|
@@ -1,453 +0,0 @@
|
|||||||
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
|
|
||||||
Permission is granted to copy, distribute and/or modify this document
|
|
||||||
under the terms of the GNU Free Documentation License, Version 1.3
|
|
||||||
or any later version published by the Free Software Foundation;
|
|
||||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
|
||||||
A copy of the license is included in the section entitled "GNU
|
|
||||||
Free Documentation License".
|
|
||||||
|
|
||||||
.. _api:
|
|
||||||
|
|
||||||
API
|
|
||||||
###
|
|
||||||
|
|
||||||
Chill provides a basic framework to build REST api.
|
|
||||||
|
|
||||||
Configure a route
|
|
||||||
=================
|
|
||||||
|
|
||||||
Follow those steps to build a REST api:
|
|
||||||
|
|
||||||
1. Create your model;
|
|
||||||
2. Configure the API;
|
|
||||||
|
|
||||||
You can also:
|
|
||||||
|
|
||||||
* hook into the controller to customize some steps;
|
|
||||||
* add more route and steps
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Useful links:
|
|
||||||
|
|
||||||
* `How to use annotation to configure serialization <https://symfony.com/doc/current/serializer.html>`_
|
|
||||||
* `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`:
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
chill_cruds:
|
|
||||||
resource: 'chill_main_crud_route_loader:load'
|
|
||||||
type: service
|
|
||||||
|
|
||||||
|
|
||||||
Create your model
|
|
||||||
*****************
|
|
||||||
|
|
||||||
Create your model on the usual way:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\OriginRepository;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=OriginRepository::class)
|
|
||||||
* @ORM\Table(name="chill_person_accompanying_period_origin")
|
|
||||||
*/
|
|
||||||
class Origin
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="json")
|
|
||||||
*/
|
|
||||||
private $label;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="date_immutable", nullable=true)
|
|
||||||
*/
|
|
||||||
private $noActiveAfter;
|
|
||||||
|
|
||||||
// .. getters and setters
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Configure api
|
|
||||||
*************
|
|
||||||
|
|
||||||
Configure the api using Yaml (see the full configuration: :ref:`api_full_configuration`):
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
# config/packages/chill_main.yaml
|
|
||||||
chill_main:
|
|
||||||
apis:
|
|
||||||
accompanying_period_origin:
|
|
||||||
base_path: '/api/1.0/person/accompanying-period/origin'
|
|
||||||
class: 'Chill\PersonBundle\Entity\AccompanyingPeriod\Origin'
|
|
||||||
name: accompanying_period_origin
|
|
||||||
base_role: 'ROLE_USER'
|
|
||||||
actions:
|
|
||||||
_index:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
_entity:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If you are working on a shared bundle (aka "The chill bundles"), you should define your configuration inside the class :code:`ChillXXXXBundleExtension`, using the "prependConfig" feature:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\DependencyInjection;
|
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
||||||
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ChillPersonExtension
|
|
||||||
* Loads and manages your bundle configuration
|
|
||||||
*
|
|
||||||
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
|
|
||||||
* @package Chill\PersonBundle\DependencyInjection
|
|
||||||
*/
|
|
||||||
class ChillPersonExtension extends Extension implements PrependExtensionInterface
|
|
||||||
{
|
|
||||||
public function prepend(ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
$this->prependCruds($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ContainerBuilder $container
|
|
||||||
*/
|
|
||||||
protected function prependCruds(ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
$container->prependExtensionConfig('chill_main', [
|
|
||||||
'apis' => [
|
|
||||||
[
|
|
||||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Origin::class,
|
|
||||||
'name' => 'accompanying_period_origin',
|
|
||||||
'base_path' => '/api/1.0/person/accompanying-period/origin',
|
|
||||||
'controller' => \Chill\PersonBundle\Controller\OpeningApiController::class,
|
|
||||||
'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
|
|
||||||
]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The :code:`_index` and :code:`_entity` action
|
|
||||||
=============================================
|
|
||||||
|
|
||||||
The :code:`_index` and :code:`_entity` action are default actions:
|
|
||||||
|
|
||||||
* they will call a specific method in the default controller;
|
|
||||||
* they will generate defined routes:
|
|
||||||
|
|
||||||
Index:
|
|
||||||
Name: :code:`chill_api_single_accompanying_period_origin__index`
|
|
||||||
|
|
||||||
Path: :code:`/api/1.0/person/accompanying-period/origin.{_format}`
|
|
||||||
|
|
||||||
Entity:
|
|
||||||
Name: :code:`chill_api_single_accompanying_period_origin__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.
|
|
||||||
|
|
||||||
For index action, the role will be called with :code:`NULL` as :code:`$subject`. The retrieved entity will be the subject for single queries.
|
|
||||||
|
|
||||||
You can also define a role for each method. In this case, this role is used for the given method, and, if any, the base role is taken into account.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
# config/packages/chill_main.yaml
|
|
||||||
chill_main:
|
|
||||||
apis:
|
|
||||||
accompanying_period_origin:
|
|
||||||
base_path: '/api/1.0/person/bla/bla'
|
|
||||||
class: 'Chill\PersonBundle\Entity\Blah'
|
|
||||||
name: bla
|
|
||||||
actions:
|
|
||||||
_entity:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
roles:
|
|
||||||
GET: MY_ROLE_SEE
|
|
||||||
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`.
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Controller;
|
|
||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class OpeningApiController extends ApiController
|
|
||||||
{
|
|
||||||
protected function customizeQuery(string $action, Request $request, $qb): void
|
|
||||||
{
|
|
||||||
$qb->where($qb->expr()->gt('e.noActiveAfter', ':now'))
|
|
||||||
->orWhere($qb->expr()->isNull('e.noActiveAfter'));
|
|
||||||
$qb->setParameter('now', new \DateTime('now'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
And set your controller in configuration:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
chill_main:
|
|
||||||
apis:
|
|
||||||
accompanying_period_origin:
|
|
||||||
base_path: '/api/1.0/person/accompanying-period/origin'
|
|
||||||
class: 'Chill\PersonBundle\Entity\AccompanyingPeriod\Origin'
|
|
||||||
name: accompanying_period_origin
|
|
||||||
# add a controller
|
|
||||||
controller: 'Chill\PersonBundle\Controller\OpeningApiController'
|
|
||||||
base_role: 'ROLE_USER'
|
|
||||||
actions:
|
|
||||||
_index:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
_entity:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
|
|
||||||
Create your own actions
|
|
||||||
=======================
|
|
||||||
|
|
||||||
You can add your own actions:
|
|
||||||
|
|
||||||
.. 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:
|
|
||||||
# add a custom participation:
|
|
||||||
participation:
|
|
||||||
methods:
|
|
||||||
POST: true
|
|
||||||
DELETE: true
|
|
||||||
GET: false
|
|
||||||
HEAD: false
|
|
||||||
PUT: false
|
|
||||||
roles:
|
|
||||||
POST: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
|
||||||
DELETE: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
|
||||||
GET: null
|
|
||||||
HEAD: null
|
|
||||||
PUT: null
|
|
||||||
single-collection: single
|
|
||||||
|
|
||||||
The key :code:`single-collection` with value :code:`single` will add a :code:`/{id}/ + "action name"` (in this example, :code:`/{id}/participation`) into the path, after the base path. If the value is :code:`collection`, no id will be set, but the action name will be append to the path.
|
|
||||||
|
|
||||||
Then, create the corresponding action into your controller:
|
|
||||||
|
|
||||||
.. 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\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;
|
|
||||||
|
|
||||||
class AccompanyingCourseApiController extends ApiController
|
|
||||||
{
|
|
||||||
protected EventDispatcherInterface $eventDispatcher;
|
|
||||||
|
|
||||||
protected ValidatorInterface $validator;
|
|
||||||
|
|
||||||
public function __construct(EventDispatcherInterface $eventDispatcher, $validator)
|
|
||||||
{
|
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
|
||||||
$this->validator = $validator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function participationApi($id, Request $request, $_format)
|
|
||||||
{
|
|
||||||
/** @var AccompanyingPeriod $accompanyingPeriod */
|
|
||||||
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
|
|
||||||
$person = $this->getSerializer()
|
|
||||||
->deserialize($request->getContent(), Person::class, $_format, []);
|
|
||||||
|
|
||||||
if (NULL === $person) {
|
|
||||||
throw new BadRequestException('person id not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->onPostCheckACL('participation', $request, $accompanyingPeriod, $_format);
|
|
||||||
|
|
||||||
switch ($request->getMethod()) {
|
|
||||||
case Request::METHOD_POST:
|
|
||||||
$participation = $accompanyingPeriod->addPerson($person);
|
|
||||||
break;
|
|
||||||
case Request::METHOD_DELETE:
|
|
||||||
$participation = $accompanyingPeriod->removePerson($person);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new BadRequestException("This method is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
$errors = $this->validator->validate($accompanyingPeriod);
|
|
||||||
|
|
||||||
if ($errors->count() > 0) {
|
|
||||||
// only format accepted
|
|
||||||
return $this->json($errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->getDoctrine()->getManager()->flush();
|
|
||||||
|
|
||||||
return $this->json($participation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Serialization for collection
|
|
||||||
============================
|
|
||||||
|
|
||||||
A specific model has been defined for returning collection:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"count": 49,
|
|
||||||
"results": [
|
|
||||||
],
|
|
||||||
"pagination": {
|
|
||||||
"more": true,
|
|
||||||
"next": "/api/1.0/search.json&q=xxxx......&page=2",
|
|
||||||
"previous": null,
|
|
||||||
"first": 0,
|
|
||||||
"items_per_page": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
|
|
||||||
class MyController extends AbstractController
|
|
||||||
{
|
|
||||||
|
|
||||||
protected function serializeCollection(PaginatorInterface $paginator, $entities): Response
|
|
||||||
{
|
|
||||||
$model = new Collection($entities, $paginator);
|
|
||||||
|
|
||||||
return $this->json($model, Response::HTTP_OK, [], $context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. _api_full_configuration:
|
|
||||||
|
|
||||||
Full configuration example
|
|
||||||
==========================
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
apis:
|
|
||||||
-
|
|
||||||
class: Chill\PersonBundle\Entity\AccompanyingPeriod
|
|
||||||
name: accompanying_course
|
|
||||||
base_path: /api/1.0/person/accompanying-course
|
|
||||||
controller: Chill\PersonBundle\Controller\AccompanyingCourseApiController
|
|
||||||
actions:
|
|
||||||
_entity:
|
|
||||||
roles:
|
|
||||||
GET: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
|
||||||
HEAD: null
|
|
||||||
POST: null
|
|
||||||
DELETE: null
|
|
||||||
PUT: null
|
|
||||||
controller_action: null
|
|
||||||
path: null
|
|
||||||
single-collection: single
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
POST: false
|
|
||||||
DELETE: false
|
|
||||||
PUT: false
|
|
||||||
participation:
|
|
||||||
methods:
|
|
||||||
POST: true
|
|
||||||
DELETE: true
|
|
||||||
GET: false
|
|
||||||
HEAD: false
|
|
||||||
PUT: false
|
|
||||||
roles:
|
|
||||||
POST: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
|
||||||
DELETE: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
|
||||||
GET: null
|
|
||||||
HEAD: null
|
|
||||||
PUT: null
|
|
||||||
controller_action: null
|
|
||||||
# the requirements for the route. Will be set to `[ 'id' => '\d+' ]` if left empty.
|
|
||||||
requirements: []
|
|
||||||
path: null
|
|
||||||
single-collection: single
|
|
||||||
base_role: null
|
|
||||||
|
|
||||||
|
|
@@ -16,7 +16,6 @@ As Chill rely on the `symfony <http://symfony.com>`_ framework, reading the fram
|
|||||||
|
|
||||||
Instructions to create a new bundle <create-a-new-bundle.rst>
|
Instructions to create a new bundle <create-a-new-bundle.rst>
|
||||||
CRUD (Create - Update - Delete) for one entity <crud.rst>
|
CRUD (Create - Update - Delete) for one entity <crud.rst>
|
||||||
Helpers for building a REST API <api.rst>
|
|
||||||
Routing <routing.rst>
|
Routing <routing.rst>
|
||||||
Menus <menus.rst>
|
Menus <menus.rst>
|
||||||
Forms <forms.rst>
|
Forms <forms.rst>
|
||||||
|
@@ -7,8 +7,6 @@
|
|||||||
Free Documentation License".
|
Free Documentation License".
|
||||||
|
|
||||||
|
|
||||||
.. _pagination-ref:
|
|
||||||
|
|
||||||
Pagination
|
Pagination
|
||||||
##########
|
##########
|
||||||
|
|
||||||
@@ -17,7 +15,7 @@ The Bundle :code:`Chill\MainBundle` provides a **Pagination** api which allow yo
|
|||||||
A simple example
|
A simple example
|
||||||
****************
|
****************
|
||||||
|
|
||||||
In the controller, get the :code:`Chill\Main\Pagination\PaginatorFactory` from the `Container` and use this :code:`PaginatorFactory` to create a :code:`Paginator` instance.
|
In the controller, get the :class:`Chill\Main\Pagination\PaginatorFactory` from the `Container` and use this :code:`PaginatorFactory` to create a :code:`Paginator` instance.
|
||||||
|
|
||||||
|
|
||||||
.. literalinclude:: pagination/example.php
|
.. literalinclude:: pagination/example.php
|
||||||
|
@@ -18,11 +18,11 @@
|
|||||||
<testsuite name="MainBundle">
|
<testsuite name="MainBundle">
|
||||||
<directory suffix="Test.php">src/Bundle/ChillMainBundle/Tests/</directory>
|
<directory suffix="Test.php">src/Bundle/ChillMainBundle/Tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
<!--
|
|
||||||
<testsuite name="PersonBundle">
|
<testsuite name="PersonBundle">
|
||||||
<directory suffix="Test.php">src/Bundle/ChillPersonBundle/Tests/</directory>
|
<directory suffix="Test.php">src/Bundle/ChillPersonBundle/Tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
-->
|
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
|
||||||
<listeners>
|
<listeners>
|
||||||
|
@@ -1,77 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 Champs Libres Cooperative <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\MainBundle\CRUD\CompilerPass;
|
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
|
||||||
use Chill\MainBundle\Routing\MenuComposer;
|
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class CRUDControllerCompilerPass implements CompilerPassInterface
|
|
||||||
{
|
|
||||||
public function process(ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
$crudConfig = $container->getParameter('chill_main_crud_route_loader_config');
|
|
||||||
$apiConfig = $container->getParameter('chill_main_api_route_loader_config');
|
|
||||||
|
|
||||||
foreach ($crudConfig as $crudEntry) {
|
|
||||||
$this->configureCrudController($container, $crudEntry, 'crud');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($apiConfig as $crudEntry) {
|
|
||||||
$this->configureCrudController($container, $crudEntry, 'api');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a controller for each definition, and add a methodCall to inject crud configuration to controller
|
|
||||||
*/
|
|
||||||
private function configureCrudController(ContainerBuilder $container, array $crudEntry, string $apiOrCrud): void
|
|
||||||
{
|
|
||||||
$controllerClass = $crudEntry['controller'];
|
|
||||||
|
|
||||||
$controllerServiceName = 'cs'.$apiOrCrud.'_'.$crudEntry['name'].'_controller';
|
|
||||||
|
|
||||||
if ($container->hasDefinition($controllerClass)) {
|
|
||||||
$controller = $container->getDefinition($controllerClass);
|
|
||||||
$container->removeDefinition($controllerClass);
|
|
||||||
$alreadyDefined = true;
|
|
||||||
} else {
|
|
||||||
$controller = new Definition($controllerClass);
|
|
||||||
$alreadyDefined = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$controller->addTag('controller.service_arguments');
|
|
||||||
if (FALSE === $alreadyDefined) {
|
|
||||||
$controller->setAutoconfigured(true);
|
|
||||||
$controller->setPublic(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
|
||||||
$container->setParameter($param, $crudEntry);
|
|
||||||
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
|
||||||
|
|
||||||
$container->setDefinition($controllerServiceName, $controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,225 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\CRUD\Controller;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
|
|
||||||
class AbstractCRUDController extends AbstractController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The crud configuration
|
|
||||||
*
|
|
||||||
* This configuration si defined by `chill_main['crud']` or `chill_main['apis']`
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected array $crudConfig = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the instance of the entity with the given id
|
|
||||||
*
|
|
||||||
* @param string $id
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
protected function getEntity($action, $id, Request $request): ?object
|
|
||||||
{
|
|
||||||
return $this->getDoctrine()
|
|
||||||
->getRepository($this->getEntityClass())
|
|
||||||
->find($id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count the number of entities
|
|
||||||
*
|
|
||||||
* By default, count all entities. You can customize the query by
|
|
||||||
* using the method `customizeQuery`.
|
|
||||||
*
|
|
||||||
* @param string $action
|
|
||||||
* @param Request $request
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
protected function countEntities(string $action, Request $request, $_format): int
|
|
||||||
{
|
|
||||||
return $this->buildQueryEntities($action, $request)
|
|
||||||
->select('COUNT(e)')
|
|
||||||
->getQuery()
|
|
||||||
->getSingleScalarResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the entity.
|
|
||||||
*
|
|
||||||
* By default, get all entities. You can customize the query by using the
|
|
||||||
* method `customizeQuery`.
|
|
||||||
*
|
|
||||||
* The method `orderEntity` is called internally to order entities.
|
|
||||||
*
|
|
||||||
* It returns, by default, a query builder.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function queryEntities(string $action, Request $request, string $_format, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
$query = $this->buildQueryEntities($action, $request)
|
|
||||||
->setFirstResult($paginator->getCurrentPage()->getFirstItemNumber())
|
|
||||||
->setMaxResults($paginator->getItemsPerPage());
|
|
||||||
|
|
||||||
// allow to order queries and return the new query
|
|
||||||
return $this->orderQuery($action, $query, $request, $paginator, $_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add ordering fields in the query build by self::queryEntities
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
|
|
||||||
{
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build the base query for listing all entities.
|
|
||||||
*
|
|
||||||
* This method is used internally by `countEntities` `queryEntities`
|
|
||||||
*
|
|
||||||
* This base query does not contains any `WHERE` or `SELECT` clauses. You
|
|
||||||
* can add some by using the method `customizeQuery`.
|
|
||||||
*
|
|
||||||
* The alias for the entity is "e".
|
|
||||||
*
|
|
||||||
* @param string $action
|
|
||||||
* @param Request $request
|
|
||||||
* @return QueryBuilder
|
|
||||||
*/
|
|
||||||
protected function buildQueryEntities(string $action, Request $request)
|
|
||||||
{
|
|
||||||
$qb = $this->getDoctrine()->getManager()
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('e')
|
|
||||||
->from($this->getEntityClass(), 'e')
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->customizeQuery($action, $request, $qb);
|
|
||||||
|
|
||||||
return $qb;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function customizeQuery(string $action, Request $request, $query): void {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the result of the query
|
|
||||||
*/
|
|
||||||
protected function getQueryResult(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query)
|
|
||||||
{
|
|
||||||
return $query->getQuery()->getResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function onPreIndex(string $action, Request $request, string $_format): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* method used by indexAction
|
|
||||||
*/
|
|
||||||
protected function onPreIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* method used by indexAction
|
|
||||||
*/
|
|
||||||
protected function onPostIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* method used by indexAction
|
|
||||||
*/
|
|
||||||
protected function onPostIndexFetchQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $entities): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the complete FQDN of the class
|
|
||||||
*
|
|
||||||
* @return string the complete fqdn of the class
|
|
||||||
*/
|
|
||||||
protected function getEntityClass(): string
|
|
||||||
{
|
|
||||||
return $this->crudConfig['class'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* called on post fetch entity
|
|
||||||
*/
|
|
||||||
protected function onPostFetchEntity(string $action, Request $request, $entity, $_format): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called on post check ACL
|
|
||||||
*/
|
|
||||||
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check the acl. Called by every action.
|
|
||||||
*
|
|
||||||
* By default, check the role given by `getRoleFor` for the value given in
|
|
||||||
* $entity.
|
|
||||||
*
|
|
||||||
* Throw an \Symfony\Component\Security\Core\Exception\AccessDeniedHttpException
|
|
||||||
* if not accessible.
|
|
||||||
*
|
|
||||||
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedHttpException
|
|
||||||
*/
|
|
||||||
protected function checkACL(string $action, Request $request, string $_format, $entity = null)
|
|
||||||
{
|
|
||||||
$this->denyAccessUnlessGranted($this->getRoleFor($action, $request, $entity, $_format), $entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return string the crud name
|
|
||||||
*/
|
|
||||||
protected function getCrudName(): string
|
|
||||||
{
|
|
||||||
return $this->crudConfig['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getActionConfig(string $action)
|
|
||||||
{
|
|
||||||
return $this->crudConfig['actions'][$action];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the crud configuration
|
|
||||||
*
|
|
||||||
* Used by the container to inject configuration for this crud.
|
|
||||||
*/
|
|
||||||
public function setCrudConfig(array $config): void
|
|
||||||
{
|
|
||||||
$this->crudConfig = $config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return PaginatorFactory
|
|
||||||
*/
|
|
||||||
protected function getPaginatorFactory(): PaginatorFactory
|
|
||||||
{
|
|
||||||
return $this->container->get('chill_main.paginator_factory');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,220 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\CRUD\Controller;
|
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
|
|
||||||
class ApiController extends AbstractCRUDController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The view action.
|
|
||||||
*
|
|
||||||
* Some steps may be overriden during this process of rendering:
|
|
||||||
*
|
|
||||||
* This method:
|
|
||||||
*
|
|
||||||
* 1. fetch the entity, using `getEntity`
|
|
||||||
* 2. launch `onPostFetchEntity`. If postfetch is an instance of Response,
|
|
||||||
* this response is returned.
|
|
||||||
* 2. throw an HttpNotFoundException if entity is null
|
|
||||||
* 3. check ACL using `checkACL` ;
|
|
||||||
* 4. launch `onPostCheckACL`. If the result is an instance of Response,
|
|
||||||
* this response is returned ;
|
|
||||||
* 5. Serialize the entity and return the result. The serialization context is given by `getSerializationContext`
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function entityGet(string $action, Request $request, $id, $_format = 'html'): 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($_format === 'json') {
|
|
||||||
$context = $this->getContextForSerialization($action, $request, $_format, $entity);
|
|
||||||
|
|
||||||
return $this->json($entity, Response::HTTP_OK, [], $context);
|
|
||||||
} else {
|
|
||||||
throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This format is not implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onBeforeSerialize(string $action, Request $request, $_format, $entity): ?Response
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base method for handling api action
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function entityApi(Request $request, $id, $_format): Response
|
|
||||||
{
|
|
||||||
switch ($request->getMethod()) {
|
|
||||||
case Request::METHOD_GET:
|
|
||||||
case REQUEST::METHOD_HEAD:
|
|
||||||
return $this->entityGet('_entity', $request, $id, $_format);
|
|
||||||
default:
|
|
||||||
throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This method is not implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base action for indexing entities
|
|
||||||
*/
|
|
||||||
public function indexApi(Request $request, string $_format)
|
|
||||||
{
|
|
||||||
switch ($request->getMethod()) {
|
|
||||||
case Request::METHOD_GET:
|
|
||||||
case REQUEST::METHOD_HEAD:
|
|
||||||
return $this->indexApiAction('_index', $request, $_format);
|
|
||||||
default:
|
|
||||||
throw $this->createNotFoundException("This method is not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build an index page.
|
|
||||||
*
|
|
||||||
* Some steps may be overriden during this process of rendering.
|
|
||||||
*
|
|
||||||
* This method:
|
|
||||||
*
|
|
||||||
* 1. Launch `onPreIndex`
|
|
||||||
* x. check acl. If it does return a response instance, return it
|
|
||||||
* x. launch `onPostCheckACL`. If it does return a response instance, return it
|
|
||||||
* 1. count the items, using `countEntities`
|
|
||||||
* 2. build a paginator element from the the number of entities ;
|
|
||||||
* 3. Launch `onPreIndexQuery`. If it does return a response instance, return it
|
|
||||||
* 3. build a query, using `queryEntities`
|
|
||||||
* x. fetch the results, using `getQueryResult`
|
|
||||||
* x. Launch `onPostIndexFetchQuery`. If it does return a response instance, return it
|
|
||||||
* 4. Serialize the entities in a Collection, using `SerializeCollection`
|
|
||||||
*
|
|
||||||
* @param string $action
|
|
||||||
* @param Request $request
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
protected function indexApiAction($action, Request $request, $_format)
|
|
||||||
{
|
|
||||||
$this->onPreIndex($action, $request, $_format);
|
|
||||||
|
|
||||||
$response = $this->checkACL($action, $request, $_format);
|
|
||||||
if ($response instanceof Response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($entity)) {
|
|
||||||
$entity = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $this->onPostCheckACL($action, $request, $_format, $entity);
|
|
||||||
if ($response instanceof Response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$totalItems = $this->countEntities($action, $request, $_format);
|
|
||||||
$paginator = $this->getPaginatorFactory()->create($totalItems);
|
|
||||||
|
|
||||||
$response = $this->onPreIndexBuildQuery($action, $request, $_format, $totalItems,
|
|
||||||
$paginator);
|
|
||||||
|
|
||||||
if ($response instanceof Response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $this->queryEntities($action, $request, $_format, $paginator);
|
|
||||||
|
|
||||||
$response = $this->onPostIndexBuildQuery($action, $request, $_format, $totalItems,
|
|
||||||
$paginator, $query);
|
|
||||||
|
|
||||||
if ($response instanceof Response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$entities = $this->getQueryResult($action, $request, $_format, $totalItems, $paginator, $query);
|
|
||||||
|
|
||||||
$response = $this->onPostIndexFetchQuery($action, $request, $_format, $totalItems,
|
|
||||||
$paginator, $entities);
|
|
||||||
|
|
||||||
if ($response instanceof Response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->serializeCollection($action, $request, $_format, $paginator, $entities);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize collections
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function serializeCollection(string $action, Request $request, string $_format, PaginatorInterface $paginator, $entities): Response
|
|
||||||
{
|
|
||||||
$model = new Collection($entities, $paginator);
|
|
||||||
|
|
||||||
$context = $this->getContextForSerialization($action, $request, $_format, $entities);
|
|
||||||
|
|
||||||
return $this->json($model, Response::HTTP_OK, [], $context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function getContextForSerialization(string $action, Request $request, string $_format, $entity): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the role given from the config.
|
|
||||||
*/
|
|
||||||
protected function getRoleFor(string $action, Request $request, $entity, $_format): string
|
|
||||||
{
|
|
||||||
$actionConfig = $this->getActionConfig($action);
|
|
||||||
|
|
||||||
if (NULL !== $actionConfig['roles'][$request->getMethod()]) {
|
|
||||||
return $actionConfig['roles'][$request->getMethod()];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->crudConfig['base_role']) {
|
|
||||||
return $this->crudConfig['base_role'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \RuntimeException(sprintf("the config does not have any role for the ".
|
|
||||||
"method %s nor a global role for the whole action. Add those to your ".
|
|
||||||
"configuration or override the required method", $request->getMethod()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getSerializer(): SerializerInterface
|
|
||||||
{
|
|
||||||
return $this->get('serializer');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -34,7 +34,6 @@ use Chill\MainBundle\CRUD\Form\CRUDDeleteEntityForm;
|
|||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CRUDController
|
* Class CRUDController
|
||||||
@@ -485,7 +484,7 @@ class CRUDController extends AbstractController
|
|||||||
* @param mixed $id
|
* @param mixed $id
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
protected function viewAction(string $action, Request $request, $id, $_format = 'html'): Response
|
protected function viewAction(string $action, Request $request, $id)
|
||||||
{
|
{
|
||||||
$entity = $this->getEntity($action, $id, $request);
|
$entity = $this->getEntity($action, $id, $request);
|
||||||
|
|
||||||
@@ -497,7 +496,7 @@ class CRUDController extends AbstractController
|
|||||||
|
|
||||||
if (NULL === $entity) {
|
if (NULL === $entity) {
|
||||||
throw $this->createNotFoundException(sprintf("The %s with id %s "
|
throw $this->createNotFoundException(sprintf("The %s with id %s "
|
||||||
. "is not found", $this->getCrudName(), $id));
|
. "is not found"), $this->getCrudName(), $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->checkACL($action, $entity);
|
$response = $this->checkACL($action, $entity);
|
||||||
@@ -510,36 +509,17 @@ class CRUDController extends AbstractController
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_format === 'html') {
|
$defaultTemplateParameters = [
|
||||||
$defaultTemplateParameters = [
|
'entity' => $entity,
|
||||||
'entity' => $entity,
|
'crud_name' => $this->getCrudName()
|
||||||
'crud_name' => $this->getCrudName()
|
];
|
||||||
];
|
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
$this->getTemplateFor($action, $entity, $request),
|
$this->getTemplateFor($action, $entity, $request),
|
||||||
$this->generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters)
|
$this->generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters)
|
||||||
);
|
);
|
||||||
} elseif ($_format === 'json') {
|
|
||||||
$context = $this->getContextForSerialization($action, $request, $entity, $_format);
|
|
||||||
|
|
||||||
return $this->json($entity, Response::HTTP_OK, [], $context);
|
|
||||||
} else {
|
|
||||||
throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This format is not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the context for the serialization
|
|
||||||
*/
|
|
||||||
public function getContextForSerialization(string $action, Request $request, $entity, string $_format): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The edit action.
|
* The edit action.
|
||||||
*
|
*
|
||||||
@@ -819,7 +799,7 @@ class CRUDController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
protected function getRoleFor($action)
|
protected function getRoleFor($action)
|
||||||
{
|
{
|
||||||
if (\array_key_exists('role', $this->getActionConfig($action))) {
|
if (NULL !== ($this->getActionConfig($action)['role'])) {
|
||||||
return $this->getActionConfig($action)['role'];
|
return $this->getActionConfig($action)['role'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1201,7 +1181,6 @@ class CRUDController extends AbstractController
|
|||||||
AuthorizationHelper::class => AuthorizationHelper::class,
|
AuthorizationHelper::class => AuthorizationHelper::class,
|
||||||
EventDispatcherInterface::class => EventDispatcherInterface::class,
|
EventDispatcherInterface::class => EventDispatcherInterface::class,
|
||||||
Resolver::class => Resolver::class,
|
Resolver::class => Resolver::class,
|
||||||
SerializerInterface::class => SerializerInterface::class,
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -23,9 +23,6 @@ namespace Chill\MainBundle\CRUD\Routing;
|
|||||||
use Symfony\Component\Config\Loader\Loader;
|
use Symfony\Component\Config\Loader\Loader;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
|
||||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CRUDRoutesLoader
|
* Class CRUDRoutesLoader
|
||||||
@@ -35,34 +32,24 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
|
|||||||
*/
|
*/
|
||||||
class CRUDRoutesLoader extends Loader
|
class CRUDRoutesLoader extends Loader
|
||||||
{
|
{
|
||||||
protected array $crudConfig = [];
|
/**
|
||||||
|
* @var array
|
||||||
protected array $apiCrudConfig = [];
|
*/
|
||||||
|
protected $config = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $isLoaded = false;
|
private $isLoaded = false;
|
||||||
|
|
||||||
private const ALL_SINGLE_METHODS = [
|
|
||||||
Request::METHOD_GET,
|
|
||||||
Request::METHOD_POST,
|
|
||||||
Request::METHOD_PUT,
|
|
||||||
Request::METHOD_DELETE
|
|
||||||
];
|
|
||||||
|
|
||||||
private const ALL_INDEX_METHODS = [ Request::METHOD_GET, Request::METHOD_HEAD ];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRUDRoutesLoader constructor.
|
* CRUDRoutesLoader constructor.
|
||||||
*
|
*
|
||||||
* @param $crudConfig the config from cruds
|
* @param $config
|
||||||
* @param $apicrudConfig the config from api_crud
|
|
||||||
*/
|
*/
|
||||||
public function __construct(array $crudConfig, array $apiConfig)
|
public function __construct($config)
|
||||||
{
|
{
|
||||||
$this->crudConfig = $crudConfig;
|
$this->config = $config;
|
||||||
$this->apiConfig = $apiConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,159 +63,51 @@ class CRUDRoutesLoader extends Loader
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load routes for CRUD and CRUD Api
|
* @return RouteCollection
|
||||||
*/
|
*/
|
||||||
public function load($resource, $type = null): RouteCollection
|
public function load($resource, $type = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (true === $this->isLoaded) {
|
if (true === $this->isLoaded) {
|
||||||
throw new \RuntimeException('Do not add the "CRUD" loader twice');
|
throw new \RuntimeException('Do not add the "CRUD" loader twice');
|
||||||
}
|
}
|
||||||
|
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
|
|
||||||
foreach ($this->crudConfig as $crudConfig) {
|
foreach ($this->config as $config) {
|
||||||
$collection->addCollection($this->loadCrudConfig($crudConfig));
|
$collection->addCollection($this->loadConfig($config));
|
||||||
}
|
|
||||||
foreach ($this->apiConfig as $crudConfig) {
|
|
||||||
$collection->addCollection($this->loadApi($crudConfig));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $collection;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load routes for CRUD (without api)
|
* @param $config
|
||||||
*
|
|
||||||
* @param $crudConfig
|
|
||||||
* @return RouteCollection
|
* @return RouteCollection
|
||||||
*/
|
*/
|
||||||
protected function loadCrudConfig($crudConfig): RouteCollection
|
protected function loadConfig($config): RouteCollection
|
||||||
{
|
{
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
$controller ='cscrud_'.$crudConfig['name'].'_controller';
|
foreach ($config['actions'] as $name => $action) {
|
||||||
|
|
||||||
foreach ($crudConfig['actions'] as $name => $action) {
|
|
||||||
// defaults (controller name)
|
|
||||||
$defaults = [
|
$defaults = [
|
||||||
'_controller' => $controller.':'.($action['controller_action'] ?? $name)
|
'_controller' => 'cscrud_'.$config['name'].'_controller'.':'.($action['controller_action'] ?? $name)
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($name === 'index') {
|
if ($name === 'index') {
|
||||||
$path = "{_locale}".$crudConfig['base_path'];
|
$path = "{_locale}".$config['base_path'];
|
||||||
$route = new Route($path, $defaults);
|
$route = new Route($path, $defaults);
|
||||||
} elseif ($name === 'new') {
|
} elseif ($name === 'new') {
|
||||||
$path = "{_locale}".$crudConfig['base_path'].'/'.$name;
|
$path = "{_locale}".$config['base_path'].'/'.$name;
|
||||||
$route = new Route($path, $defaults);
|
$route = new Route($path, $defaults);
|
||||||
} else {
|
} else {
|
||||||
$path = "{_locale}".$crudConfig['base_path'].($action['path'] ?? '/{id}/'.$name);
|
$path = "{_locale}".$config['base_path'].($action['path'] ?? '/{id}/'.$name);
|
||||||
$requirements = $action['requirements'] ?? [
|
$requirements = $action['requirements'] ?? [
|
||||||
'{id}' => '\d+'
|
'{id}' => '\d+'
|
||||||
];
|
];
|
||||||
$route = new Route($path, $defaults, $requirements);
|
$route = new Route($path, $defaults, $requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
$collection->add('chill_crud_'.$crudConfig['name'].'_'.$name, $route);
|
$collection->add('chill_crud_'.$config['name'].'_'.$name, $route);
|
||||||
}
|
|
||||||
|
|
||||||
return $collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load routes for api single
|
|
||||||
*
|
|
||||||
* @param $crudConfig
|
|
||||||
* @return RouteCollection
|
|
||||||
*/
|
|
||||||
protected function loadApi(array $crudConfig): RouteCollection
|
|
||||||
{
|
|
||||||
$collection = new RouteCollection();
|
|
||||||
$controller ='csapi_'.$crudConfig['name'].'_controller';
|
|
||||||
|
|
||||||
foreach ($crudConfig['actions'] as $name => $action) {
|
|
||||||
// filter only on single actions
|
|
||||||
$singleCollection = $action['single-collection'] ?? $name === '_entity' ? 'single' : NULL;
|
|
||||||
if ('collection' === $singleCollection) {
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute default action
|
|
||||||
switch ($name) {
|
|
||||||
case '_entity':
|
|
||||||
$controllerAction = 'entityApi';
|
|
||||||
break;
|
|
||||||
case '_index':
|
|
||||||
$controllerAction = 'indexApi';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$controllerAction = $name.'Api';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$defaults = [
|
|
||||||
'_controller' => $controller.':'.($action['controller_action'] ?? $controllerAction)
|
|
||||||
];
|
|
||||||
|
|
||||||
// path are rewritten
|
|
||||||
// if name === 'default', we rewrite it to nothing :-)
|
|
||||||
$localName = \in_array($name, [ '_entity', '_index' ]) ? '' : '/'.$name;
|
|
||||||
if ('collection' === $action['single-collection'] || '_index' === $name) {
|
|
||||||
$localPath = $action['path'] ?? $localName.'.{_format}';
|
|
||||||
} else {
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load routes for api multi
|
|
||||||
*
|
|
||||||
* @param $crudConfig
|
|
||||||
* @return RouteCollection
|
|
||||||
*/
|
|
||||||
protected function loadApiMultiConfig(array $crudConfig): RouteCollection
|
|
||||||
{
|
|
||||||
$collection = new RouteCollection();
|
|
||||||
$controller ='csapi_'.$crudConfig['name'].'_controller';
|
|
||||||
|
|
||||||
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;
|
return $collection;
|
||||||
|
@@ -14,7 +14,6 @@ use Chill\MainBundle\DependencyInjection\CompilerPass\NotificationCounterCompile
|
|||||||
use Chill\MainBundle\DependencyInjection\CompilerPass\MenuCompilerPass;
|
use Chill\MainBundle\DependencyInjection\CompilerPass\MenuCompilerPass;
|
||||||
use Chill\MainBundle\DependencyInjection\CompilerPass\ACLFlagsCompilerPass;
|
use Chill\MainBundle\DependencyInjection\CompilerPass\ACLFlagsCompilerPass;
|
||||||
use Chill\MainBundle\DependencyInjection\CompilerPass\GroupingCenterCompilerPass;
|
use Chill\MainBundle\DependencyInjection\CompilerPass\GroupingCenterCompilerPass;
|
||||||
use Chill\MainBundle\CRUD\CompilerPass\CRUDControllerCompilerPass;
|
|
||||||
use Chill\MainBundle\Templating\Entity\CompilerPass as RenderEntityCompilerPass;
|
use Chill\MainBundle\Templating\Entity\CompilerPass as RenderEntityCompilerPass;
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +33,5 @@ class ChillMainBundle extends Bundle
|
|||||||
$container->addCompilerPass(new ACLFlagsCompilerPass());
|
$container->addCompilerPass(new ACLFlagsCompilerPass());
|
||||||
$container->addCompilerPass(new GroupingCenterCompilerPass());
|
$container->addCompilerPass(new GroupingCenterCompilerPass());
|
||||||
$container->addCompilerPass(new RenderEntityCompilerPass());
|
$container->addCompilerPass(new RenderEntityCompilerPass());
|
||||||
$container->addCompilerPass(new CRUDControllerCompilerPass());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Controller;
|
|
||||||
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Chill\MainBundle\Entity\Address;
|
|
||||||
use Chill\MainBundle\Entity\AddressReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class AddressController
|
|
||||||
*
|
|
||||||
* @package Chill\MainBundle\Controller
|
|
||||||
*/
|
|
||||||
class AddressController extends AbstractController
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get API Data for showing endpoint
|
|
||||||
*
|
|
||||||
* @Route(
|
|
||||||
* "/{_locale}/main/api/1.0/address/{address_id}/show.{_format}",
|
|
||||||
* name="chill_main_address_api_show"
|
|
||||||
* )
|
|
||||||
* @ParamConverter("address", options={"id": "address_id"})
|
|
||||||
*/
|
|
||||||
public function showAddress(Address $address, $_format): Response
|
|
||||||
{
|
|
||||||
// TODO check ACL ?
|
|
||||||
switch ($_format) {
|
|
||||||
case 'json':
|
|
||||||
return $this->json($address);
|
|
||||||
default:
|
|
||||||
throw new BadRequestException('Unsupported format');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get API Data for showing endpoint
|
|
||||||
*
|
|
||||||
* @Route(
|
|
||||||
* "/{_locale}/main/api/1.0/address-reference/{address_reference_id}/show.{_format}",
|
|
||||||
* name="chill_main_address_reference_api_show"
|
|
||||||
* )
|
|
||||||
* @ParamConverter("addressReference", options={"id": "address_reference_id"})
|
|
||||||
*/
|
|
||||||
public function showAddressReference(AddressReference $addressReference, $_format): Response
|
|
||||||
{
|
|
||||||
// TODO check ACL ?
|
|
||||||
switch ($_format) {
|
|
||||||
case 'json':
|
|
||||||
return $this->json($addressReference);
|
|
||||||
default:
|
|
||||||
throw new BadRequestException('Unsupported format');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\DataFixtures\ORM;
|
|
||||||
|
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
||||||
use Doctrine\Persistence\ObjectManager;
|
|
||||||
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
|
||||||
use Chill\MainBundle\Entity\AddressReference;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load reference addresses into database
|
|
||||||
*
|
|
||||||
* @author Champs Libres
|
|
||||||
*/
|
|
||||||
class LoadAddressReferences extends AbstractFixture implements ContainerAwareInterface, OrderedFixtureInterface {
|
|
||||||
|
|
||||||
|
|
||||||
protected $faker;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->faker = \Faker\Factory::create('fr_FR');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var ContainerInterface
|
|
||||||
*/
|
|
||||||
private $container;
|
|
||||||
|
|
||||||
public function setContainer(ContainerInterface $container = null)
|
|
||||||
{
|
|
||||||
$this->container = $container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOrder() {
|
|
||||||
return 51;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a random point
|
|
||||||
*
|
|
||||||
* @return Point
|
|
||||||
*/
|
|
||||||
private function getRandomPoint()
|
|
||||||
{
|
|
||||||
$lonBrussels = 4.35243;
|
|
||||||
$latBrussels = 50.84676;
|
|
||||||
$lon = $lonBrussels + 0.01 * rand(-5, 5);
|
|
||||||
$lat = $latBrussels + 0.01 * rand(-5, 5);
|
|
||||||
return Point::fromLonLat($lon, $lat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a random reference address
|
|
||||||
*
|
|
||||||
* @return AddressReference
|
|
||||||
*/
|
|
||||||
private function getRandomAddressReference()
|
|
||||||
{
|
|
||||||
$ar= new AddressReference();
|
|
||||||
|
|
||||||
$ar->setRefId($this->faker->numerify('ref-id-######'));
|
|
||||||
$ar->setStreet($this->faker->streetName);
|
|
||||||
$ar->setStreetNumber(rand(0,199));
|
|
||||||
$ar ->setPoint($this->getRandomPoint());
|
|
||||||
$ar->setPostcode($this->getReference(
|
|
||||||
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
|
|
||||||
));
|
|
||||||
|
|
||||||
$ar->setMunicipalityCode($ar->getPostcode()->getCode());
|
|
||||||
|
|
||||||
return $ar
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function load(ObjectManager $manager) {
|
|
||||||
|
|
||||||
echo "loading some reference address... \n";
|
|
||||||
|
|
||||||
for ($i=0; $i<10; $i++) {
|
|
||||||
$ar = $this->getRandomAddressReference();
|
|
||||||
$manager->persist($ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
$manager->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@@ -133,7 +133,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
|||||||
$loader->load('services/search.yaml');
|
$loader->load('services/search.yaml');
|
||||||
$loader->load('services/serializer.yaml');
|
$loader->load('services/serializer.yaml');
|
||||||
|
|
||||||
$this->configureCruds($container, $config['cruds'], $config['apis'], $loader);
|
$this->configureCruds($container, $config['cruds'], $loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,12 +188,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
|||||||
$container->prependExtensionConfig('doctrine', array(
|
$container->prependExtensionConfig('doctrine', array(
|
||||||
'dbal' => [
|
'dbal' => [
|
||||||
'types' => [
|
'types' => [
|
||||||
'dateinterval' => [
|
'dateinterval' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class
|
||||||
'class' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class
|
|
||||||
],
|
|
||||||
'point' => [
|
|
||||||
'class' => \Chill\MainBundle\Doctrine\Type\PointType::class
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
@@ -215,24 +210,51 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load parameter for configuration and set parameters for api
|
* @param ContainerBuilder $container
|
||||||
|
* @param array $config the config under 'cruds' key
|
||||||
|
* @return null
|
||||||
*/
|
*/
|
||||||
protected function configureCruds(
|
protected function configureCruds(ContainerBuilder $container, $config, Loader\YamlFileLoader $loader)
|
||||||
ContainerBuilder $container,
|
|
||||||
array $crudConfig,
|
|
||||||
array $apiConfig,
|
|
||||||
Loader\YamlFileLoader $loader
|
|
||||||
): void
|
|
||||||
{
|
{
|
||||||
if (count($crudConfig) === 0) {
|
if (count($config) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$loader->load('services/crud.yaml');
|
$loader->load('services/crud.yaml');
|
||||||
|
|
||||||
$container->setParameter('chill_main_crud_route_loader_config', $crudConfig);
|
$container->setParameter('chill_main_crud_route_loader_config', $config);
|
||||||
$container->setParameter('chill_main_api_route_loader_config', $apiConfig);
|
|
||||||
|
|
||||||
// Note: the controller are loaded inside compiler pass
|
$definition = new Definition();
|
||||||
|
$definition
|
||||||
|
->setClass(\Chill\MainBundle\CRUD\Routing\CRUDRoutesLoader::class)
|
||||||
|
->addArgument('%chill_main_crud_route_loader_config%')
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->setDefinition('chill_main_crud_route_loader', $definition);
|
||||||
|
|
||||||
|
$alreadyExistingNames = [];
|
||||||
|
|
||||||
|
foreach ($config as $crudEntry) {
|
||||||
|
$controller = $crudEntry['controller'];
|
||||||
|
$controllerServiceName = 'cscrud_'.$crudEntry['name'].'_controller';
|
||||||
|
$name = $crudEntry['name'];
|
||||||
|
|
||||||
|
// check for existing crud names
|
||||||
|
if (\in_array($name, $alreadyExistingNames)) {
|
||||||
|
throw new LogicException(sprintf("the name %s is defined twice in CRUD", $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$container->has($controllerServiceName)) {
|
||||||
|
$controllerDefinition = new Definition($controller);
|
||||||
|
$controllerDefinition->addTag('controller.service_arguments');
|
||||||
|
$controllerDefinition->setAutoconfigured(true);
|
||||||
|
$controllerDefinition->setClass($crudEntry['controller']);
|
||||||
|
$container->setDefinition($controllerServiceName, $controllerDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container->setParameter('chill_main_crud_config_'.$name, $crudEntry);
|
||||||
|
$container->getDefinition($controllerServiceName)
|
||||||
|
->addMethodCall('setCrudConfig', ['%chill_main_crud_config_'.$name.'%']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
|||||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||||
use Chill\MainBundle\DependencyInjection\Widget\AddWidgetConfigurationTrait;
|
use Chill\MainBundle\DependencyInjection\Widget\AddWidgetConfigurationTrait;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +140,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
->scalarNode('controller_action')
|
->scalarNode('controller_action')
|
||||||
->defaultNull()
|
->defaultNull()
|
||||||
->info('the method name to call in the route. Will be set to the action name if left empty.')
|
->info('the method name to call in the route. Will be set to the action name if left empty.')
|
||||||
->example("action")
|
->example("'action'")
|
||||||
->end()
|
->end()
|
||||||
->scalarNode('path')
|
->scalarNode('path')
|
||||||
->defaultNull()
|
->defaultNull()
|
||||||
@@ -169,78 +168,6 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
|
|
||||||
->end()
|
->end()
|
||||||
|
|
||||||
|
|
||||||
->arrayNode('apis')
|
|
||||||
->defaultValue([])
|
|
||||||
->arrayPrototype()
|
|
||||||
->children()
|
|
||||||
->scalarNode('class')->cannotBeEmpty()->isRequired()->end()
|
|
||||||
->scalarNode('controller')
|
|
||||||
->cannotBeEmpty()
|
|
||||||
->defaultValue(\Chill\MainBundle\CRUD\Controller\ApiController::class)
|
|
||||||
->end()
|
|
||||||
->scalarNode('name')->cannotBeEmpty()->isRequired()->end()
|
|
||||||
->scalarNode('base_path')->cannotBeEmpty()->isRequired()->end()
|
|
||||||
->scalarNode('base_role')->defaultNull()->end()
|
|
||||||
->arrayNode('actions')
|
|
||||||
->useAttributeAsKey('name')
|
|
||||||
->arrayPrototype()
|
|
||||||
->children()
|
|
||||||
->scalarNode('controller_action')
|
|
||||||
->defaultNull()
|
|
||||||
->info('the method name to call in the controller. Will be set to the concatenation '.
|
|
||||||
'of action name + \'Api\' if left empty.')
|
|
||||||
->example("showApi")
|
|
||||||
->end()
|
|
||||||
->scalarNode('path')
|
|
||||||
->defaultNull()
|
|
||||||
->info('the path that will be **appended** after the base path. Do not forget to add ' .
|
|
||||||
'arguments for the method. By default, will set to the action name, including an `{id}` '.
|
|
||||||
'parameter. A suffix of action name will be appended, except if the action name '.
|
|
||||||
'is "_entity".')
|
|
||||||
->example('/{id}/my-action')
|
|
||||||
->end()
|
|
||||||
->arrayNode('requirements')
|
|
||||||
->ignoreExtraKeys(false)
|
|
||||||
->info('the requirements for the route. Will be set to `[ \'id\' => \'\d+\' ]` if left empty.')
|
|
||||||
->end()
|
|
||||||
->enumNode('single-collection')
|
|
||||||
->values(['single', 'collection'])
|
|
||||||
->defaultValue('single')
|
|
||||||
->info('indicates if the returned object is a single element or a collection. '.
|
|
||||||
'If the action name is `_index`, this value will always be considered as '.
|
|
||||||
'`collection`')
|
|
||||||
->end()
|
|
||||||
->arrayNode('methods')
|
|
||||||
->addDefaultsIfNotSet()
|
|
||||||
->info('the allowed methods')
|
|
||||||
->children()
|
|
||||||
->booleanNode(Request::METHOD_GET)->defaultTrue()->end()
|
|
||||||
->booleanNode(Request::METHOD_HEAD)->defaultTrue()->end()
|
|
||||||
->booleanNode(Request::METHOD_POST)->defaultFalse()->end()
|
|
||||||
->booleanNode(Request::METHOD_DELETE)->defaultFalse()->end()
|
|
||||||
->booleanNode(Request::METHOD_PUT)->defaultFalse()->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->arrayNode('roles')
|
|
||||||
->addDefaultsIfNotSet()
|
|
||||||
->info("The role require for each http method")
|
|
||||||
->children()
|
|
||||||
->scalarNode(Request::METHOD_GET)->defaultNull()->end()
|
|
||||||
->scalarNode(Request::METHOD_HEAD)->defaultNull()->end()
|
|
||||||
->scalarNode(Request::METHOD_POST)->defaultNull()->end()
|
|
||||||
->scalarNode(Request::METHOD_DELETE)->defaultNull()->end()
|
|
||||||
->scalarNode(Request::METHOD_PUT)->defaultNull()->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
|
|
||||||
->end()
|
|
||||||
->end() // end of root/children
|
->end() // end of root/children
|
||||||
->end() // end of root
|
->end() // end of root
|
||||||
;
|
;
|
||||||
|
@@ -1,103 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Doctrine\Model;
|
|
||||||
|
|
||||||
use \JsonSerializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of Point
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class Point implements JsonSerializable {
|
|
||||||
private float $lat;
|
|
||||||
private float $lon;
|
|
||||||
public static string $SRID = '4326';
|
|
||||||
|
|
||||||
private function __construct(float $lon, float $lat)
|
|
||||||
{
|
|
||||||
$this->lat = $lat;
|
|
||||||
$this->lon = $lon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toGeoJson(): string
|
|
||||||
{
|
|
||||||
$array = $this->toArrayGeoJson();
|
|
||||||
return \json_encode($array);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function jsonSerialize(): array
|
|
||||||
{
|
|
||||||
return $this->toArrayGeoJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toArrayGeoJson(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
"type" => "Point",
|
|
||||||
"coordinates" => [ $this->lon, $this->lat ]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function toWKT(): string
|
|
||||||
{
|
|
||||||
return 'SRID='.self::$SRID.';POINT('.$this->lon.' '.$this->lat.')';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param type $geojson
|
|
||||||
* @return Point
|
|
||||||
*/
|
|
||||||
public static function fromGeoJson(string $geojson): Point
|
|
||||||
{
|
|
||||||
$a = json_decode($geojson);
|
|
||||||
//check if the geojson string is correct
|
|
||||||
if (NULL === $a or !isset($a->type) or !isset($a->coordinates)){
|
|
||||||
throw PointException::badJsonString($geojson);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($a->type != 'Point'){
|
|
||||||
throw PointException::badGeoType();
|
|
||||||
}
|
|
||||||
|
|
||||||
$lat = $a->coordinates[1];
|
|
||||||
$lon = $a->coordinates[0];
|
|
||||||
|
|
||||||
return Point::fromLonLat($lon, $lat);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromLonLat(float $lon, float $lat): Point
|
|
||||||
{
|
|
||||||
if (($lon > -180 && $lon < 180) && ($lat > -90 && $lat < 90))
|
|
||||||
{
|
|
||||||
return new Point($lon, $lat);
|
|
||||||
} else {
|
|
||||||
throw PointException::badCoordinates($lon, $lat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromArrayGeoJson(array $array): Point
|
|
||||||
{
|
|
||||||
if ($array['type'] == 'Point' &&
|
|
||||||
isset($array['coordinates']))
|
|
||||||
{
|
|
||||||
return self::fromLonLat($array['coordinates'][0], $array['coordinates'][1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLat(): float
|
|
||||||
{
|
|
||||||
return $this->lat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLon(): float
|
|
||||||
{
|
|
||||||
return $this->lon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Doctrine\Model;
|
|
||||||
|
|
||||||
use \Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of PointException
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class PointException extends Exception {
|
|
||||||
|
|
||||||
public static function badCoordinates($lon, $lat): self
|
|
||||||
{
|
|
||||||
return new self("Input coordinates are not valid in the used coordinate system (longitude = $lon , latitude = $lat)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function badJsonString($str): self
|
|
||||||
{
|
|
||||||
return new self("The JSON string is not valid: $str");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function badGeoType(): self
|
|
||||||
{
|
|
||||||
return new self("The geoJSON object type is not valid");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,75 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Doctrine\Type;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
use Doctrine\DBAL\Types\Type;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\PointException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Type for Doctrine to implement the Geography Point type
|
|
||||||
* implemented by Postgis on postgis+postgresql databases
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class PointType extends Type {
|
|
||||||
|
|
||||||
const POINT = 'point';
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param array $fieldDeclaration
|
|
||||||
* @param AbstractPlatform $platform
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
|
||||||
{
|
|
||||||
return 'geometry(POINT,'.Point::$SRID.')';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param type $value
|
|
||||||
* @param AbstractPlatform $platform
|
|
||||||
* @return Point
|
|
||||||
*/
|
|
||||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
|
||||||
{
|
|
||||||
if ($value === NULL){
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
return Point::fromGeoJson($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return self::POINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
|
||||||
{
|
|
||||||
if ($value === NULL){
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
return $value->toWKT();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canRequireSQLConversion()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function convertToPHPValueSQL($sqlExpr, $platform)
|
|
||||||
{
|
|
||||||
return 'ST_AsGeoJSON('.$sqlExpr.') ';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
|
|
||||||
{
|
|
||||||
return $sqlExpr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -4,8 +4,6 @@ namespace Chill\MainBundle\Entity;
|
|||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address
|
* Address
|
||||||
@@ -30,14 +28,14 @@ class Address
|
|||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255)
|
* @ORM\Column(type="string", length=255)
|
||||||
*/
|
*/
|
||||||
private $street = '';
|
private $streetAddress1 = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255)
|
* @ORM\Column(type="string", length=255)
|
||||||
*/
|
*/
|
||||||
private $streetNumber = '';
|
private $streetAddress2 = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var PostalCode
|
* @var PostalCode
|
||||||
@@ -46,55 +44,6 @@ class Address
|
|||||||
*/
|
*/
|
||||||
private $postcode;
|
private $postcode;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
|
||||||
*/
|
|
||||||
private $floor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
|
||||||
*/
|
|
||||||
private $corridor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
|
||||||
*/
|
|
||||||
private $steps;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $buildingName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
|
||||||
*/
|
|
||||||
private $flat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $distribution;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $extra;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates when the address starts validation. Used to build an history
|
* Indicates when the address starts validation. Used to build an history
|
||||||
* of address. By default, the current date.
|
* of address. By default, the current date.
|
||||||
@@ -105,16 +54,6 @@ class Address
|
|||||||
*/
|
*/
|
||||||
private $validFrom;
|
private $validFrom;
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates when the address ends. Used to build an history
|
|
||||||
* of address.
|
|
||||||
*
|
|
||||||
* @var \DateTime|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="date", nullable=true)
|
|
||||||
*/
|
|
||||||
private $validTo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the address is a "no address", aka homeless person, ...
|
* True if the address is a "no address", aka homeless person, ...
|
||||||
*
|
*
|
||||||
@@ -122,25 +61,6 @@ class Address
|
|||||||
*/
|
*/
|
||||||
private $isNoAddress = false;
|
private $isNoAddress = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* A geospatial field storing the coordinates of the Address
|
|
||||||
*
|
|
||||||
* @var Point|null
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="point", nullable=true)
|
|
||||||
*/
|
|
||||||
private $point;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ThirdParty reference for person's addresses that are linked to a third party
|
|
||||||
*
|
|
||||||
* @var ThirdParty|null
|
|
||||||
*
|
|
||||||
* @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
|
|
||||||
* @ORM\JoinColumn(nullable=true)
|
|
||||||
*/
|
|
||||||
private $linkedToThirdParty;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of metadata, added by customizable fields
|
* A list of metadata, added by customizable fields
|
||||||
*
|
*
|
||||||
@@ -153,6 +73,7 @@ class Address
|
|||||||
$this->validFrom = new \DateTime();
|
$this->validFrom = new \DateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id
|
* Get id
|
||||||
*
|
*
|
||||||
@@ -164,7 +85,7 @@ class Address
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set streetAddress1 (legacy function)
|
* Set streetAddress1
|
||||||
*
|
*
|
||||||
* @param string $streetAddress1
|
* @param string $streetAddress1
|
||||||
*
|
*
|
||||||
@@ -172,23 +93,23 @@ class Address
|
|||||||
*/
|
*/
|
||||||
public function setStreetAddress1($streetAddress1)
|
public function setStreetAddress1($streetAddress1)
|
||||||
{
|
{
|
||||||
$this->street = $streetAddress1 === NULL ? '' : $streetAddress1;
|
$this->streetAddress1 = $streetAddress1 === NULL ? '' : $streetAddress1;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get streetAddress1 (legacy function)
|
* Get streetAddress1
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getStreetAddress1()
|
public function getStreetAddress1()
|
||||||
{
|
{
|
||||||
return $this->street;
|
return $this->streetAddress1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set streetAddress2 (legacy function)
|
* Set streetAddress2
|
||||||
*
|
*
|
||||||
* @param string $streetAddress2
|
* @param string $streetAddress2
|
||||||
*
|
*
|
||||||
@@ -196,19 +117,19 @@ class Address
|
|||||||
*/
|
*/
|
||||||
public function setStreetAddress2($streetAddress2)
|
public function setStreetAddress2($streetAddress2)
|
||||||
{
|
{
|
||||||
$this->streetNumber = $streetAddress2 === NULL ? '' : $streetAddress2;
|
$this->streetAddress2 = $streetAddress2 === NULL ? '' : $streetAddress2;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get streetAddress2 (legacy function)
|
* Get streetAddress2
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getStreetAddress2()
|
public function getStreetAddress2()
|
||||||
{
|
{
|
||||||
return $this->streetNumber;
|
return $this->streetAddress2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -365,149 +286,5 @@ class Address
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStreet(): ?string
|
|
||||||
{
|
|
||||||
return $this->street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStreet(string $street): self
|
|
||||||
{
|
|
||||||
$this->street = $street;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStreetNumber(): ?string
|
|
||||||
{
|
|
||||||
return $this->streetNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStreetNumber(string $streetNumber): self
|
|
||||||
{
|
|
||||||
$this->streetNumber = $streetNumber;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFloor(): ?string
|
|
||||||
{
|
|
||||||
return $this->floor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setFloor(?string $floor): self
|
|
||||||
{
|
|
||||||
$this->floor = $floor;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCorridor(): ?string
|
|
||||||
{
|
|
||||||
return $this->corridor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCorridor(?string $corridor): self
|
|
||||||
{
|
|
||||||
$this->corridor = $corridor;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSteps(): ?string
|
|
||||||
{
|
|
||||||
return $this->steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSteps(?string $steps): self
|
|
||||||
{
|
|
||||||
$this->steps = $steps;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBuildingName(): ?string
|
|
||||||
{
|
|
||||||
return $this->buildingName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setBuildingName(?string $buildingName): self
|
|
||||||
{
|
|
||||||
$this->buildingName = $buildingName;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFlat(): ?string
|
|
||||||
{
|
|
||||||
return $this->flat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setFlat(?string $flat): self
|
|
||||||
{
|
|
||||||
$this->flat = $flat;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDistribution(): ?string
|
|
||||||
{
|
|
||||||
return $this->distribution;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDistribution(?string $distribution): self
|
|
||||||
{
|
|
||||||
$this->distribution = $distribution;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getExtra(): ?string
|
|
||||||
{
|
|
||||||
return $this->extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setExtra(?string $extra): self
|
|
||||||
{
|
|
||||||
$this->extra = $extra;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getValidTo(): ?\DateTimeInterface
|
|
||||||
{
|
|
||||||
return $this->validTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setValidTo(\DateTimeInterface $validTo): self
|
|
||||||
{
|
|
||||||
$this->validTo = $validTo;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPoint(): ?Point
|
|
||||||
{
|
|
||||||
return $this->point;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPoint(?Point $point): self
|
|
||||||
{
|
|
||||||
$this->point = $point;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLinkedToThirdParty()
|
|
||||||
{
|
|
||||||
return $this->linkedToThirdParty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLinkedToThirdParty($linkedToThirdParty): self
|
|
||||||
{
|
|
||||||
$this->linkedToThirdParty = $linkedToThirdParty;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,165 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Entity;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\AddressReferenceRepository;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=AddressReferenceRepository::class)
|
|
||||||
* @ORM\Table(name="chill_main_address_reference")
|
|
||||||
* @ORM\HasLifecycleCallbacks()
|
|
||||||
*/
|
|
||||||
class AddressReference
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $refId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $street;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $streetNumber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var PostalCode
|
|
||||||
*
|
|
||||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
|
|
||||||
*/
|
|
||||||
private $postcode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $municipalityCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $source;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A geospatial field storing the coordinates of the Address
|
|
||||||
*
|
|
||||||
* @var Point
|
|
||||||
*
|
|
||||||
* @ORM\Column(type="point")
|
|
||||||
*/
|
|
||||||
private $point;
|
|
||||||
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRefId(): ?string
|
|
||||||
{
|
|
||||||
return $this->refId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setRefId(string $refId): self
|
|
||||||
{
|
|
||||||
$this->refId = $refId;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStreet(): ?string
|
|
||||||
{
|
|
||||||
return $this->street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStreet(?string $street): self
|
|
||||||
{
|
|
||||||
$this->street = $street;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStreetNumber(): ?string
|
|
||||||
{
|
|
||||||
return $this->streetNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStreetNumber(?string $streetNumber): self
|
|
||||||
{
|
|
||||||
$this->streetNumber = $streetNumber;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set postcode
|
|
||||||
*
|
|
||||||
* @param PostalCode $postcode
|
|
||||||
*
|
|
||||||
* @return Address
|
|
||||||
*/
|
|
||||||
public function setPostcode(PostalCode $postcode = null)
|
|
||||||
{
|
|
||||||
$this->postcode = $postcode;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get postcode
|
|
||||||
*
|
|
||||||
* @return PostalCode
|
|
||||||
*/
|
|
||||||
public function getPostcode()
|
|
||||||
{
|
|
||||||
return $this->postcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMunicipalityCode(): ?string
|
|
||||||
{
|
|
||||||
return $this->municipalityCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setMunicipalityCode(?string $municipalityCode): self
|
|
||||||
{
|
|
||||||
$this->municipalityCode = $municipalityCode;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSource(): ?string
|
|
||||||
{
|
|
||||||
return $this->source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSource(?string $source): self
|
|
||||||
{
|
|
||||||
$this->source = $source;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPoint(): ?Point
|
|
||||||
{
|
|
||||||
return $this->point;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPoint(?Point $point): self
|
|
||||||
{
|
|
||||||
$this->point = $point;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -45,10 +45,10 @@ class AddressType extends AbstractType
|
|||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
->add('street', TextType::class, array(
|
->add('streetAddress1', TextType::class, array(
|
||||||
'required' => !$options['has_no_address'] // true if has no address is false
|
'required' => !$options['has_no_address'] // true if has no address is false
|
||||||
))
|
))
|
||||||
->add('streetNumber', TextType::class, array(
|
->add('streetAddress2', TextType::class, array(
|
||||||
'required' => false
|
'required' => false
|
||||||
))
|
))
|
||||||
->add('postCode', PostalCodeType::class, array(
|
->add('postCode', PostalCodeType::class, array(
|
||||||
|
@@ -27,7 +27,6 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
use Chill\MainBundle\Form\Type\DataTransformer\ObjectToIdTransformer;
|
use Chill\MainBundle\Form\Type\DataTransformer\ObjectToIdTransformer;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Chill\MainBundle\Form\Type\Select2ChoiceType;
|
use Chill\MainBundle\Form\Type\Select2ChoiceType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends choice to allow adding select2 library on widget
|
* Extends choice to allow adding select2 library on widget
|
||||||
@@ -42,26 +41,15 @@ class Select2CountryType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
private $requestStack;
|
private $requestStack;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var TranslatableStringHelper
|
|
||||||
*/
|
|
||||||
protected $translatableStringHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ObjectManager
|
* @var ObjectManager
|
||||||
*/
|
*/
|
||||||
private $em;
|
private $em;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(RequestStack $requestStack,ObjectManager $em)
|
||||||
RequestStack $requestStack,
|
|
||||||
ObjectManager $em,
|
|
||||||
TranslatableStringHelper $translatableStringHelper
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
$this->requestStack = $requestStack;
|
$this->requestStack = $requestStack;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
@@ -87,7 +75,7 @@ class Select2CountryType extends AbstractType
|
|||||||
$choices = array();
|
$choices = array();
|
||||||
|
|
||||||
foreach ($countries as $c) {
|
foreach ($countries as $c) {
|
||||||
$choices[$c->getId()] = $this->translatableStringHelper->localize($c->getName());
|
$choices[$c->getId()] = $c->getName()[$locale];
|
||||||
}
|
}
|
||||||
|
|
||||||
asort($choices, SORT_STRING | SORT_FLAG_CASE);
|
asort($choices, SORT_STRING | SORT_FLAG_CASE);
|
||||||
|
@@ -27,7 +27,6 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
use Chill\MainBundle\Form\Type\DataTransformer\MultipleObjectsToIdTransformer;
|
use Chill\MainBundle\Form\Type\DataTransformer\MultipleObjectsToIdTransformer;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Chill\MainBundle\Form\Type\Select2ChoiceType;
|
use Chill\MainBundle\Form\Type\Select2ChoiceType;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends choice to allow adding select2 library on widget for languages (multiple)
|
* Extends choice to allow adding select2 library on widget for languages (multiple)
|
||||||
@@ -44,21 +43,10 @@ class Select2LanguageType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
private $em;
|
private $em;
|
||||||
|
|
||||||
/**
|
public function __construct(RequestStack $requestStack,ObjectManager $em)
|
||||||
*
|
|
||||||
* @var TranslatableStringHelper
|
|
||||||
*/
|
|
||||||
protected $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
RequestStack $requestStack,
|
|
||||||
ObjectManager $em,
|
|
||||||
TranslatableStringHelper $translatableStringHelper
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
$this->requestStack = $requestStack;
|
$this->requestStack = $requestStack;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
@@ -84,7 +72,7 @@ class Select2LanguageType extends AbstractType
|
|||||||
$choices = array();
|
$choices = array();
|
||||||
|
|
||||||
foreach ($languages as $l) {
|
foreach ($languages as $l) {
|
||||||
$choices[$l->getId()] = $this->translatableStringHelper->localize($l->getName());
|
$choices[$l->getId()] = $l->getName()[$locale];
|
||||||
}
|
}
|
||||||
|
|
||||||
asort($choices, SORT_STRING | SORT_FLAG_CASE);
|
asort($choices, SORT_STRING | SORT_FLAG_CASE);
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Repository;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\AddressReference;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @method AddressReference|null find($id, $lockMode = null, $lockVersion = null)
|
|
||||||
* @method AddressReference|null findOneBy(array $criteria, array $orderBy = null)
|
|
||||||
* @method AddressReference[] findAll()
|
|
||||||
* @method AddressReference[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
|
||||||
*/
|
|
||||||
class AddressReferenceRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, AddressReference::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return AddressReference[] Returns an array of AddressReference objects
|
|
||||||
// */
|
|
||||||
/*
|
|
||||||
public function findByExampleField($value)
|
|
||||||
{
|
|
||||||
return $this->createQueryBuilder('a')
|
|
||||||
->andWhere('a.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->orderBy('a.id', 'ASC')
|
|
||||||
->setMaxResults(10)
|
|
||||||
->getQuery()
|
|
||||||
->getResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
public function findOneBySomeField($value): ?AddressReference
|
|
||||||
{
|
|
||||||
return $this->createQueryBuilder('a')
|
|
||||||
->andWhere('a.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->getQuery()
|
|
||||||
->getOneOrNullResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -28,7 +28,7 @@
|
|||||||
// @import "bootstrap/scss/card";
|
// @import "bootstrap/scss/card";
|
||||||
// @import "bootstrap/scss/breadcrumb";
|
// @import "bootstrap/scss/breadcrumb";
|
||||||
// @import "bootstrap/scss/pagination";
|
// @import "bootstrap/scss/pagination";
|
||||||
@import "bootstrap/scss/badge";
|
// @import "bootstrap/scss/badge";
|
||||||
// @import "bootstrap/scss/jumbotron";
|
// @import "bootstrap/scss/jumbotron";
|
||||||
// @import "bootstrap/scss/alert";
|
// @import "bootstrap/scss/alert";
|
||||||
// @import "bootstrap/scss/progress";
|
// @import "bootstrap/scss/progress";
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
// @import "bootstrap/scss/popover";
|
// @import "bootstrap/scss/popover";
|
||||||
// @import "bootstrap/scss/carousel";
|
// @import "bootstrap/scss/carousel";
|
||||||
// @import "bootstrap/scss/spinners";
|
// @import "bootstrap/scss/spinners";
|
||||||
@import "bootstrap/scss/utilities";
|
// @import "bootstrap/scss/utilities";
|
||||||
// @import "bootstrap/scss/print";
|
// @import "bootstrap/scss/print";
|
||||||
|
|
||||||
@import "custom";
|
@import "custom";
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
@include button($green, $white);
|
@include button($green, $white);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.bt-reset, &.bt-delete, &.bt-remove {
|
&.bt-reset, &.bt-delete {
|
||||||
@include button($red, $white);
|
@include button($red, $white);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
&.bt-save::before,
|
&.bt-save::before,
|
||||||
&.bt-new::before,
|
&.bt-new::before,
|
||||||
&.bt-delete::before,
|
&.bt-delete::before,
|
||||||
&.bt-remove::before,
|
|
||||||
&.bt-update::before,
|
&.bt-update::before,
|
||||||
&.bt-edit::before,
|
&.bt-edit::before,
|
||||||
&.bt-cancel::before,
|
&.bt-cancel::before,
|
||||||
@@ -58,11 +57,6 @@
|
|||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
&.bt-remove::before {
|
|
||||||
// add a times
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bt-edit::before, &.bt-update::before {
|
&.bt-edit::before, &.bt-update::before {
|
||||||
// add a pencil
|
// add a pencil
|
||||||
content: "";
|
content: "";
|
||||||
@@ -100,7 +94,6 @@
|
|||||||
&.bt-save::before,
|
&.bt-save::before,
|
||||||
&.bt-new::before,
|
&.bt-new::before,
|
||||||
&.bt-delete::before,
|
&.bt-delete::before,
|
||||||
&.bt-remove::before,
|
|
||||||
&.bt-update::before,
|
&.bt-update::before,
|
||||||
&.bt-edit::before,
|
&.bt-edit::before,
|
||||||
&.bt-cancel::before,
|
&.bt-cancel::before,
|
||||||
@@ -130,7 +123,6 @@
|
|||||||
&.bt-save::before,
|
&.bt-save::before,
|
||||||
&.bt-new::before,
|
&.bt-new::before,
|
||||||
&.bt-delete::before,
|
&.bt-delete::before,
|
||||||
&.bt-remove::before,
|
|
||||||
&.bt-update::before,
|
&.bt-update::before,
|
||||||
&.bt-edit::before,
|
&.bt-edit::before,
|
||||||
&.bt-cancel::before,
|
&.bt-cancel::before,
|
||||||
|
@@ -39,8 +39,6 @@ div.subheader {
|
|||||||
height: 130px;
|
height: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
//// VUEJS ////
|
|
||||||
|
|
||||||
div.vue-component {
|
div.vue-component {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
margin: 2em 0;
|
margin: 2em 0;
|
||||||
@@ -57,97 +55,3 @@ div.vue-component {
|
|||||||
}
|
}
|
||||||
dd { margin-left: 1em; }
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.discret {
|
|
||||||
color: grey;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
<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="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>
|
|
||||||
</div>
|
|
||||||
<!-- :: 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
|
|
||||||
* - 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',
|
|
||||||
props: ['modalDialogClass'],
|
|
||||||
emits: ['close']
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,55 +0,0 @@
|
|||||||
import { createI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
const datetimeFormats = {
|
|
||||||
fr: {
|
|
||||||
short: {
|
|
||||||
year: "numeric",
|
|
||||||
month: "numeric",
|
|
||||||
day: "numeric"
|
|
||||||
},
|
|
||||||
long: {
|
|
||||||
year: "numeric",
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
weekday: "short",
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const messages = {
|
|
||||||
fr: {
|
|
||||||
action: {
|
|
||||||
actions: "Actions",
|
|
||||||
show: "Voir",
|
|
||||||
edit: "Modifier",
|
|
||||||
create: "Créer",
|
|
||||||
remove: "Enlever",
|
|
||||||
delete: "Supprimer",
|
|
||||||
save: "Enregistrer",
|
|
||||||
add: "Ajouter",
|
|
||||||
show_modal: "Ouvrir une modale",
|
|
||||||
ok: "OK",
|
|
||||||
cancel: "Annuler",
|
|
||||||
close: "Fermer",
|
|
||||||
next: "Suivant",
|
|
||||||
previous: "Précédent",
|
|
||||||
back: "Retour",
|
|
||||||
check_all: "cocher tout",
|
|
||||||
reset: "réinitialiser"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _createI18n = (appMessages) => {
|
|
||||||
Object.assign(messages.fr, appMessages.fr);
|
|
||||||
return createI18n({
|
|
||||||
locale: 'fr',
|
|
||||||
fallbackLocale: 'fr',
|
|
||||||
datetimeFormats,
|
|
||||||
messages,
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
export { _createI18n }
|
|
@@ -6,8 +6,8 @@
|
|||||||
<div class="chill_address_is_noaddress">{{ 'address.consider homeless'|trans }}</div>
|
<div class="chill_address_is_noaddress">{{ 'address.consider homeless'|trans }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="chill_address_address">
|
<div class="chill_address_address">
|
||||||
{% if address.street is not empty %}<p class="street street1">{{ address.street }}</p>{% endif %}
|
{% if address.streetAddress1 is not empty %}<p class="street street1">{{ address.streetAddress1 }}</p>{% endif %}
|
||||||
{% if address.streetNumber is not empty %}<p class="street street2">{{ address.streetNumber }}</p>{% endif %}
|
{% if address.streetAddress2 is not empty %}<p class="street street2">{{ address.streetAddress2 }}</p>{% endif %}
|
||||||
{% if address.postCode is not empty %}
|
{% if address.postCode is not empty %}
|
||||||
<p class="postalCode"><span class="code">{{ address.postCode.code }}</span> <span class="name">{{ address.postCode.name }}</span></p>
|
<p class="postalCode"><span class="code">{{ address.postCode.code }}</span> <span class="name">{{ address.postCode.name }}</span></p>
|
||||||
<p class="country">{{ address.postCode.country.name|localize_translatable_string }}</p>
|
<p class="country">{{ address.postCode.country.name|localize_translatable_string }}</p>
|
||||||
|
@@ -204,7 +204,7 @@ class SearchProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getResultByName($pattern, $name, $start = 0, $limit = 50,
|
public function getResultByName($pattern, $name, $start = 0, $limit = 50,
|
||||||
array $options = array(), $format = 'html')
|
array $options = array(), $format)
|
||||||
{
|
{
|
||||||
$terms = $this->parse($pattern);
|
$terms = $this->parse($pattern);
|
||||||
$search = $this->getByName($name);
|
$search = $this->getByName($name);
|
||||||
|
@@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Serializer\Model;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
|
|
||||||
class Collection
|
|
||||||
{
|
|
||||||
private PaginatorInterface $paginator;
|
|
||||||
|
|
||||||
private $items;
|
|
||||||
|
|
||||||
public function __construct($items, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
$this->items = $items;
|
|
||||||
$this->paginator = $paginator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPaginator(): PaginatorInterface
|
|
||||||
{
|
|
||||||
return $this->paginator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItems()
|
|
||||||
{
|
|
||||||
return $this->items;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Serializer\Normalizer;
|
|
||||||
|
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
|
||||||
|
|
||||||
class CollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
|
|
||||||
{
|
|
||||||
use NormalizerAwareTrait;
|
|
||||||
|
|
||||||
public function supportsNormalization($data, string $format = null): bool
|
|
||||||
{
|
|
||||||
return $data instanceof Collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function normalize($collection, string $format = null, array $context = [])
|
|
||||||
{
|
|
||||||
/** @var $collection Collection */
|
|
||||||
/** @var $collection Chill\MainBundle\Pagination\PaginatorInterface */
|
|
||||||
$paginator = $collection->getPaginator();
|
|
||||||
|
|
||||||
$data['count'] = $paginator->getTotalItems();
|
|
||||||
$pagination['first'] = $paginator->getCurrentPageFirstItemNumber();
|
|
||||||
$pagination['items_per_page'] = $paginator->getItemsPerPage();
|
|
||||||
$pagination['next'] = $paginator->hasNextPage() ?
|
|
||||||
$paginator->getNextPage()->generateUrl() : null;
|
|
||||||
$pagination['previous'] = $paginator->hasPreviousPage() ?
|
|
||||||
$paginator->getPreviousPage()->generateUrl() : null;
|
|
||||||
$pagination['more'] = $paginator->hasNextPage();
|
|
||||||
$data['pagination'] = $pagination;
|
|
||||||
|
|
||||||
// normalize results
|
|
||||||
$data['results'] = $this->normalizer->normalize($collection->getItems(),
|
|
||||||
$format, $context);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,7 +9,15 @@ class LoginControllerTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
public function testLogin()
|
public function testLogin()
|
||||||
{
|
{
|
||||||
$client = static::createClient();
|
$client = static::createClient(array(
|
||||||
|
'framework' => array(
|
||||||
|
'default_locale' => 'en',
|
||||||
|
'translator' => array(
|
||||||
|
'fallback' => 'en'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
));
|
||||||
|
|
||||||
//load login page and submit form
|
//load login page and submit form
|
||||||
$crawler = $client->request('GET', '/login');
|
$crawler = $client->request('GET', '/login');
|
||||||
@@ -37,14 +45,14 @@ class LoginControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertRegExp('/center a_social/', $client->getResponse()
|
$this->assertRegExp('/center a_social/', $client->getResponse()
|
||||||
->getContent());
|
->getContent());
|
||||||
$logoutLinkFilter = $crawler->filter('a:contains("Se déconnecter")');
|
$logoutLinkFilter = $crawler->filter('a:contains("Logout")');
|
||||||
|
|
||||||
//check there is > 0 logout link
|
//check there is > 0 logout link
|
||||||
$this->assertGreaterThan(0, $logoutLinkFilter->count(), 'check that a logout link is present');
|
$this->assertGreaterThan(0, $logoutLinkFilter->count(), 'check that a logout link is present');
|
||||||
|
|
||||||
//click on logout link
|
//click on logout link
|
||||||
$client->followRedirects(false);
|
$client->followRedirects(false);
|
||||||
$client->click($crawler->selectLink('Se déconnecter')->link());
|
$client->click($crawler->selectLink('Logout')->link());
|
||||||
|
|
||||||
$this->assertTrue($client->getResponse()->isRedirect());
|
$this->assertTrue($client->getResponse()->isRedirect());
|
||||||
$client->followRedirect(); #redirect to login page
|
$client->followRedirect(); #redirect to login page
|
||||||
|
@@ -32,6 +32,20 @@ use Chill\MainBundle\Search\SearchInterface;
|
|||||||
*/
|
*/
|
||||||
class SearchControllerTest extends WebTestCase
|
class SearchControllerTest extends WebTestCase
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
static::bootKernel();
|
||||||
|
|
||||||
|
//add a default service
|
||||||
|
$this->addSearchService(
|
||||||
|
$this->createDefaultSearchService('<p>I am default</p>', 10), 'default'
|
||||||
|
);
|
||||||
|
//add a domain service
|
||||||
|
$this->addSearchService(
|
||||||
|
$this->createDefaultSearchService('<p>I am domain bar</p>', 20), 'bar'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the behaviour when no domain is provided in the search pattern :
|
* Test the behaviour when no domain is provided in the search pattern :
|
||||||
@@ -91,6 +105,29 @@ class SearchControllerTest extends WebTestCase
|
|||||||
$this->assertTrue($client->getResponse()->isNotFound());
|
$this->assertTrue($client->getResponse()->isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testSearchWithinSpecificSearchName()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
//add a search service which will be supported
|
||||||
|
$this->addSearchService(
|
||||||
|
$this->createNonDefaultDomainSearchService("<p>I am domain foo</p>", 100, TRUE), 'foo'
|
||||||
|
);
|
||||||
|
|
||||||
|
$client = $this->getAuthenticatedClient();
|
||||||
|
$crawler = $client->request('GET', '/fr/search',
|
||||||
|
array('q' => '@foo default search', 'name' => 'foo'));
|
||||||
|
|
||||||
|
//$this->markTestSkipped();
|
||||||
|
$this->assertEquals(0, $crawler->filter('p:contains("I am default")')->count(),
|
||||||
|
"The mocked default results are not shown");
|
||||||
|
$this->assertEquals(0, $crawler->filter('p:contains("I am domain bar")')->count(),
|
||||||
|
"The mocked non-default results are not shown");
|
||||||
|
$this->assertEquals(1, $crawler->filter('p:contains("I am domain foo")')->count(),
|
||||||
|
"The mocked nnon default results for foo are shown");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
private function getAuthenticatedClient()
|
private function getAuthenticatedClient()
|
||||||
{
|
{
|
||||||
return static::createClient(array(), array(
|
return static::createClient(array(), array(
|
||||||
|
@@ -37,12 +37,11 @@ class UserControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$username = 'Test_user'. uniqid();
|
$username = 'Test_user'. uniqid();
|
||||||
$password = 'Password1234!';
|
$password = 'Password1234!';
|
||||||
dump($crawler->text());
|
|
||||||
// Fill in the form and submit it
|
// Fill in the form and submit it
|
||||||
$form = $crawler->selectButton('Créer')->form(array(
|
$form = $crawler->selectButton('Créer')->form(array(
|
||||||
'chill_mainbundle_user[username]' => $username,
|
'chill_mainbundle_user[username]' => $username,
|
||||||
'chill_mainbundle_user[plainPassword][first]' => $password,
|
'chill_mainbundle_user[plainPassword][password][first]' => $password,
|
||||||
'chill_mainbundle_user[plainPassword][second]' => $password
|
'chill_mainbundle_user[plainPassword][password][second]' => $password
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->client->submit($form);
|
$this->client->submit($form);
|
||||||
@@ -120,8 +119,8 @@ class UserControllerTest extends WebTestCase
|
|||||||
$crawler = $this->client->click($link);
|
$crawler = $this->client->click($link);
|
||||||
|
|
||||||
$form = $crawler->selectButton('Changer le mot de passe')->form(array(
|
$form = $crawler->selectButton('Changer le mot de passe')->form(array(
|
||||||
'chill_mainbundle_user_password[new_password][first]' => $newPassword,
|
'chill_mainbundle_user_password[password][first]' => $newPassword,
|
||||||
'chill_mainbundle_user_password[new_password][second]' => $newPassword,
|
'chill_mainbundle_user_password[password][second]' => $newPassword,
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->client->submit($form);
|
$this->client->submit($form);
|
||||||
|
@@ -0,0 +1,179 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
* Copyright (C) 2015 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\MainBundle\Tests\DependencyInjection;
|
||||||
|
|
||||||
|
use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of ConfigConsistencyCompilerPassTest
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class ConfigConsistencyCompilerPassTest extends \PHPUnit\Framework\TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @var \Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass
|
||||||
|
*/
|
||||||
|
private $configConsistencyCompilerPass;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->configConsistencyCompilerPass = new ConfigConsistencyCompilerPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that everything is fine is configuration is correct
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function testLanguagesArePresent()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this ->configConsistencyCompilerPass
|
||||||
|
->process(
|
||||||
|
$this->mockContainer(
|
||||||
|
$this->mockTranslatorDefinition(array('fr')),
|
||||||
|
array('fr', 'nl')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertTrue(TRUE, 'the config consistency can process');
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
$this->assertTrue(FALSE,
|
||||||
|
'the config consistency can process');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that everything is fine is configuration is correct
|
||||||
|
* if multiple fallback languages are present
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function testMultiplesLanguagesArePresent()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this ->configConsistencyCompilerPass
|
||||||
|
->process(
|
||||||
|
$this->mockContainer(
|
||||||
|
$this->mockTranslatorDefinition(array('fr', 'nl')),
|
||||||
|
array('fr', 'nl', 'en')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertTrue(TRUE, 'the config consistency can process');
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
$this->assertTrue(FALSE,
|
||||||
|
'the config consistency can process');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that a runtime exception is throw if the available language does
|
||||||
|
* not contains the fallback locale
|
||||||
|
*
|
||||||
|
* @expectedException \RuntimeException
|
||||||
|
* @expectedExceptionMessageRegExp /The chill_main.available_languages parameter does not contains fallback locales./
|
||||||
|
*/
|
||||||
|
public function testLanguageNotPresent()
|
||||||
|
{
|
||||||
|
$container = $this->mockContainer(
|
||||||
|
$this->mockTranslatorDefinition(array('en')), array('fr')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->configConsistencyCompilerPass->process($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that a logic exception is thrown if the setFallbackLocale
|
||||||
|
* method is not defined in translator definition
|
||||||
|
*
|
||||||
|
* @expectedException \LogicException
|
||||||
|
*/
|
||||||
|
public function testSetFallbackNotDefined()
|
||||||
|
{
|
||||||
|
$container = $this->mockContainer(
|
||||||
|
$this->mockTranslatorDefinition(NULL), array('fr')
|
||||||
|
);
|
||||||
|
$this->configConsistencyCompilerPass->process($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ContainerBuilder
|
||||||
|
*/
|
||||||
|
private function mockContainer($definition, $availableLanguages)
|
||||||
|
{
|
||||||
|
$container = $this
|
||||||
|
->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$container->method('getParameter')
|
||||||
|
->will($this->returnCallback(
|
||||||
|
function($parameter) use ($availableLanguages) {
|
||||||
|
if ($parameter === 'chill_main.available_languages') {
|
||||||
|
return $availableLanguages;
|
||||||
|
} else {
|
||||||
|
throw new \LogicException("the parameter '$parameter' "
|
||||||
|
. "is not defined in stub test");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
$container->method('findDefinition')
|
||||||
|
->will($this->returnCallback(
|
||||||
|
function($id) use ($definition) {
|
||||||
|
if (in_array($id, array('translator', 'translator.default'))) {
|
||||||
|
return $definition;
|
||||||
|
} else {
|
||||||
|
throw new \LogicException("the id $id is not defined in test");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param type $languages
|
||||||
|
* @return 'Symfony\Component\DependencyInjection\Definition'
|
||||||
|
*/
|
||||||
|
private function mockTranslatorDefinition(array $languages = NULL)
|
||||||
|
{
|
||||||
|
$definition = $this
|
||||||
|
->getMockBuilder('Symfony\Component\DependencyInjection\Definition')
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
if (NULL !== $languages) {
|
||||||
|
$definition->method('getMethodCalls')
|
||||||
|
->willReturn(array(
|
||||||
|
['setFallbackLocales', array($languages)]
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$definition->method('getMethodCalls')
|
||||||
|
->willReturn(array(['nothing', array()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $definition;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,119 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\MainBundle\Tests\Doctrine\Model;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the point model methods
|
|
||||||
*
|
|
||||||
* @author Julien Minet <julien.minet@champs-libres.coop>
|
|
||||||
*/
|
|
||||||
class ExportControllerTest extends KernelTestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
public function testToWKT()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);
|
|
||||||
|
|
||||||
$this->assertEquals($point->toWKT(),'SRID=4326;POINT(4.8634 50.47382)');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testToGeojson()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);
|
|
||||||
|
|
||||||
$this->assertEquals($point->toGeoJson(),'{"type":"Point","coordinates":[4.8634,50.47382]}');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testToArrayGeoJson()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
$point->toArrayGeoJson(),
|
|
||||||
[
|
|
||||||
'type' => 'Point',
|
|
||||||
'coordinates' => [4.8634, 50.47382]
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testJsonSerialize()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
$point->jsonSerialize(),
|
|
||||||
[
|
|
||||||
'type' => 'Point',
|
|
||||||
'coordinates' => [4.8634, 50.47382]
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromGeoJson()
|
|
||||||
{
|
|
||||||
$geojson = '{"type":"Point","coordinates":[4.8634,50.47382]}';
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);;
|
|
||||||
|
|
||||||
$this->assertEquals($point, Point::fromGeoJson($geojson));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromLonLat()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);;
|
|
||||||
|
|
||||||
$this->assertEquals($point, Point::fromLonLat($lon, $lat));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromArrayGeoJson()
|
|
||||||
{
|
|
||||||
$array = [
|
|
||||||
'type' => 'Point',
|
|
||||||
'coordinates' => [4.8634, 50.47382]
|
|
||||||
];
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);;
|
|
||||||
|
|
||||||
$this->assertEquals($point, Point::fromArrayGeoJson($array));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetLat()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);;
|
|
||||||
|
|
||||||
$this->assertEquals($lat, $point->getLat());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetLon()
|
|
||||||
{
|
|
||||||
$lon = 4.8634;
|
|
||||||
$lat = 50.47382;
|
|
||||||
$point = $this->preparePoint($lon, $lat);;
|
|
||||||
|
|
||||||
$this->assertEquals($lon, $point->getLon());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function preparePoint($lon, $lat)
|
|
||||||
{
|
|
||||||
return Point::fromLonLat($lon, $lat);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -624,9 +624,8 @@ class ExportManagerTest extends KernelTestCase
|
|||||||
$exportManager->addFormatter($formatter, 'spreadsheet');
|
$exportManager->addFormatter($formatter, 'spreadsheet');
|
||||||
|
|
||||||
//ob_start();
|
//ob_start();
|
||||||
$response = $exportManager->generate(
|
$response = $exportManager->generate('dummy',
|
||||||
'dummy',
|
array(PickCenterType::CENTERS_IDENTIFIERS => array($center)),
|
||||||
array($center),
|
|
||||||
array(
|
array(
|
||||||
ExportType::FILTER_KEY => array(
|
ExportType::FILTER_KEY => array(
|
||||||
'filter_foo' => array(
|
'filter_foo' => array(
|
||||||
|
@@ -54,20 +54,13 @@ class PageTest extends KernelTestCase
|
|||||||
$number = 1,
|
$number = 1,
|
||||||
$itemPerPage = 10,
|
$itemPerPage = 10,
|
||||||
$route = 'route',
|
$route = 'route',
|
||||||
array $routeParameters = array(),
|
array $routeParameters = array()
|
||||||
$totalItems = 100
|
|
||||||
) {
|
) {
|
||||||
$urlGenerator = $this->prophet->prophesize();
|
$urlGenerator = $this->prophet->prophesize();
|
||||||
$urlGenerator->willImplement(UrlGeneratorInterface::class);
|
$urlGenerator->willImplement(UrlGeneratorInterface::class);
|
||||||
|
|
||||||
return new Page(
|
return new Page($number, $itemPerPage, $urlGenerator->reveal(), $route,
|
||||||
$number,
|
$routeParameters);
|
||||||
$itemPerPage,
|
|
||||||
$urlGenerator->reveal(),
|
|
||||||
$route,
|
|
||||||
$routeParameters,
|
|
||||||
$totalItems
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPageNumber() {
|
public function testPageNumber() {
|
||||||
|
@@ -21,10 +21,9 @@ namespace Chill\MainBundle\Test\Search;
|
|||||||
|
|
||||||
use Chill\MainBundle\Search\SearchProvider;
|
use Chill\MainBundle\Search\SearchProvider;
|
||||||
use Chill\MainBundle\Search\SearchInterface;
|
use Chill\MainBundle\Search\SearchInterface;
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
|
|
||||||
class SearchProviderTest extends TestCase
|
class SearchProviderTest extends \PHPUnit\Framework\TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -50,7 +50,7 @@ class AuthorizationHelperTest extends KernelTestCase
|
|||||||
*/
|
*/
|
||||||
private function getAuthorizationHelper()
|
private function getAuthorizationHelper()
|
||||||
{
|
{
|
||||||
return static::$container
|
return static::$kernel->getContainer()
|
||||||
->get('chill.main.security.authorization.helper')
|
->get('chill.main.security.authorization.helper')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,8 @@ class TokenManagerTest extends KernelTestCase
|
|||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
|
|
||||||
$logger = self::$container
|
$logger = self::$kernel
|
||||||
|
->getContainer()
|
||||||
->get('logger');
|
->get('logger');
|
||||||
|
|
||||||
$this->tokenManager = new TokenManager('secret', $logger);
|
$this->tokenManager = new TokenManager('secret', $logger);
|
||||||
|
@@ -36,19 +36,53 @@ class ChillMenuTwigFunctionTest extends KernelTestCase
|
|||||||
public static function setUpBeforeClass()
|
public static function setUpBeforeClass()
|
||||||
{
|
{
|
||||||
self::bootKernel(array('environment' => 'test'));
|
self::bootKernel(array('environment' => 'test'));
|
||||||
static::$templating = static::$container
|
static::$templating = static::$kernel
|
||||||
->get('templating');
|
->getContainer()->get('templating');
|
||||||
$pathToBundle = static::$container->getParameter('kernel.bundles_metadata')['ChillMainBundle']['path'];
|
|
||||||
//load templates in Tests/Resources/views
|
//load templates in Tests/Resources/views
|
||||||
static::$container->get('twig.loader')
|
static::$kernel->getContainer()->get('twig.loader')
|
||||||
->addPath($pathToBundle.'/Resources/test/views/', $namespace = 'tests');
|
->addPath(static::$kernel->getContainer()->getParameter('kernel.root_dir')
|
||||||
|
.'/Resources/views/', $namespace = 'tests');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNormalMenu()
|
public function testNormalMenu()
|
||||||
{
|
{
|
||||||
$content = static::$templating->render('@tests/menus/normalMenu.html.twig');
|
$content = static::$templating->render('@tests/menus/normalMenu.html.twig');
|
||||||
$this->assertContains('ul', $content,
|
$crawler = new Crawler($content);
|
||||||
"test that the file contains an ul tag"
|
|
||||||
);
|
$ul = $crawler->filter('ul')->getNode(0);
|
||||||
|
$this->assertEquals( 'ul', $ul->tagName);
|
||||||
|
|
||||||
|
$lis = $crawler->filter('ul')->children();
|
||||||
|
$this->assertEquals(3, count($lis));
|
||||||
|
|
||||||
|
$lis->each(function(Crawler $node, $i) {
|
||||||
|
$this->assertEquals('li', $node->getNode(0)->tagName);
|
||||||
|
|
||||||
|
$a = $node->children()->getNode(0);
|
||||||
|
$this->assertEquals('a', $a->tagName);
|
||||||
|
switch($i) {
|
||||||
|
case 0:
|
||||||
|
$this->assertEquals('/dummy?param=fake', $a->getAttribute('href'));
|
||||||
|
$this->assertEquals('active', $a->getAttribute('class'));
|
||||||
|
$this->assertEquals('test0', $a->nodeValue);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$this->assertEquals('/dummy1?param=fake', $a->getAttribute('href'));
|
||||||
|
$this->assertEmpty($a->getAttribute('class'));
|
||||||
|
$this->assertEquals('test1', $a->nodeValue);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$this->assertEquals('/dummy2/fake', $a->getAttribute('href'));
|
||||||
|
$this->assertEmpty($a->getAttribute('class'));
|
||||||
|
$this->assertEquals('test2', $a->nodeValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMenuOverrideTemplate()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped("this hacks seems not working now");
|
||||||
|
$content = static::$templating->render('@tests/menus/overrideTemplate.html.twig');
|
||||||
|
$this->assertEquals('fake template', $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ class MenuComposerTest extends KernelTestCase
|
|||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
self::bootKernel(array('environment' => 'test'));
|
self::bootKernel(array('environment' => 'test'));
|
||||||
$this->menuComposer = static::$container
|
$this->menuComposer = static::$kernel->getContainer()
|
||||||
->get('chill.main.menu_composer');
|
->get('chill.main.menu_composer');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,5 +42,50 @@ class MenuComposerTest extends KernelTestCase
|
|||||||
$routes = $this->menuComposer->getRoutesFor('dummy0');
|
$routes = $this->menuComposer->getRoutesFor('dummy0');
|
||||||
|
|
||||||
$this->assertInternalType('array', $routes);
|
$this->assertInternalType('array', $routes);
|
||||||
|
$this->assertCount(3, $routes);
|
||||||
|
//check that the keys are sorted
|
||||||
|
$orders = array_keys($routes);
|
||||||
|
foreach ($orders as $key => $order){
|
||||||
|
if (array_key_exists($key + 1, $orders)) {
|
||||||
|
$this->assertGreaterThan($order, $orders[$key + 1],
|
||||||
|
'Failing to assert that routes are ordered');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check that the array are identical, order is not important :
|
||||||
|
|
||||||
|
$expected = array(
|
||||||
|
50 => array(
|
||||||
|
'key' => 'chill_main_dummy_0',
|
||||||
|
'label' => 'test0',
|
||||||
|
'otherkey' => 'othervalue'
|
||||||
|
),
|
||||||
|
51 => array(
|
||||||
|
'key' => 'chill_main_dummy_1',
|
||||||
|
'label' => 'test1',
|
||||||
|
'helper'=> 'great helper'
|
||||||
|
),
|
||||||
|
52 => array(
|
||||||
|
'key' => 'chill_main_dummy_2',
|
||||||
|
'label' => 'test2'
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($expected as $order => $route ){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//compare arrays
|
||||||
|
foreach($expected as $order => $route) {
|
||||||
|
//check the key are the one expected
|
||||||
|
$this->assertTrue(isset($routes[$order]));
|
||||||
|
|
||||||
|
if (isset($routes[$order])){ #avoid an exception if routes with order does not exists
|
||||||
|
//sort arrays. Order matters for phpunit::assertSame
|
||||||
|
ksort($route);
|
||||||
|
ksort($routes[$order]);
|
||||||
|
$this->assertSame($route, $routes[$order]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -86,3 +86,7 @@ login_check:
|
|||||||
|
|
||||||
logout:
|
logout:
|
||||||
path: /logout
|
path: /logout
|
||||||
|
|
||||||
|
chill_main_test:
|
||||||
|
path: /{_locale}/main/test
|
||||||
|
controller: Chill\MainBundle\Controller\DefaultController::testAction
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
Chill\MainBundle\CRUD\Routing\CRUDRoutesLoader:
|
Chill\MainBundle\CRUD\Routing\CRUDRoutesLoader:
|
||||||
arguments:
|
arguments:
|
||||||
$crudConfig: '%chill_main_crud_route_loader_config%'
|
$config: '%chill_main_crud_route_loader_config%'
|
||||||
$apiConfig: '%chill_main_api_route_loader_config%'
|
|
||||||
tags: [ routing.loader ]
|
tags: [ routing.loader ]
|
||||||
|
|
||||||
Chill\MainBundle\CRUD\Resolver\Resolver:
|
Chill\MainBundle\CRUD\Resolver\Resolver:
|
||||||
|
@@ -23,7 +23,6 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
- "@request_stack"
|
- "@request_stack"
|
||||||
- "@doctrine.orm.entity_manager"
|
- "@doctrine.orm.entity_manager"
|
||||||
- "@chill.main.helper.translatable_string"
|
|
||||||
tags:
|
tags:
|
||||||
- { name: form.type, alias: select2_chill_country }
|
- { name: form.type, alias: select2_chill_country }
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
- "@request_stack"
|
- "@request_stack"
|
||||||
- "@doctrine.orm.entity_manager"
|
- "@doctrine.orm.entity_manager"
|
||||||
- "@chill.main.helper.translatable_string"
|
|
||||||
tags:
|
tags:
|
||||||
- { name: form.type, alias: select2_chill_language }
|
- { name: form.type, alias: select2_chill_language }
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ services:
|
|||||||
- "@request_stack"
|
- "@request_stack"
|
||||||
- "@router"
|
- "@router"
|
||||||
- "%chill_main.pagination.item_per_page%"
|
- "%chill_main.pagination.item_per_page%"
|
||||||
|
|
||||||
Chill\MainBundle\Pagination\PaginatorFactory: '@chill_main.paginator_factory'
|
Chill\MainBundle\Pagination\PaginatorFactory: '@chill_main.paginator_factory'
|
||||||
|
|
||||||
chill_main.paginator.twig_extensions:
|
chill_main.paginator.twig_extensions:
|
||||||
|
@@ -11,7 +11,3 @@ services:
|
|||||||
Chill\MainBundle\Serializer\Normalizer\UserNormalizer:
|
Chill\MainBundle\Serializer\Normalizer\UserNormalizer:
|
||||||
tags:
|
tags:
|
||||||
- { name: 'serializer.normalizer', priority: 64 }
|
- { name: 'serializer.normalizer', priority: 64 }
|
||||||
|
|
||||||
Chill\MainBundle\Serializer\Normalizer\CollectionNormalizer:
|
|
||||||
tags:
|
|
||||||
- { name: 'serializer.normalizer', priority: 64 }
|
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Chill\Migrations\Main;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the postgis extension
|
|
||||||
*/
|
|
||||||
final class Version20210414091001 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function up(Schema $schema) : void
|
|
||||||
{
|
|
||||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
|
||||||
|
|
||||||
$this->addSql('CREATE EXTENSION IF NOT EXISTS postgis;');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema) : void
|
|
||||||
{
|
|
||||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
|
||||||
|
|
||||||
$this->addSql('DROP EXTENSION IF NOT EXISTS postgis;');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return "Enable the postgis extension in public schema";
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Chill\Migrations\Main;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add new fields to address, including a Point geometry field.
|
|
||||||
*/
|
|
||||||
final class Version20210420115006 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription() : string
|
|
||||||
{
|
|
||||||
return 'Add a Point data type and modify the Address entity';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema) : void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address RENAME COLUMN streetaddress1 TO street;');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address RENAME COLUMN streetaddress2 TO streetNumber;');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD floor VARCHAR(16) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD corridor VARCHAR(16) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD steps VARCHAR(16) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD buildingName VARCHAR(255) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD flat VARCHAR(16) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD distribution VARCHAR(255) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD extra VARCHAR(255) DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD validTo DATE DEFAULT NULL');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD point geometry(POINT,4326) DEFAULT NULL');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function down(Schema $schema) : void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address RENAME COLUMN street TO streetaddress1;');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address RENAME COLUMN streetNumber TO streetaddress2;');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP floor');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP corridor');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP steps');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP buildingName');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP flat');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP distribution');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP extra');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP validTo');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP point');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Chill\Migrations\Main;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a AddressReference table for storing authoritative address data
|
|
||||||
*/
|
|
||||||
final class Version20210503085107 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'Add a AddressReference table for storing authoritative address data';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('CREATE SEQUENCE chill_main_address_reference_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
|
||||||
$this->addSql('CREATE TABLE chill_main_address_reference (id INT NOT NULL, postcode_id INT DEFAULT NULL, refId VARCHAR(255) NOT NULL, street VARCHAR(255) DEFAULT NULL, streetNumber VARCHAR(255) DEFAULT NULL, municipalityCode VARCHAR(255) DEFAULT NULL, source VARCHAR(255) DEFAULT NULL, point geometry(POINT,4326) NOT NULL, PRIMARY KEY(id))');
|
|
||||||
$this->addSql('CREATE INDEX IDX_CA6C1BD7EECBFDF1 ON chill_main_address_reference (postcode_id)');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address_reference ADD CONSTRAINT FK_CA6C1BD7EECBFDF1 FOREIGN KEY (postcode_id) REFERENCES chill_main_postal_code (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('DROP SEQUENCE chill_main_address_reference_id_seq CASCADE');
|
|
||||||
$this->addSql('DROP TABLE chill_main_address_reference');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Chill\Migrations\Main;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add linkedToThirdParty field to Address
|
|
||||||
*/
|
|
||||||
final class Version20210505153727 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'Add linkedToThirdParty field to Address';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address ADD linkedToThirdParty_id INT DEFAULT NULL');
|
|
||||||
$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');
|
|
||||||
$this->addSql('CREATE INDEX IDX_165051F6114B8DD9 ON chill_main_address (linkedToThirdParty_id)');
|
|
||||||
$this->addSql('
|
|
||||||
CREATE TABLE chill_main_address_legacy AS
|
|
||||||
TABLE chill_main_address;
|
|
||||||
');
|
|
||||||
$this->addSql('
|
|
||||||
WITH hydrated_addresses AS (
|
|
||||||
SELECT *, rank() OVER (PARTITION BY pa_a.person_id ORDER BY validfrom)
|
|
||||||
FROM chill_main_address AS aa JOIN chill_person_persons_to_addresses AS pa_a ON aa.id = pa_a.address_id
|
|
||||||
)
|
|
||||||
UPDATE chill_main_address AS b
|
|
||||||
SET validto = (
|
|
||||||
SELECT validfrom - INTERVAL \'1 DAY\'
|
|
||||||
FROM hydrated_addresses
|
|
||||||
WHERE hydrated_addresses.id = (
|
|
||||||
SELECT a1.id
|
|
||||||
FROM hydrated_addresses AS a1 JOIN hydrated_addresses AS a2 ON a2.person_id = a1.person_id AND a2.rank = (a1.rank-1)
|
|
||||||
WHERE a2.id = b.id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT FK_165051F6114B8DD9');
|
|
||||||
$this->addSql('DROP INDEX IDX_165051F6114B8DD9');
|
|
||||||
$this->addSql('ALTER TABLE chill_main_address DROP linkedToThirdParty_id');
|
|
||||||
$this->addSql('DROP TABLE IF EXISTS chill_main_address_legacy');
|
|
||||||
$this->addSql('
|
|
||||||
UPDATE chill_main_address
|
|
||||||
SET validto = null;
|
|
||||||
');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
class AccompanyingCourseApiController extends ApiController
|
|
||||||
{
|
|
||||||
protected EventDispatcherInterface $eventDispatcher;
|
|
||||||
|
|
||||||
protected ValidatorInterface $validator;
|
|
||||||
|
|
||||||
public function __construct(EventDispatcherInterface $eventDispatcher, $validator)
|
|
||||||
{
|
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
|
||||||
$this->validator = $validator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function participationApi($id, Request $request, $_format)
|
|
||||||
{
|
|
||||||
/** @var AccompanyingPeriod $accompanyingPeriod */
|
|
||||||
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
|
|
||||||
$person = $this->getSerializer()
|
|
||||||
->deserialize($request->getContent(), Person::class, $_format, []);
|
|
||||||
|
|
||||||
if (NULL === $person) {
|
|
||||||
throw new BadRequestException('person id not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add acl
|
|
||||||
//
|
|
||||||
$this->onPostCheckACL('participation', $request, $_format, $accompanyingPeriod);
|
|
||||||
|
|
||||||
switch ($request->getMethod()) {
|
|
||||||
case Request::METHOD_POST:
|
|
||||||
$participation = $accompanyingPeriod->addPerson($person);
|
|
||||||
break;
|
|
||||||
case Request::METHOD_DELETE:
|
|
||||||
$participation = $accompanyingPeriod->removePerson($person);
|
|
||||||
$participation->setEndDate(new \DateTimeImmutable('now'));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new BadRequestException("This method is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
$errors = $this->validator->validate($accompanyingPeriod);
|
|
||||||
|
|
||||||
if ($errors->count() > 0) {
|
|
||||||
// only format accepted
|
|
||||||
return $this->json($errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->getDoctrine()->getManager()->flush();
|
|
||||||
|
|
||||||
return $this->json($participation);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
|
|
||||||
{
|
|
||||||
$this->eventDispatcher->dispatch(
|
|
||||||
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
|
|
||||||
new AccompanyingPeriodPrivacyEvent($entity, [
|
|
||||||
'action' => $action,
|
|
||||||
'request' => $request->getMethod()
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -121,7 +121,7 @@ class AccompanyingCourseController extends Controller
|
|||||||
* @Route(
|
* @Route(
|
||||||
* "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}",
|
* "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}",
|
||||||
* name="chill_person_accompanying_course_api_add_participation",
|
* name="chill_person_accompanying_course_api_add_participation",
|
||||||
* methods={"POST","DELETE"},
|
* methods={"POST"},
|
||||||
* format="json",
|
* format="json",
|
||||||
* requirements={
|
* requirements={
|
||||||
* "_format": "json",
|
* "_format": "json",
|
||||||
@@ -129,7 +129,7 @@ class AccompanyingCourseController extends Controller
|
|||||||
* )
|
* )
|
||||||
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
||||||
*/
|
*/
|
||||||
public function participationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
|
public function addParticipationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
|
||||||
{
|
{
|
||||||
switch ($_format) {
|
switch ($_format) {
|
||||||
case 'json':
|
case 'json':
|
||||||
@@ -146,9 +146,7 @@ class AccompanyingCourseController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO add acl
|
// TODO add acl
|
||||||
$participation = ($request->getMethod() === 'POST') ?
|
$accompanyingCourse->addPerson($person);
|
||||||
$accompanyingCourse->addPerson($person) : $accompanyingCourse->removePerson($person);
|
|
||||||
|
|
||||||
$errors = $this->validator->validate($accompanyingCourse);
|
$errors = $this->validator->validate($accompanyingCourse);
|
||||||
|
|
||||||
if ($errors->count() > 0) {
|
if ($errors->count() > 0) {
|
||||||
@@ -158,6 +156,6 @@ class AccompanyingCourseController extends Controller
|
|||||||
|
|
||||||
$this->getDoctrine()->getManager()->flush();
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
return $this->json($participation);
|
return new JsonResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Controller;
|
|
||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class OpeningApiController extends ApiController
|
|
||||||
{
|
|
||||||
protected function customizeQuery(string $action, Request $request, $qb): void
|
|
||||||
{
|
|
||||||
$qb->where($qb->expr()->gt('e.noActiveAfter', ':now'))
|
|
||||||
->orWhere($qb->expr()->isNull('e.noActiveAfter'));
|
|
||||||
$qb->setParameter('now', new \DateTime('now'));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chill is a software for social workers
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
|
||||||
* <http://www.champs-libres.coop>, <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\DataFixtures\ORM;
|
|
||||||
|
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
|
||||||
use Doctrine\Persistence\ObjectManager;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|
||||||
use Chill\PersonBundle\Entity\Person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of LoadAccompanyingPeriod
|
|
||||||
*
|
|
||||||
* @author Champs-Libres Coop
|
|
||||||
*/
|
|
||||||
class LoadAccompanyingPeriod extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
|
|
||||||
{
|
|
||||||
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
|
||||||
|
|
||||||
|
|
||||||
public const ACCOMPANYING_PERIOD = 'parcours 1';
|
|
||||||
|
|
||||||
public function getOrder()
|
|
||||||
{
|
|
||||||
return 10004;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static $references = array();
|
|
||||||
|
|
||||||
public function load(ObjectManager $manager)
|
|
||||||
{
|
|
||||||
|
|
||||||
$centerA = $this->getReference('centerA');
|
|
||||||
$centerAId = $centerA->getId();
|
|
||||||
|
|
||||||
$personIds = $this->container->get('doctrine.orm.entity_manager')
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('p.id')
|
|
||||||
->from('ChillPersonBundle:Person', 'p')
|
|
||||||
->where('p.center = :centerAId')
|
|
||||||
->orderBy('p.id', 'ASC')
|
|
||||||
->setParameter('centerAId', $centerAId)
|
|
||||||
->getQuery()
|
|
||||||
->getScalarResult();
|
|
||||||
|
|
||||||
$openingDate = new \DateTime('2020-04-01');
|
|
||||||
|
|
||||||
$person1 = $manager->getRepository(Person::class)->find($personIds[0]);
|
|
||||||
$person2 = $manager->getRepository(Person::class)->find($personIds[1]);
|
|
||||||
|
|
||||||
$socialScope = $this->getReference('scope_social');
|
|
||||||
|
|
||||||
$a = new AccompanyingPeriod($openingDate);
|
|
||||||
$a->addPerson($person1);
|
|
||||||
$a->addPerson($person2);
|
|
||||||
$a->addScope($socialScope);
|
|
||||||
$a->setStep(AccompanyingPeriod::STEP_CONFIRMED);
|
|
||||||
|
|
||||||
$manager->persist($a);
|
|
||||||
|
|
||||||
$this->addReference(self::ACCOMPANYING_PERIOD, $a);
|
|
||||||
echo "Adding one AccompanyingPeriod\n";
|
|
||||||
|
|
||||||
$manager->flush();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,62 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chill is a software for social workers
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
|
||||||
* <http://www.champs-libres.coop>, <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\DataFixtures\ORM;
|
|
||||||
|
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
|
||||||
use Doctrine\Persistence\ObjectManager;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of LoadAccompanyingPeriodOrigin
|
|
||||||
*
|
|
||||||
* @author Champs-Libres Coop
|
|
||||||
*/
|
|
||||||
class LoadAccompanyingPeriodOrigin extends AbstractFixture implements OrderedFixtureInterface
|
|
||||||
{
|
|
||||||
|
|
||||||
public const ACCOMPANYING_PERIOD_ORIGIN = 'accompanying_period_origin';
|
|
||||||
|
|
||||||
public function getOrder()
|
|
||||||
{
|
|
||||||
return 10005;
|
|
||||||
}
|
|
||||||
|
|
||||||
private $phoneCall = ['en' => 'phone call', 'fr' => 'appel téléphonique'];
|
|
||||||
|
|
||||||
public static $references = array();
|
|
||||||
|
|
||||||
public function load(ObjectManager $manager)
|
|
||||||
{
|
|
||||||
$o = new Origin();
|
|
||||||
$o->setLabel(json_encode($this->phoneCall));
|
|
||||||
|
|
||||||
$manager->persist($o);
|
|
||||||
|
|
||||||
$this->addReference(self::ACCOMPANYING_PERIOD_ORIGIN, $o);
|
|
||||||
echo "Adding one AccompanyingPeriod Origin\n";
|
|
||||||
|
|
||||||
$manager->flush();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -29,7 +29,6 @@ use Chill\PersonBundle\Entity\Person;
|
|||||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||||
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Doctrine\Model\Point;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load people into database
|
* Load people into database
|
||||||
@@ -227,24 +226,8 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
echo "add person'".$p->__toString()."'\n";
|
echo "add person'".$p->__toString()."'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a random point
|
* Creata a random address
|
||||||
*
|
|
||||||
* @return Point
|
|
||||||
*/
|
|
||||||
private function getRandomPoint()
|
|
||||||
{
|
|
||||||
$lonBrussels = 4.35243;
|
|
||||||
$latBrussels = 50.84676;
|
|
||||||
$lon = $lonBrussels + 0.01 * rand(-5, 5);
|
|
||||||
$lat = $latBrussels + 0.01 * rand(-5, 5);
|
|
||||||
return Point::fromLonLat($lon, $lat);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a random address
|
|
||||||
*
|
*
|
||||||
* @return Address
|
* @return Address
|
||||||
*/
|
*/
|
||||||
@@ -255,9 +238,6 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
->setStreetAddress2(
|
->setStreetAddress2(
|
||||||
rand(0,9) > 5 ? $this->faker->streetAddress : ''
|
rand(0,9) > 5 ? $this->faker->streetAddress : ''
|
||||||
)
|
)
|
||||||
->setPoint(
|
|
||||||
rand(0,9) > 5 ? $this->getRandomPoint() : NULL
|
|
||||||
)
|
|
||||||
->setPostcode($this->getReference(
|
->setPostcode($this->getReference(
|
||||||
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
|
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
|
||||||
))
|
))
|
||||||
|
@@ -25,7 +25,6 @@ use Doctrine\Persistence\ObjectManager;
|
|||||||
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
|
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
|
||||||
use Chill\MainBundle\Entity\RoleScope;
|
use Chill\MainBundle\Entity\RoleScope;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a role CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE for all groups except administrative,
|
* Add a role CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE for all groups except administrative,
|
||||||
@@ -45,7 +44,6 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
{
|
{
|
||||||
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
||||||
$permissionsGroup = $this->getReference($permissionsGroupRef);
|
$permissionsGroup = $this->getReference($permissionsGroupRef);
|
||||||
$scopeSocial = $this->getReference('scope_social');
|
|
||||||
|
|
||||||
//create permission group
|
//create permission group
|
||||||
switch ($permissionsGroup->getName()) {
|
switch ($permissionsGroup->getName()) {
|
||||||
@@ -53,12 +51,6 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
case 'direction':
|
case 'direction':
|
||||||
printf("Adding CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE to %s permission group \n", $permissionsGroup->getName());
|
printf("Adding CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE to %s permission group \n", $permissionsGroup->getName());
|
||||||
|
|
||||||
$permissionsGroup->addRoleScope(
|
|
||||||
(new RoleScope())
|
|
||||||
->setRole(AccompanyingPeriodVoter::SEE)
|
|
||||||
->setScope($scopeSocial)
|
|
||||||
);
|
|
||||||
|
|
||||||
$roleScopeUpdate = (new RoleScope())
|
$roleScopeUpdate = (new RoleScope())
|
||||||
->setRole('CHILL_PERSON_UPDATE')
|
->setRole('CHILL_PERSON_UPDATE')
|
||||||
->setScope(null);
|
->setScope(null);
|
||||||
|
@@ -28,7 +28,6 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
|||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ChillPersonExtension
|
* Class ChillPersonExtension
|
||||||
@@ -77,7 +76,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
$loader->load('services/templating.yaml');
|
$loader->load('services/templating.yaml');
|
||||||
$loader->load('services/alt_names.yaml');
|
$loader->load('services/alt_names.yaml');
|
||||||
$loader->load('services/serializer.yaml');
|
$loader->load('services/serializer.yaml');
|
||||||
$loader->load('services/security.yaml');
|
|
||||||
|
|
||||||
// load service advanced search only if configure
|
// load service advanced search only if configure
|
||||||
if ($config['search']['search_by_phone'] != 'never') {
|
if ($config['search']['search_by_phone'] != 'never') {
|
||||||
@@ -309,55 +307,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
'template' => '@ChillPerson/MaritalStatus/edit.html.twig',
|
'template' => '@ChillPerson/MaritalStatus/edit.html.twig',
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
],
|
|
||||||
],
|
|
||||||
'apis' => [
|
|
||||||
[
|
|
||||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
|
||||||
'name' => 'accompanying_course',
|
|
||||||
'base_path' => '/api/1.0/person/accompanying-course',
|
|
||||||
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
|
|
||||||
'actions' => [
|
|
||||||
'_entity' => [
|
|
||||||
'roles' => [
|
|
||||||
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'participation' => [
|
|
||||||
'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
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Origin::class,
|
|
||||||
'name' => 'accompanying_period_origin',
|
|
||||||
'base_path' => '/api/1.0/person/accompanying-period/origin',
|
|
||||||
'controller' => \Chill\PersonBundle\Controller\OpeningApiController::class,
|
|
||||||
'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
|
|
||||||
]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
@@ -118,7 +118,7 @@ class AccompanyingPeriod
|
|||||||
*
|
*
|
||||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
||||||
* mappedBy="accompanyingPeriod",
|
* mappedBy="accompanyingPeriod",
|
||||||
* cascade={"persist", "refresh", "remove", "merge", "detach"})
|
* cascade={"persist", "remove", "merge", "detach"})
|
||||||
*/
|
*/
|
||||||
private $participations;
|
private $participations;
|
||||||
|
|
||||||
@@ -344,68 +344,50 @@ class AccompanyingPeriod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the participation containing a person
|
* This private function scan Participations Collection,
|
||||||
|
* searching for a given Person
|
||||||
*/
|
*/
|
||||||
public function getParticipationsContainsPerson(Person $person): Collection
|
private function participationsContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
||||||
{
|
{
|
||||||
return $this->getParticipations($person)->filter(
|
foreach ($this->participations as $participation) {
|
||||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
/** @var AccompanyingPeriodParticipation $participation */
|
||||||
if ($person === $participation->getPerson()) {
|
if ($person === $participation->getPerson()) {
|
||||||
return $participation;
|
return $participation;
|
||||||
}
|
}}
|
||||||
});
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the opened participation containing a person
|
* This public function is the same but return only true or false
|
||||||
*
|
|
||||||
* "Open" means that the closed date is NULL
|
|
||||||
*/
|
|
||||||
public function getOpenParticipationContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
|
||||||
{
|
|
||||||
$collection = $this->getParticipationsContainsPerson($person)->filter(
|
|
||||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
|
||||||
if (NULL === $participation->getEndDate()) {
|
|
||||||
return $participation;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $collection->count() > 0 ? $collection->first() : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the accompanying period contains a person.
|
|
||||||
*
|
|
||||||
* **Note**: this participation can be opened or not.
|
|
||||||
*/
|
*/
|
||||||
public function containsPerson(Person $person): bool
|
public function containsPerson(Person $person): bool
|
||||||
{
|
{
|
||||||
return $this->getParticipationsContainsPerson($person)->count() > 0;
|
return ($this->participationsContainsPerson($person) === null) ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Person
|
* Add Person
|
||||||
*/
|
*/
|
||||||
public function addPerson(Person $person = null): AccompanyingPeriodParticipation
|
public function addPerson(Person $person = null): self
|
||||||
{
|
{
|
||||||
$participation = new AccompanyingPeriodParticipation($this, $person);
|
$participation = new AccompanyingPeriodParticipation($this, $person);
|
||||||
$this->participations[] = $participation;
|
$this->participations[] = $participation;
|
||||||
|
|
||||||
return $participation;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Person
|
* Remove Person
|
||||||
*/
|
*/
|
||||||
public function removePerson(Person $person): ?AccompanyingPeriodParticipation
|
public function removePerson(Person $person): void
|
||||||
{
|
{
|
||||||
$participation = $this->getOpenParticipationContainsPerson($person);
|
$participation = $this->participationsContainsPerson($person);
|
||||||
|
|
||||||
if ($participation instanceof AccompanyingPeriodParticipation) {
|
if (! null === $participation) {
|
||||||
$participation->setEndDate(new \DateTimeImmutable('now'));
|
$participation->setEndDate(new \DateTimeImmutable('now'));
|
||||||
|
$this->participations->removeElement($participation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $participation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
namespace App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Result;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Result;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
use App\Repository\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
namespace App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Goal;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Result;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Result;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkGoalRepository;
|
use App\Repository\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoalRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\OriginRepository;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\OriginRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +53,7 @@ class Origin
|
|||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLabel()
|
public function getLabel(): ?string
|
||||||
{
|
{
|
||||||
return $this->label;
|
return $this->label;
|
||||||
}
|
}
|
||||||
|
@@ -1,70 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
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(repositoryClass=HouseholdRepository::class)
|
|
||||||
*/
|
|
||||||
class Household
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Addresses
|
|
||||||
* @var Collection
|
|
||||||
*
|
|
||||||
* @ORM\ManyToMany(
|
|
||||||
* targetEntity="Chill\MainBundle\Entity\Address",
|
|
||||||
* cascade={"persist", "remove", "merge", "detach"})
|
|
||||||
* @ORM\JoinTable(name="chill_person_household_to_addresses")
|
|
||||||
* @ORM\OrderBy({"validFrom" = "DESC"})
|
|
||||||
*/
|
|
||||||
private $addresses;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Address $address
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addAddress(Address $address)
|
|
||||||
{
|
|
||||||
$this->addresses[] = $address;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Address $address
|
|
||||||
*/
|
|
||||||
public function removeAddress(Address $address)
|
|
||||||
{
|
|
||||||
$this->addresses->removeElement($address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, the addresses are ordered by date, descending (the most
|
|
||||||
* recent first)
|
|
||||||
*
|
|
||||||
* @return \Chill\MainBundle\Entity\Address[]
|
|
||||||
*/
|
|
||||||
public function getAddresses()
|
|
||||||
{
|
|
||||||
return $this->addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,153 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
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(repositoryClass=HouseholdMembersRepository::class)
|
|
||||||
*/
|
|
||||||
class HouseholdMembers
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $position;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="date")
|
|
||||||
*/
|
|
||||||
private $startDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="date")
|
|
||||||
*/
|
|
||||||
private $endDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $comment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="boolean")
|
|
||||||
*/
|
|
||||||
private $sharedHousehold;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var Person
|
|
||||||
* @ORM\ManyToOne(
|
|
||||||
* targetEntity="\Chill\PersonBundle\Entity\Person"
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
private $person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var Household
|
|
||||||
* @ORM\ManyToOne(
|
|
||||||
* targetEntity="\Chill\PersonBundle\Entity\Household\Household"
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
private $household;
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPosition(): ?string
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPosition(?string $position): self
|
|
||||||
{
|
|
||||||
$this->position = $position;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStartDate(): ?\DateTimeInterface
|
|
||||||
{
|
|
||||||
return $this->startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStartDate(\DateTimeInterface $startDate): self
|
|
||||||
{
|
|
||||||
$this->startDate = $startDate;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEndDate(): ?\DateTimeInterface
|
|
||||||
{
|
|
||||||
return $this->endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEndDate(\DateTimeInterface $endDate): self
|
|
||||||
{
|
|
||||||
$this->endDate = $endDate;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getComment(): ?string
|
|
||||||
{
|
|
||||||
return $this->comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setComment(?string $comment): self
|
|
||||||
{
|
|
||||||
$this->comment = $comment;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSharedHousehold(): ?bool
|
|
||||||
{
|
|
||||||
return $this->sharedHousehold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSharedHousehold(bool $sharedHousehold): self
|
|
||||||
{
|
|
||||||
$this->sharedHousehold = $sharedHousehold;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPerson(): ?Person
|
|
||||||
{
|
|
||||||
return $this->person;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPerson(?Person $person): self
|
|
||||||
{
|
|
||||||
$this->person = $person;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHousehold(): ?Household
|
|
||||||
{
|
|
||||||
return $this->household;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHousehold(?Household $household): self
|
|
||||||
{
|
|
||||||
$this->household = $household;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -22,17 +22,15 @@ namespace Chill\PersonBundle\Entity;
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use ArrayIterator;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Criteria;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\Country;
|
use Chill\MainBundle\Entity\Country;
|
||||||
use Chill\PersonBundle\Entity\MaritalStatus;
|
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
use DateTime;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
use Doctrine\Common\Collections\Criteria;
|
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,7 +388,7 @@ class Person implements HasCenterInterface
|
|||||||
*
|
*
|
||||||
* @deprecated since 1.1 use `getOpenedAccompanyingPeriod instead
|
* @deprecated since 1.1 use `getOpenedAccompanyingPeriod instead
|
||||||
*/
|
*/
|
||||||
public function getCurrentAccompanyingPeriod() : ?AccompanyingPeriod
|
public function getCurrentAccompanyingPeriod() : AccompanyingPeriod
|
||||||
{
|
{
|
||||||
return $this->getOpenedAccompanyingPeriod();
|
return $this->getOpenedAccompanyingPeriod();
|
||||||
}
|
}
|
||||||
@@ -1010,13 +1008,19 @@ class Person implements HasCenterInterface
|
|||||||
/**
|
/**
|
||||||
* By default, the addresses are ordered by date, descending (the most
|
* By default, the addresses are ordered by date, descending (the most
|
||||||
* recent first)
|
* recent first)
|
||||||
|
*
|
||||||
|
* @return \Chill\MainBundle\Entity\Address[]
|
||||||
*/
|
*/
|
||||||
public function getAddresses(): Collection
|
public function getAddresses()
|
||||||
{
|
{
|
||||||
return $this->addresses;
|
return $this->addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastAddress(DateTime $from = null)
|
/**
|
||||||
|
* @param \DateTime|null $date
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function getLastAddress(\DateTime $date = null)
|
||||||
{
|
{
|
||||||
$from ??= new DateTime('now');
|
$from ??= new DateTime('now');
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
namespace App\Entity\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
use App\Repository\Chill\PersonBundle\Entity\SocialWork\EvaluationRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
namespace App\Entity\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
|
use App\Repository\Chill\PersonBundle\Entity\SocialWork\GoalRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
namespace App\Entity\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
use App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
|
use App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
|
||||||
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
|
use App\Repository\Chill\PersonBundle\Entity\SocialWork\ResultRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
namespace App\Entity\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
use App\Repository\Chill\PersonBundle\Entity\SocialWork\SocialActionRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
|
||||||
|
|
||||||
|
namespace App\Entity\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
use App\Repository\Chill\PersonBundle\Entity\SocialWork\SocialIssueRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
|
namespace App\Repository\Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
|
use App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
|
namespace App\Repository\Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
use App\Entity\Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -23,7 +23,6 @@
|
|||||||
namespace Chill\PersonBundle\Repository;
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\Household;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\Household\HouseholdMembers;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\Household;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace App\Repository\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace App\Repository\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Goal;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace App\Repository\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Result;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\Result;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace App\Repository\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Repository\SocialWork;
|
namespace App\Repository\Chill\PersonBundle\Entity\SocialWork;
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
use App\Entity\Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<accompanying-course v-bind:accompanying_course="accompanying_course"/>
|
||||||
|
<persons-associated v-bind:persons_associated="accompanying_course.persons"/>
|
||||||
|
<requestor v-bind:accompanying_course="accompanying_course"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AccompanyingCourse from './components/AccompanyingCourse.vue';
|
||||||
|
import PersonsAssociated from './components/PersonsAssociated.vue';
|
||||||
|
import Requestor from './components/Requestor.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
AccompanyingCourse,
|
||||||
|
PersonsAssociated,
|
||||||
|
Requestor
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
accompanying_course: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
accompanyingCourseId() {
|
||||||
|
return window.accompanyingCourseId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getAccompanyingCourse() {
|
||||||
|
let data_;
|
||||||
|
return fetch(`/fr/api/parcours/${accompanyingCourseId}/show`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.$data.accompanying_course = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.getAccompanyingCourse();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vue-component">
|
||||||
|
<h3>Parcours</h3>
|
||||||
|
<dl>
|
||||||
|
<dt>id</dt>
|
||||||
|
<dd>{{ accompanying_course.id }}</dd>
|
||||||
|
<dt>opening_date</dt>
|
||||||
|
<dd>{{ accompanying_course.opening_date }}</dd>
|
||||||
|
<dt>closing_date</dt>
|
||||||
|
<dd>{{ accompanying_course.closing_date }}</dd>
|
||||||
|
<dt>remark</dt>
|
||||||
|
<dd>{{ accompanying_course.remark }}</dd>
|
||||||
|
<dt>closing_motive</dt>
|
||||||
|
<dd>{{ accompanying_course.closing_motive }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AccompanyingCourse',
|
||||||
|
props: {
|
||||||
|
accompanying_course: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<tr>
|
||||||
|
<td>{{ person.firstname }}</td>
|
||||||
|
<td>{{ person.lastname }}</td>
|
||||||
|
<td>{{ person.startdate }}</td>
|
||||||
|
<td>{{ person.enddate }}</td>
|
||||||
|
<td>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li><button class="sc-button bt-show"></button></li>
|
||||||
|
<li><button class="sc-button bt-update"></button></li>
|
||||||
|
<li><button class="sc-button bt-delete" @click.prevent="$emit('remove', person)"></button></li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'PersonItem',
|
||||||
|
props: {
|
||||||
|
person: { type: Object, required: true }
|
||||||
|
},
|
||||||
|
emits: ['remove']
|
||||||
|
}
|
||||||
|
</script>
|
@@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vue-component">
|
||||||
|
<h3>Usagers concernés</h3>
|
||||||
|
|
||||||
|
<label>{{ counter }} usagers</label>
|
||||||
|
|
||||||
|
<table class="rounded">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="chill-orange">firstname</th>
|
||||||
|
<th class="chill-orange">lastname</th>
|
||||||
|
<th class="chill-orange">startdate</th>
|
||||||
|
<th class="chill-orange">enddate</th>
|
||||||
|
<th class="chill-orange">actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<person-item
|
||||||
|
v-for="person in persons_associated"
|
||||||
|
v-bind:person="person"
|
||||||
|
v-bind:key="person.id"
|
||||||
|
@remove="removePerson" />
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li><button class="sc-button bt-create" @click="addPerson">Ajouter un usager</button></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PersonItem from "./PersonItem.vue"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PersonsAssociated',
|
||||||
|
components: {
|
||||||
|
PersonItem
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
persons_associated: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
persons: this.persons_associated
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
async counter() {
|
||||||
|
// Pourquoi je peux pas compter un tableau avec length ???!!!
|
||||||
|
return this.persons_associated.length // <= boum !
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addPerson() {
|
||||||
|
this.persons_associated.push({
|
||||||
|
"firstname": "Lisa",
|
||||||
|
"lastname": "Simpson",
|
||||||
|
"startdate": "1975-09-15",
|
||||||
|
"enddate": "2021-04-20"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
removePerson(item) {
|
||||||
|
this.persons_associated = this.persons_associated.filter(person => person !== item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vue-component">
|
||||||
|
<h3>Demandeur</h3>
|
||||||
|
{{ accompanying_course.id }}
|
||||||
|
{{ accompanying_course.remark }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Requestor',
|
||||||
|
props: {
|
||||||
|
accompanying_course: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@@ -0,0 +1,8 @@
|
|||||||
|
import App from './App.vue';
|
||||||
|
import { createApp } from 'vue';
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
template: `<app></app>`
|
||||||
|
})
|
||||||
|
.component('app', App)
|
||||||
|
.mount('#accompanying-course');
|
@@ -1,25 +0,0 @@
|
|||||||
<template>
|
|
||||||
<accompanying-course></accompanying-course>
|
|
||||||
<persons-associated></persons-associated>
|
|
||||||
<requestor></requestor>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
import AccompanyingCourse from './components/AccompanyingCourse.vue';
|
|
||||||
import PersonsAssociated from './components/PersonsAssociated.vue';
|
|
||||||
import Requestor from './components/Requestor.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'App',
|
|
||||||
components: {
|
|
||||||
AccompanyingCourse,
|
|
||||||
PersonsAssociated,
|
|
||||||
Requestor
|
|
||||||
},
|
|
||||||
computed: mapState([
|
|
||||||
'accompanyingCourse'
|
|
||||||
])
|
|
||||||
};
|
|
||||||
</script>
|
|
@@ -1,49 +0,0 @@
|
|||||||
const
|
|
||||||
locale = 'fr',
|
|
||||||
format = 'json'
|
|
||||||
, accompanying_period_id = window.accompanyingCourseId //tmp
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Endpoint chill_person_accompanying_course_api_show
|
|
||||||
* method GET, get AccompanyingCourse Object
|
|
||||||
*
|
|
||||||
* @accompanying_period_id___ integer
|
|
||||||
* @TODO var is not used but necessary in method signature
|
|
||||||
*/
|
|
||||||
let getAccompanyingCourse = (accompanying_period_id___) => { //tmp
|
|
||||||
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/show.${format}`;
|
|
||||||
return fetch(url)
|
|
||||||
.then(response => {
|
|
||||||
if (response.ok) { return response.json(); }
|
|
||||||
throw Error('Error with request resource response');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Endpoint chill_person_accompanying_course_api_add_participation,
|
|
||||||
* method POST/DELETE, add/close a participation to the accompanyingCourse
|
|
||||||
*
|
|
||||||
* @accompanying_period_id integer - id of accompanyingCourse
|
|
||||||
* @person_id integer - id of person
|
|
||||||
* @method string - POST or DELETE
|
|
||||||
*/
|
|
||||||
let postParticipation = (accompanying_period_id, person_id, method) => {
|
|
||||||
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/participation.${format}`
|
|
||||||
return fetch(url, {
|
|
||||||
method: method,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({id: person_id})
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
if (response.ok) { return response.json(); }
|
|
||||||
throw Error('Error with request resource response');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
getAccompanyingCourse,
|
|
||||||
postParticipation
|
|
||||||
};
|
|
@@ -1,28 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="vue-component">
|
|
||||||
<h3>{{ $t('course.title') }}</h3>
|
|
||||||
<dl>
|
|
||||||
<dt>{{ $t('course.id') }}</dt>
|
|
||||||
<dd>{{ accompanyingCourse.id }}</dd>
|
|
||||||
<dt>{{ $t('course.opening_date') }}</dt>
|
|
||||||
<dd>{{ $d(accompanyingCourse.openingDate.datetime, 'short') }}</dd>
|
|
||||||
<dt>{{ $t('course.closing_date') }}</dt>
|
|
||||||
<dd>{{ $d(accompanyingCourse.closingDate.datetime, 'short') }}</dd>
|
|
||||||
<dt>{{ $t('course.remark') }}</dt>
|
|
||||||
<dd>{{ accompanyingCourse.remark }}</dd>
|
|
||||||
<dt>{{ $t('course.closing_motive') }}</dt>
|
|
||||||
<dd>{{ accompanyingCourse.closing_motive }}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'AccompanyingCourse',
|
|
||||||
computed: {
|
|
||||||
accompanyingCourse() {
|
|
||||||
return this.$store.state.accompanyingCourse
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user