mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
bootstrap api and apply on accompanying period
This commit is contained in:
parent
f02e33fda7
commit
07e0692783
@ -0,0 +1,76 @@
|
|||||||
|
<?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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
||||||
|
$container->setParameter($param, $crudEntry);
|
||||||
|
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
||||||
|
|
||||||
|
$container->setDefinition($controllerServiceName, $controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -33,6 +33,7 @@ class AbstractCRUDController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the complete FQDN of the class
|
||||||
*
|
*
|
||||||
* @return string the complete fqdn of the class
|
* @return string the complete fqdn of the class
|
||||||
*/
|
*/
|
||||||
@ -42,7 +43,7 @@ class AbstractCRUDController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* called on post fetch entity
|
||||||
*/
|
*/
|
||||||
protected function onPostFetchEntity(string $action, Request $request, $entity, $_format): ?Response
|
protected function onPostFetchEntity(string $action, Request $request, $entity, $_format): ?Response
|
||||||
{
|
{
|
||||||
@ -50,14 +51,13 @@ class AbstractCRUDController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Called on post check ACL
|
||||||
*/
|
*/
|
||||||
protected function onPostCheckACL(string $action, Request $request, $entity, $_format): ?Response
|
protected function onPostCheckACL(string $action, Request $request, $entity, $_format): ?Response
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check the acl. Called by every action.
|
* check the acl. Called by every action.
|
||||||
*
|
*
|
||||||
@ -74,12 +74,20 @@ class AbstractCRUDController extends AbstractController
|
|||||||
$this->denyAccessUnlessGranted($this->getRoleFor($action, $request, $entity, $_format), $entity);
|
$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)
|
protected function getActionConfig(string $action)
|
||||||
{
|
{
|
||||||
return $this->crudConfig['actions'][$action];
|
return $this->crudConfig['actions'][$action];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the crud configuration
|
* Set the crud configuration
|
||||||
*
|
*
|
||||||
@ -87,7 +95,6 @@ class AbstractCRUDController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function setCrudConfig(array $config): void
|
public function setCrudConfig(array $config): void
|
||||||
{
|
{
|
||||||
dump($config);
|
|
||||||
$this->crudConfig = $config;
|
$this->crudConfig = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ namespace Chill\MainBundle\CRUD\Controller;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
class ApiController extends AbstractCRUDController
|
class ApiController extends AbstractCRUDController
|
||||||
{
|
{
|
||||||
@ -114,22 +115,6 @@ class ApiController extends AbstractCRUDController
|
|||||||
|
|
||||||
protected function getSerializer(): SerializerInterface
|
protected function getSerializer(): SerializerInterface
|
||||||
{
|
{
|
||||||
return $this->get(SerializerInterface::class);
|
return $this->get('serializer');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Defined the services necessary for this controller
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getSubscribedServices(): array
|
|
||||||
{
|
|
||||||
return \array_merge(
|
|
||||||
parent::getSubscribedServices(),
|
|
||||||
[
|
|
||||||
SerializerInterface::class => SerializerInterface::class,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,7 @@ class CRUDRoutesLoader extends Loader
|
|||||||
protected function loadCrudConfig($crudConfig): RouteCollection
|
protected function loadCrudConfig($crudConfig): RouteCollection
|
||||||
{
|
{
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
$controller = $crudConfig['controller'] === CrudController::class ?
|
$controller ='cscrud_'.$crudConfig['name'].'_controller';
|
||||||
'cscrud_'.$crudConfig['name'].'_controller' : $crudConfig['controller'];
|
|
||||||
|
|
||||||
foreach ($crudConfig['actions'] as $name => $action) {
|
foreach ($crudConfig['actions'] as $name => $action) {
|
||||||
// defaults (controller name)
|
// defaults (controller name)
|
||||||
@ -144,8 +143,7 @@ class CRUDRoutesLoader extends Loader
|
|||||||
protected function loadApiSingle(array $crudConfig): RouteCollection
|
protected function loadApiSingle(array $crudConfig): RouteCollection
|
||||||
{
|
{
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
$controller = $crudConfig['controller'] === ApiController::class ?
|
$controller ='csapi_'.$crudConfig['name'].'_controller';
|
||||||
'cscrud_'.$crudConfig['name'].'_controller' : $crudConfig['controller'];
|
|
||||||
|
|
||||||
foreach ($crudConfig['actions'] as $name => $action) {
|
foreach ($crudConfig['actions'] as $name => $action) {
|
||||||
// filter only on single actions
|
// filter only on single actions
|
||||||
@ -160,7 +158,7 @@ class CRUDRoutesLoader extends Loader
|
|||||||
|
|
||||||
// path are rewritten
|
// path are rewritten
|
||||||
// if name === 'default', we rewrite it to nothing :-)
|
// if name === 'default', we rewrite it to nothing :-)
|
||||||
$localName = '_entity' === $name ? '' : $name;
|
$localName = '_entity' === $name ? '' : '/'.$name;
|
||||||
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
|
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
|
||||||
$path = $crudConfig['base_path'].$localPath;
|
$path = $crudConfig['base_path'].$localPath;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ 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\DependencyInjection\CompilerPass\CRUDControllerCompilerPass;
|
use Chill\MainBundle\CRUD\CompilerPass\CRUDControllerCompilerPass;
|
||||||
use Chill\MainBundle\Templating\Entity\CompilerPass as RenderEntityCompilerPass;
|
use Chill\MainBundle\Templating\Entity\CompilerPass as RenderEntityCompilerPass;
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,95 +210,24 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ContainerBuilder $container
|
* Load parameter for configuration and set parameters for api
|
||||||
* @param array $config the config under 'cruds' key
|
|
||||||
* @return null
|
|
||||||
*/
|
*/
|
||||||
protected function configureCruds(ContainerBuilder $container, $crudConfig, $apiConfig, Loader\YamlFileLoader $loader)
|
protected function configureCruds(
|
||||||
|
ContainerBuilder $container,
|
||||||
|
array $crudConfig,
|
||||||
|
array $apiConfig,
|
||||||
|
Loader\YamlFileLoader $loader
|
||||||
|
): void
|
||||||
{
|
{
|
||||||
if ((count($crudConfig) + count($apiConfig)) === 0) {
|
if (count($crudConfig) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump(array_keys($container->getDefinitions()));
|
|
||||||
|
|
||||||
$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', $crudConfig);
|
||||||
$container->setParameter('chill_main_api_route_loader_config', $apiConfig);
|
$container->setParameter('chill_main_api_route_loader_config', $apiConfig);
|
||||||
return;
|
|
||||||
/*
|
|
||||||
$definition = new Definition();
|
|
||||||
$definition
|
|
||||||
->setClass(\Chill\MainBundle\CRUD\Routing\CRUDRoutesLoader::class)
|
|
||||||
->addArgument('%chill_main_crud_route_loader_config%')
|
|
||||||
->addArgument('%chill_main_api_route_loader_config%')
|
|
||||||
;
|
|
||||||
|
|
||||||
$container->setDefinition('chill_main_crud_route_loader', $definition);
|
// Note: the controller are loaded inside compiler pass
|
||||||
*/
|
|
||||||
|
|
||||||
$alreadyExistingNames = [];
|
|
||||||
|
|
||||||
foreach ($crudConfig as $crudEntry) {
|
|
||||||
$this->configureCrudController($container, $crudEntry, 'crud');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($apiConfig as $crudEntry) {
|
|
||||||
$this->configureCrudController($container, $crudEntry, 'crud');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
{
|
|
||||||
$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_'.$apiOrCrud.'_config_'.$name, $crudEntry);
|
|
||||||
$container->getDefinition($controllerServiceName)
|
|
||||||
->addMethodCall('setCrudConfig', ['%chill_main_'.$apiOrCrud.'_config_'.$name.'%']);
|
|
||||||
/*
|
|
||||||
dump($controllerClass);
|
|
||||||
|
|
||||||
if ($container->hasDefinition($controllerClass)) {
|
|
||||||
dump('container has controller class');
|
|
||||||
$controllerServiceName = $controllerClass;
|
|
||||||
$controller = $container->getDefinition($controllerServiceName);
|
|
||||||
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
|
||||||
$container->setParameter($param, $crudEntry);
|
|
||||||
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
|
||||||
dump(__LINE__, $controller);
|
|
||||||
$controller->setDefinition($controllerServiceName, $controller);
|
|
||||||
} else {
|
|
||||||
$controllerServiceName = 'cs'.$apiOrCrud.'_'.$crudEntry['name'].'_controller';
|
|
||||||
$controller = new Definition($controllerClass);
|
|
||||||
$controller->addTag('controller.service_arguments');
|
|
||||||
$controller->setAutoconfigured(true);
|
|
||||||
$controller->setClass($controllerClass);
|
|
||||||
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
|
||||||
$container->setParameter($param, $crudEntry);
|
|
||||||
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
|
||||||
dump(__LINE__, $controller);
|
|
||||||
$container->setDefinition($controllerServiceName, $controller);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,103 +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\DependencyInjection\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, 'crud');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
{
|
|
||||||
$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_'.$apiOrCrud.'_config_'.$name, $crudEntry);
|
|
||||||
$container->getDefinition($controllerServiceName)
|
|
||||||
->addMethodCall('setCrudConfig', ['%chill_main_'.$apiOrCrud.'_config_'.$name.'%']);
|
|
||||||
/*
|
|
||||||
dump($controllerClass);
|
|
||||||
*/
|
|
||||||
|
|
||||||
$controllerClass = $crudEntry['controller'];
|
|
||||||
dump('in_array', $controllerClass, \in_array($controllerClass, \array_keys($container->getDefinitions())));
|
|
||||||
|
|
||||||
if ($container->hasDefinition($controllerClass)) {
|
|
||||||
dump('container has controller class');
|
|
||||||
$controllerServiceName = $controllerClass;
|
|
||||||
$controller = $container->getDefinition($controllerServiceName);
|
|
||||||
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
|
||||||
$container->setParameter($param, $crudEntry);
|
|
||||||
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
|
||||||
dump(__LINE__, $controller);
|
|
||||||
$controller->setDefinition($controllerServiceName, $controller);
|
|
||||||
} else {
|
|
||||||
$controllerServiceName = 'cs'.$apiOrCrud.'_'.$crudEntry['name'].'_controller';
|
|
||||||
$controller = new Definition($controllerClass);
|
|
||||||
$controller->addTag('controller.service_arguments');
|
|
||||||
$controller->setAutoconfigured(true);
|
|
||||||
$controller->setClass($controllerClass);
|
|
||||||
$param = 'chill_main_'.$apiOrCrud.'_config_'.$crudEntry['name'];
|
|
||||||
$container->setParameter($param, $crudEntry);
|
|
||||||
$controller->addMethodCall('setCrudConfig', ['%'.$param.'%']);
|
|
||||||
dump(__LINE__, $controller);
|
|
||||||
$container->setDefinition($controllerServiceName, $controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,33 +8,51 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
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
|
class AccompanyingCourseApiController extends ApiController
|
||||||
{
|
{
|
||||||
public function participationApi($accompanyingPeriodId, Request $request)
|
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 */
|
/** @var AccompanyingPeriod $accompanyingPeriod */
|
||||||
$accompanyingPeriod = $this->getEntity($accompanyingPeriodId);
|
$accompanyingPeriod = $this->getEntity('participation', $id, $request);
|
||||||
$person = $this->serializer->deserialize($request->getContent(), Person::class, $_format, []);
|
$person = $this->getSerializer()
|
||||||
|
->deserialize($request->getContent(), Person::class, $_format, []);
|
||||||
|
|
||||||
if (NULL === $person) {
|
if (NULL === $person) {
|
||||||
throw new BadRequestException('person id not found');
|
throw new BadRequestException('person id not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO add acl
|
// TODO add acl
|
||||||
|
//
|
||||||
|
$this->onPostCheckACL('participation', $request, $accompanyingPeriod, $_format);
|
||||||
|
|
||||||
switch ($request->getMethod()) {
|
switch ($request->getMethod()) {
|
||||||
case Request::METHOD_POST:
|
case Request::METHOD_POST:
|
||||||
$participation = $accompanyingCours->addPerson($person);
|
$participation = $accompanyingPeriod->addPerson($person);
|
||||||
break;
|
break;
|
||||||
case Request::METHOD_DELETE:
|
case Request::METHOD_DELETE:
|
||||||
$participation = $accompanyingCours->removePerson($person);
|
$participation = $accompanyingPeriod->removePerson($person);
|
||||||
|
$participation->setEndDate(new \DateTimeImmutable('now'));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new BadRequestException("This method is not supported");
|
throw new BadRequestException("This method is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
$errors = $this->validator->validate($accompanyingCourse);
|
$errors = $this->validator->validate($accompanyingPeriod);
|
||||||
|
|
||||||
if ($errors->count() > 0) {
|
if ($errors->count() > 0) {
|
||||||
// only format accepted
|
// only format accepted
|
||||||
@ -45,4 +63,17 @@ class AccompanyingCourseApiController extends ApiController
|
|||||||
|
|
||||||
return $this->json($participation);
|
return $this->json($participation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function onPostCheckACL(string $action, Request $request, $entity, $_format): ?Response
|
||||||
|
{
|
||||||
|
$this->eventDispatcher->dispatch(
|
||||||
|
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
|
||||||
|
new AccompanyingPeriodPrivacyEvent($entity, [
|
||||||
|
'action' => $action,
|
||||||
|
'request' => $request->getMethod()
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ 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,
|
||||||
@ -44,6 +45,7 @@ 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()) {
|
||||||
@ -51,6 +53,12 @@ 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);
|
||||||
|
@ -315,7 +315,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
[
|
[
|
||||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
|
||||||
'name' => 'accompanying_course',
|
'name' => 'accompanying_course',
|
||||||
'base_path' => '/api/1.0/accompanying_course',
|
'base_path' => '/api/1.0/person/accompanying-course',
|
||||||
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
|
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
|
||||||
'actions' => [
|
'actions' => [
|
||||||
'_entity' => [
|
'_entity' => [
|
||||||
@ -323,7 +323,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'/participation' => [
|
'participation' => [
|
||||||
'methods' => [
|
'methods' => [
|
||||||
Request::METHOD_POST => true,
|
Request::METHOD_POST => true,
|
||||||
Request::METHOD_DELETE => true,
|
Request::METHOD_DELETE => true,
|
||||||
|
@ -118,7 +118,7 @@ class AccompanyingPeriod
|
|||||||
*
|
*
|
||||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
||||||
* mappedBy="accompanyingPeriod",
|
* mappedBy="accompanyingPeriod",
|
||||||
* cascade={"persist", "remove", "merge", "detach"})
|
* cascade={"persist", "refresh", "remove", "merge", "detach"})
|
||||||
*/
|
*/
|
||||||
private $participations;
|
private $participations;
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ class AccompanyingPeriod
|
|||||||
*/
|
*/
|
||||||
public function getParticipationsContainsPerson(Person $person): Collection
|
public function getParticipationsContainsPerson(Person $person): Collection
|
||||||
{
|
{
|
||||||
return $this->getParticipations()->filter(
|
return $this->getParticipations($person)->filter(
|
||||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
||||||
if ($person === $participation->getPerson()) {
|
if ($person === $participation->getPerson()) {
|
||||||
return $participation;
|
return $participation;
|
||||||
@ -361,11 +361,11 @@ class AccompanyingPeriod
|
|||||||
*
|
*
|
||||||
* "Open" means that the closed date is NULL
|
* "Open" means that the closed date is NULL
|
||||||
*/
|
*/
|
||||||
public function getOpenParticipationsContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
public function getOpenParticipationContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
||||||
{
|
{
|
||||||
$collection = $this->getParticipationsContainsPerson()->filter(
|
$collection = $this->getParticipationsContainsPerson($person)->filter(
|
||||||
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
function(AccompanyingPeriodParticipation $participation) use ($person) {
|
||||||
if (NULL === $participation->getClosingDate()) {
|
if (NULL === $participation->getEndDate()) {
|
||||||
return $participation;
|
return $participation;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -380,7 +380,7 @@ class AccompanyingPeriod
|
|||||||
*/
|
*/
|
||||||
public function containsPerson(Person $person): bool
|
public function containsPerson(Person $person): bool
|
||||||
{
|
{
|
||||||
return $this->participationsContainsPerson($person)->count() > 0;
|
return $this->getParticipationsContainsPerson($person)->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,7 @@ class AccompanyingPeriodNormalizer implements NormalizerInterface, NormalizerAwa
|
|||||||
'remark' => $period->getRemark(),
|
'remark' => $period->getRemark(),
|
||||||
'participations' => $this->normalizer->normalize($period->getParticipations(), $format),
|
'participations' => $this->normalizer->normalize($period->getParticipations(), $format),
|
||||||
'closingMotive' => $this->normalizer->normalize($period->getClosingMotive(), $format),
|
'closingMotive' => $this->normalizer->normalize($period->getClosingMotive(), $format),
|
||||||
'user' => $period->getUser() ? $this->normalize($period->getUser(), $format) : null,
|
'user' => $period->getUser() ? $this->normalizer->normalize($period->getUser(), $format) : null,
|
||||||
'step' => $period->getStep(),
|
'step' => $period->getStep(),
|
||||||
'origin' => $this->normalizer->normalize($period->getOrigin(), $format),
|
'origin' => $this->normalizer->normalize($period->getOrigin(), $format),
|
||||||
'intensity' => $period->getIntensity(),
|
'intensity' => $period->getIntensity(),
|
||||||
|
@ -55,7 +55,7 @@ class PersonNormalizer implements
|
|||||||
'id' => $person->getId(),
|
'id' => $person->getId(),
|
||||||
'firstName' => $person->getFirstName(),
|
'firstName' => $person->getFirstName(),
|
||||||
'lastName' => $person->getLastName(),
|
'lastName' => $person->getLastName(),
|
||||||
'birthdate' => $person->getBirthdate(),
|
'birthdate' => $this->normalizer->normalize($person->getBirthdate()),
|
||||||
'center' => $this->normalizer->normalize($person->getCenter())
|
'center' => $this->normalizer->normalize($person->getCenter())
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
/**
|
/**
|
||||||
* Test api for AccompanyingCourseControllerTest
|
* Test api for AccompanyingCourseControllerTest
|
||||||
*/
|
*/
|
||||||
class AccompanyingCourseControllerTest extends WebTestCase
|
class AccompanyingCourseApiControllerTest extends WebTestCase
|
||||||
{
|
{
|
||||||
protected static EntityManagerInterface $em;
|
protected static EntityManagerInterface $em;
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
*/
|
*/
|
||||||
public function testAccompanyingCourseShow(int $personId, AccompanyingPeriod $period)
|
public function testAccompanyingCourseShow(int $personId, AccompanyingPeriod $period)
|
||||||
{
|
{
|
||||||
$this->client->request(Request::METHOD_GET, sprintf('/fr/person/api/1.0/accompanying-course/%d/show.json', $period->getId()));
|
$c = $this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()));
|
||||||
$response = $this->client->getResponse();
|
$response = $this->client->getResponse();
|
||||||
|
|
||||||
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||||
@ -77,6 +77,14 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
$this->assertGreaterThan(0, $data->participations);
|
$this->assertGreaterThan(0, $data->participations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testShow404()
|
||||||
|
{
|
||||||
|
$this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', 99999));
|
||||||
|
$response = $this->client->getResponse();
|
||||||
|
|
||||||
|
$this->assertEquals(404, $response->getStatusCode(), "Test that the response of rest api has a status code 'not found' (404)");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @dataProvider dataGenerateRandomAccompanyingCourse
|
* @dataProvider dataGenerateRandomAccompanyingCourse
|
||||||
@ -85,26 +93,55 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
$this->client->request(
|
$this->client->request(
|
||||||
Request::METHOD_POST,
|
Request::METHOD_POST,
|
||||||
sprintf('/fr/person/api/1.0/accompanying-course/%d/participation.json', $period->getId()),
|
sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $period->getId()),
|
||||||
[], // parameters
|
[], // parameters
|
||||||
[], // files
|
[], // files
|
||||||
[], // server parameters
|
[], // server parameters
|
||||||
\json_encode([ 'id' => $personId ])
|
\json_encode([ 'id' => $personId ])
|
||||||
);
|
);
|
||||||
$response = $this->client->getResponse();
|
$response = $this->client->getResponse();
|
||||||
|
$data = \json_decode($response->getContent(), true);
|
||||||
|
|
||||||
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||||
$this->client->request(Request::METHOD_GET, sprintf('/fr/person/api/1.0/accompanying-course/%d/show.json', $period->getId()));
|
$this->assertArrayHasKey('id', $data);
|
||||||
|
$this->assertArrayHasKey('startDate', $data);
|
||||||
|
$this->assertNotNull($data['startDate']);
|
||||||
|
|
||||||
|
// check by deownloading the accompanying cours
|
||||||
|
|
||||||
|
$this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $period->getId()));
|
||||||
|
|
||||||
$response = $this->client->getResponse();
|
$response = $this->client->getResponse();
|
||||||
$data = \json_decode($response->getContent());
|
$data = \json_decode($response->getContent());
|
||||||
|
|
||||||
|
// check that the person id is contained
|
||||||
$participationsPersonsIds = \array_map(
|
$participationsPersonsIds = \array_map(
|
||||||
function($participation) { return $participation->person->id; },
|
function($participation) { return $participation->person->id; },
|
||||||
$data->participations);
|
$data->participations);
|
||||||
|
|
||||||
$this->assertContains($personId, $participationsPersonsIds);
|
$this->assertContains($personId, $participationsPersonsIds);
|
||||||
|
|
||||||
|
// check removing the participation
|
||||||
|
$this->client->request(
|
||||||
|
Request::METHOD_DELETE,
|
||||||
|
sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $period->getId()),
|
||||||
|
[], // parameters
|
||||||
|
[], // files
|
||||||
|
[], // server parameters
|
||||||
|
\json_encode([ 'id' => $personId ])
|
||||||
|
);
|
||||||
|
$response = $this->client->getResponse();
|
||||||
|
$data = \json_decode($response->getContent(), true);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response->getStatusCode(), "Test that the response of rest api has a status code ok (200)");
|
||||||
|
$this->assertArrayHasKey('id', $data);
|
||||||
|
$this->assertArrayHasKey('startDate', $data);
|
||||||
|
$this->assertNotNull($data['startDate']);
|
||||||
|
$this->assertArrayHasKey('endDate', $data);
|
||||||
|
$this->assertNotNull($data['endDate']);
|
||||||
|
|
||||||
|
|
||||||
|
// set to variable for tear down
|
||||||
$this->personId = $personId;
|
$this->personId = $personId;
|
||||||
$this->period = $period;
|
$this->period = $period;
|
||||||
}
|
}
|
||||||
@ -112,6 +149,7 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
protected function tearDown()
|
protected function tearDown()
|
||||||
{
|
{
|
||||||
// remove participation created during test 'testAccompanyingCourseAddParticipation'
|
// remove participation created during test 'testAccompanyingCourseAddParticipation'
|
||||||
|
// and if the test could not remove it
|
||||||
|
|
||||||
$testAddParticipationName = 'testAccompanyingCourseAddParticipation';
|
$testAddParticipationName = 'testAccompanyingCourseAddParticipation';
|
||||||
|
|
||||||
@ -126,9 +164,11 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
->findOneBy(['person' => $this->personId, 'accompanyingPeriod' => $this->period])
|
->findOneBy(['person' => $this->personId, 'accompanyingPeriod' => $this->period])
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if (NULL !== $participation) {
|
||||||
$em->remove($participation);
|
$em->remove($participation);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function dataGenerateRandomAccompanyingCourse()
|
public function dataGenerateRandomAccompanyingCourse()
|
||||||
{
|
{
|
||||||
@ -139,9 +179,9 @@ class AccompanyingCourseControllerTest extends WebTestCase
|
|||||||
// * one for getting the person, which will in turn provide his accompanying period;
|
// * one for getting the person, which will in turn provide his accompanying period;
|
||||||
// * one for getting the personId to populate to the data manager
|
// * one for getting the personId to populate to the data manager
|
||||||
//
|
//
|
||||||
// Ensure to keep always $maxGenerated to the double of $maxResults
|
// Ensure to keep always $maxGenerated to the double of $maxResults. x8 is a good compromize :)
|
||||||
$maxGenerated = 1;
|
$maxGenerated = 3;
|
||||||
$maxResults = 15 * 8;
|
$maxResults = $maxGenerated * 8;
|
||||||
|
|
||||||
static::bootKernel();
|
static::bootKernel();
|
||||||
$em = static::$container->get(EntityManagerInterface::class);
|
$em = static::$container->get(EntityManagerInterface::class);
|
@ -27,7 +27,6 @@ use Chill\PersonBundle\Entity\Person;
|
|||||||
|
|
||||||
class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
public function testClosingIsAfterOpeningConsistency()
|
public function testClosingIsAfterOpeningConsistency()
|
||||||
{
|
{
|
||||||
$datetime1 = new \DateTime('now');
|
$datetime1 = new \DateTime('now');
|
||||||
@ -77,22 +76,24 @@ class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertFalse($period->isOpen());
|
$this->assertFalse($period->isOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCanBeReOpened()
|
public function testPersonPeriod()
|
||||||
{
|
{
|
||||||
$person = new Person(\DateTime::createFromFormat('Y-m-d', '2010-01-01'));
|
$person = new Person();
|
||||||
$person->close($person->getAccompanyingPeriods()[0]
|
$period = new AccompanyingPeriod(new \DateTime());
|
||||||
->setClosingDate(\DateTime::createFromFormat('Y-m-d', '2010-12-31')));
|
|
||||||
|
|
||||||
$firstAccompanygingPeriod = $person->getAccompanyingPeriodsOrdered()[0];
|
$period->addPerson($person);
|
||||||
|
|
||||||
$this->assertTrue($firstAccompanygingPeriod->canBeReOpened());
|
$this->assertEquals(1, $period->getParticipations()->count());
|
||||||
|
$this->assertTrue($period->containsPerson($person));
|
||||||
|
|
||||||
$lastAccompanyingPeriod = (new AccompanyingPeriod(\DateTime::createFromFormat('Y-m-d', '2011-01-01')))
|
$participation = $period->getOpenParticipationContainsPerson($person);
|
||||||
->setClosingDate(\DateTime::createFromFormat('Y-m-d', '2011-12-31'))
|
$participations = $period->getParticipationsContainsPerson($person);
|
||||||
;
|
$this->assertNotNull($participation);
|
||||||
$person->addAccompanyingPeriod($lastAccompanyingPeriod);
|
$this->assertEquals(1, $participations->count());
|
||||||
|
|
||||||
$this->assertFalse($firstAccompanygingPeriod->canBeReOpened());
|
$period->removePerson($person);
|
||||||
|
|
||||||
|
$participation = $period->getOpenParticipationContainsPerson($person);
|
||||||
|
$this->assertNull($participation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,3 +45,9 @@ services:
|
|||||||
$dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
|
$dispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
|
||||||
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
|
Chill\PersonBundle\Controller\AccompanyingCourseApiController:
|
||||||
|
arguments:
|
||||||
|
$eventDispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
|
||||||
|
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
|
||||||
|
tags: ['controller.service_arguments']
|
||||||
|
Loading…
x
Reference in New Issue
Block a user