mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 22:53:49 +00:00
Merge branch '111_exports_suite' into calendar/finalization
This commit is contained in:
@@ -22,6 +22,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
@@ -191,18 +192,12 @@ class ExportController extends AbstractController
|
||||
case 'export':
|
||||
return $this->exportFormStep($request, $export, $alias);
|
||||
|
||||
break;
|
||||
|
||||
case 'formatter':
|
||||
return $this->formatterFormStep($request, $export, $alias);
|
||||
|
||||
break;
|
||||
|
||||
case 'generate':
|
||||
return $this->forwardToGenerate($request, $export, $alias);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw $this->createNotFoundException("The given step '{$step}' is invalid");
|
||||
}
|
||||
@@ -214,10 +209,8 @@ class ExportController extends AbstractController
|
||||
* @param string $alias
|
||||
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
|
||||
* @param mixed $step
|
||||
*
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
protected function createCreateFormExport($alias, $step, $data = [])
|
||||
protected function createCreateFormExport($alias, $step, $data = []): FormInterface
|
||||
{
|
||||
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
|
||||
$exportManager = $this->exportManager;
|
||||
@@ -475,8 +468,6 @@ class ExportController extends AbstractController
|
||||
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
|
||||
* @param string $alias
|
||||
*
|
||||
* @throws type
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
protected function selectCentersStep(Request $request, $export, $alias)
|
||||
@@ -543,6 +534,8 @@ class ExportController extends AbstractController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -22,6 +22,7 @@ use Chill\MainBundle\Controller\UserController;
|
||||
use Chill\MainBundle\Controller\UserJobApiController;
|
||||
use Chill\MainBundle\Controller\UserJobController;
|
||||
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
||||
use Chill\MainBundle\Doctrine\DQL\Age;
|
||||
use Chill\MainBundle\Doctrine\DQL\Extract;
|
||||
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
||||
@@ -248,6 +249,7 @@ class ChillMainExtension extends Extension implements
|
||||
'datetime_functions' => [
|
||||
'EXTRACT' => Extract::class,
|
||||
'TO_CHAR' => ToChar::class,
|
||||
'AGE' => Age::class,
|
||||
],
|
||||
],
|
||||
'hydrators' => [
|
||||
|
@@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\DependencyInjection\CompilerPass;
|
||||
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
use LogicException;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@@ -30,53 +31,19 @@ class ExportsCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->has('Chill\MainBundle\Export\ExportManager')) {
|
||||
throw new LogicException('service Chill\MainBundle\Export\ExportManager '
|
||||
if (!$container->has(ExportManager::class)) {
|
||||
throw new LogicException('service ' . ExportManager::class . ' '
|
||||
. 'is not defined. It is required by ExportsCompilerPass');
|
||||
}
|
||||
|
||||
$chillManagerDefinition = $container->findDefinition(
|
||||
'Chill\MainBundle\Export\ExportManager'
|
||||
ExportManager::class
|
||||
);
|
||||
|
||||
$this->compileExports($chillManagerDefinition, $container);
|
||||
$this->compileFilters($chillManagerDefinition, $container);
|
||||
$this->compileAggregators($chillManagerDefinition, $container);
|
||||
$this->compileFormatters($chillManagerDefinition, $container);
|
||||
$this->compileExportElementsProvider($chillManagerDefinition, $container);
|
||||
}
|
||||
|
||||
private function compileAggregators(
|
||||
Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container
|
||||
) {
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export_aggregator'
|
||||
);
|
||||
|
||||
$knownAliases = [];
|
||||
|
||||
foreach ($taggedServices as $id => $tagAttributes) {
|
||||
foreach ($tagAttributes as $attributes) {
|
||||
if (!isset($attributes['alias'])) {
|
||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
||||
"service '{$id}' definition");
|
||||
}
|
||||
|
||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
||||
throw new LogicException('There is already a chill.export_aggregator service with alias '
|
||||
. $attributes['alias'] . '. Choose another alias.');
|
||||
}
|
||||
$knownAliases[] = $attributes['alias'];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addAggregator',
|
||||
[new Reference($id), $attributes['alias']]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileExportElementsProvider(
|
||||
Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container
|
||||
@@ -108,68 +75,6 @@ class ExportsCompilerPass implements CompilerPassInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function compileExports(
|
||||
Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container
|
||||
) {
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export'
|
||||
);
|
||||
|
||||
$knownAliases = [];
|
||||
|
||||
foreach ($taggedServices as $id => $tagAttributes) {
|
||||
foreach ($tagAttributes as $attributes) {
|
||||
if (!isset($attributes['alias'])) {
|
||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
||||
"service '{$id}' definition");
|
||||
}
|
||||
|
||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
||||
throw new LogicException('There is already a chill.export service with alias '
|
||||
. $attributes['alias'] . '. Choose another alias.');
|
||||
}
|
||||
$knownAliases[] = $attributes['alias'];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addExport',
|
||||
[new Reference($id), $attributes['alias']]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileFilters(
|
||||
Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container
|
||||
) {
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export_filter'
|
||||
);
|
||||
|
||||
$knownAliases = [];
|
||||
|
||||
foreach ($taggedServices as $id => $tagAttributes) {
|
||||
foreach ($tagAttributes as $attributes) {
|
||||
if (!isset($attributes['alias'])) {
|
||||
throw new LogicException("the 'alias' attribute is missing in your " .
|
||||
"service '{$id}' definition");
|
||||
}
|
||||
|
||||
if (array_search($attributes['alias'], $knownAliases, true)) {
|
||||
throw new LogicException('There is already a chill.export_filter service with alias '
|
||||
. $attributes['alias'] . '. Choose another alias.');
|
||||
}
|
||||
$knownAliases[] = $attributes['alias'];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addFilter',
|
||||
[new Reference($id), $attributes['alias']]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileFormatters(
|
||||
Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container
|
||||
|
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Age.php
Normal file
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Age.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
class Age extends FunctionNode
|
||||
{
|
||||
private $value1;
|
||||
|
||||
private $value2;
|
||||
|
||||
public function getSql(SqlWalker $sqlWalker)
|
||||
{
|
||||
if (null !== $this->value2) {
|
||||
return sprintf(
|
||||
'AGE(%s, %s)',
|
||||
$this->value1->dispatch($sqlWalker),
|
||||
$this->value2->dispatch($sqlWalker)
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'AGE(%s)',
|
||||
$this->value1->dispatch($sqlWalker),
|
||||
);
|
||||
}
|
||||
|
||||
public function parse(Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
$this->value1 = $parser->SimpleArithmeticExpression();
|
||||
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
|
||||
$this->value2 = $parser->SimpleArithmeticExpression();
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
}
|
@@ -27,7 +27,7 @@ class JsonbExistsInArray extends FunctionNode
|
||||
return sprintf(
|
||||
'%s ?? %s',
|
||||
$this->expr1->dispatch($sqlWalker),
|
||||
$sqlWalker->walkInputParameter($this->expr2)
|
||||
$this->expr2->dispatch($sqlWalker)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,7 @@ use Doctrine\DBAL\Types\ConversionException;
|
||||
use Doctrine\DBAL\Types\DateIntervalType;
|
||||
use Exception;
|
||||
|
||||
use LogicException;
|
||||
use function count;
|
||||
use function current;
|
||||
use function preg_match;
|
||||
@@ -40,7 +41,7 @@ class NativeDateIntervalType extends DateIntervalType
|
||||
return $value->format(self::FORMAT);
|
||||
}
|
||||
|
||||
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
|
||||
throw ConversionException::conversionFailedInvalidType($value, 'string', ['null', 'DateInterval']);
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
@@ -80,7 +81,7 @@ class NativeDateIntervalType extends DateIntervalType
|
||||
|
||||
protected function createConversionException($value, $exception = null)
|
||||
{
|
||||
return ConversionException::conversionFailedFormat($value, $this->getName(), 'xx year xx mons xx days 01:02:03', $exception);
|
||||
return ConversionException::conversionFailedFormat($value, 'string', 'xx year xx mons xx days 01:02:03', $exception);
|
||||
}
|
||||
|
||||
private function convertEntry(&$strings)
|
||||
@@ -125,5 +126,7 @@ class NativeDateIntervalType extends DateIntervalType
|
||||
|
||||
return $intervalSpec;
|
||||
}
|
||||
|
||||
throw new LogicException();
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,11 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
||||
*/
|
||||
class Scope
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(type="boolean", nullable=false, options={"default": true})
|
||||
*/
|
||||
private bool $active = true;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
@@ -88,6 +93,18 @@ class Scope
|
||||
return $this->roleScopes;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): Scope
|
||||
{
|
||||
$this->active = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
|
@@ -11,28 +11,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Export;
|
||||
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
interface DirectExportInterface extends ExportElementInterface
|
||||
{
|
||||
/**
|
||||
* Generate the export.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function generate(array $acl, array $data = []);
|
||||
public function generate(array $acl, array $data = []): Response;
|
||||
|
||||
/**
|
||||
* get a description, which will be used in UI (and translated).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
public function getDescription(): string;
|
||||
|
||||
/**
|
||||
* authorized role.
|
||||
*
|
||||
* @return \Symfony\Component\Security\Core\Role\Role
|
||||
*/
|
||||
public function requiredRole();
|
||||
public function requiredRole(): string;
|
||||
}
|
||||
|
@@ -14,10 +14,8 @@ namespace Chill\MainBundle\Export;
|
||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
||||
use Chill\MainBundle\Form\Type\Export\PickCenterType;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Generator;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
@@ -50,8 +48,6 @@ class ExportManager
|
||||
|
||||
private AuthorizationHelperInterface $authorizationHelper;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
/**
|
||||
* Collected Exports, injected by DI.
|
||||
*
|
||||
@@ -82,16 +78,28 @@ class ExportManager
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
EntityManagerInterface $em,
|
||||
AuthorizationCheckerInterface $authorizationChecker,
|
||||
AuthorizationHelperInterface $authorizationHelper,
|
||||
TokenStorageInterface $tokenStorage
|
||||
TokenStorageInterface $tokenStorage,
|
||||
iterable $exports,
|
||||
iterable $aggregators,
|
||||
iterable $filters
|
||||
//iterable $formatters,
|
||||
//iterable $exportElementProvider
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->em = $em;
|
||||
$this->authorizationChecker = $authorizationChecker;
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->user = $tokenStorage->getToken()->getUser();
|
||||
$this->exports = iterator_to_array($exports);
|
||||
$this->aggregators = iterator_to_array($aggregators);
|
||||
$this->filters = iterator_to_array($filters);
|
||||
// NOTE: PHP crashes on the next line (exit error code 11). This is desactivated until further investigation
|
||||
//$this->formatters = iterator_to_array($formatters);
|
||||
|
||||
//foreach ($exportElementProvider as $prefix => $provider) {
|
||||
// $this->addExportElementsProvider($provider, $prefix);
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,52 +149,17 @@ class ExportManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add an aggregator.
|
||||
*
|
||||
* @internal used by DI
|
||||
*
|
||||
* @param string $alias
|
||||
*/
|
||||
public function addAggregator(AggregatorInterface $aggregator, $alias)
|
||||
{
|
||||
$this->aggregators[$alias] = $aggregator;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an export.
|
||||
*
|
||||
* @internal used by DI
|
||||
*
|
||||
* @param DirectExportInterface|ExportInterface $export
|
||||
* @param type $alias
|
||||
*/
|
||||
public function addExport($export, $alias)
|
||||
{
|
||||
if ($export instanceof ExportInterface || $export instanceof DirectExportInterface) {
|
||||
$this->exports[$alias] = $export;
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The export with alias %s '
|
||||
. 'does not implements %s or %s.',
|
||||
$alias,
|
||||
ExportInterface::class,
|
||||
DirectExportInterface::class
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function addExportElementsProvider(ExportElementsProviderInterface $provider, $prefix)
|
||||
{
|
||||
foreach ($provider->getExportElements() as $suffix => $element) {
|
||||
$alias = $prefix . '_' . $suffix;
|
||||
|
||||
if ($element instanceof ExportInterface) {
|
||||
$this->addExport($element, $alias);
|
||||
$this->exports[$alias] = $element;
|
||||
} elseif ($element instanceof FilterInterface) {
|
||||
$this->addFilter($element, $alias);
|
||||
$this->filters[$alias] = $element;
|
||||
} elseif ($element instanceof AggregatorInterface) {
|
||||
$this->addAggregator($element, $alias);
|
||||
$this->aggregators[$alias] = $element;
|
||||
} elseif ($element instanceof FormatterInterface) {
|
||||
$this->addFormatter($element, $alias);
|
||||
} else {
|
||||
@@ -196,24 +169,12 @@ class ExportManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add a Filter.
|
||||
*
|
||||
* @internal Normally used by the dependency injection
|
||||
*
|
||||
* @param string $alias
|
||||
*/
|
||||
public function addFilter(FilterInterface $filter, $alias)
|
||||
{
|
||||
$this->filters[$alias] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a formatter.
|
||||
*
|
||||
* @internal used by DI
|
||||
*
|
||||
* @param type $alias
|
||||
* @param string $alias
|
||||
*/
|
||||
public function addFormatter(FormatterInterface $formatter, $alias)
|
||||
{
|
||||
@@ -231,7 +192,6 @@ class ExportManager
|
||||
public function generate($exportAlias, array $pickedCentersData, array $data, array $formatterData)
|
||||
{
|
||||
$export = $this->getExport($exportAlias);
|
||||
//$qb = $this->em->createQueryBuilder();
|
||||
$centers = $this->getPickedCenters($pickedCentersData);
|
||||
|
||||
if ($export instanceof DirectExportInterface) {
|
||||
|
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\LocationType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class PickLocationTypeType extends AbstractType
|
||||
{
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||
{
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'class' => LocationType::class,
|
||||
'choice_label' => function (LocationType $type) {
|
||||
return $this->translatableStringHelper->localize($type->getTitle());
|
||||
},
|
||||
'placeholder' => 'Pick a location type',
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'label' => 'Location type',
|
||||
'multiple' => false,
|
||||
])
|
||||
->setAllowedTypes('multiple', ['bool']);
|
||||
}
|
||||
|
||||
public function getParent(): string
|
||||
{
|
||||
return EntityType::class;
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Repository\LocationRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class PickUserLocationType extends AbstractType
|
||||
{
|
||||
private LocationRepository $locationRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
|
||||
{
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->locationRepository = $locationRepository;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'class' => Location::class,
|
||||
'choices' => $this->locationRepository->findByPublicLocations(),
|
||||
'choice_label' => function (Location $entity) {
|
||||
return $entity->getName() ?
|
||||
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
|
||||
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
|
||||
},
|
||||
'placeholder' => 'Pick a location',
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'label' => 'Current location',
|
||||
'multiple' => false,
|
||||
])
|
||||
->setAllowedTypes('multiple', ['bool']);
|
||||
}
|
||||
|
||||
public function getParent(): string
|
||||
{
|
||||
return EntityType::class;
|
||||
}
|
||||
}
|
@@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
|
||||
use Chill\MainBundle\Repository\ScopeRepository;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use RuntimeException;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
@@ -26,11 +26,9 @@ use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
use function array_map;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
@@ -44,47 +42,37 @@ use function count;
|
||||
*/
|
||||
class ScopePickerType extends AbstractType
|
||||
{
|
||||
protected AuthorizationHelperInterface $authorizationHelper;
|
||||
private AuthorizationHelperInterface $authorizationHelper;
|
||||
|
||||
/**
|
||||
* @var ScopeRepository
|
||||
*/
|
||||
protected $scopeRepository;
|
||||
private Security $security;
|
||||
|
||||
protected Security $security;
|
||||
|
||||
/**
|
||||
* @var TokenStorageInterface
|
||||
*/
|
||||
protected $tokenStorage;
|
||||
|
||||
/**
|
||||
* @var TranslatableStringHelper
|
||||
*/
|
||||
protected $translatableStringHelper;
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationHelperInterface $authorizationHelper,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
ScopeRepository $scopeRepository,
|
||||
Security $security,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
TranslatableStringHelperInterface $translatableStringHelper
|
||||
) {
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
$this->scopeRepository = $scopeRepository;
|
||||
$this->security = $security;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$items = $this->authorizationHelper->getReachableScopes(
|
||||
$this->security->getUser(),
|
||||
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
|
||||
$options['center']
|
||||
$items = array_filter(
|
||||
$this->authorizationHelper->getReachableScopes(
|
||||
$this->security->getUser(),
|
||||
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
|
||||
$options['center']
|
||||
),
|
||||
static function (Scope $s) { return $s->isActive(); }
|
||||
);
|
||||
|
||||
if (0 === count($items)) {
|
||||
throw new RuntimeException('no scopes are reachable. This form should not be shown to user');
|
||||
}
|
||||
|
||||
if (1 !== count($items)) {
|
||||
$builder->add('scope', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
@@ -123,35 +111,4 @@ class ScopePickerType extends AbstractType
|
||||
->setRequired('role')
|
||||
->setAllowedTypes('role', ['string', Role::class]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|Center|Center[] $center
|
||||
* @param string $role
|
||||
*
|
||||
* @return \Doctrine\ORM\QueryBuilder
|
||||
*/
|
||||
protected function buildAccessibleScopeQuery($center, $role)
|
||||
{
|
||||
$roles = $this->authorizationHelper->getParentRoles($role);
|
||||
$roles[] = $role;
|
||||
$centers = $center instanceof Center ? [$center] : $center;
|
||||
|
||||
$qb = $this->scopeRepository->createQueryBuilder('s');
|
||||
$qb
|
||||
// jointure to center
|
||||
->join('s.roleScopes', 'rs')
|
||||
->join('rs.permissionsGroups', 'pg')
|
||||
->join('pg.groupCenters', 'gc')
|
||||
// add center constraint
|
||||
->where($qb->expr()->in('IDENTITY(gc.center)', ':centers'))
|
||||
->setParameter('centers', array_map(static fn (Center $c) => $c->getId(), $centers))
|
||||
// role constraints
|
||||
->andWhere($qb->expr()->in('rs.role', ':roles'))
|
||||
->setParameter('roles', $roles)
|
||||
// user contraint
|
||||
->andWhere(':user MEMBER OF gc.users')
|
||||
->setParameter('user', $this->tokenStorage->getToken()->getUser());
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
|
@@ -11,39 +11,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Form;
|
||||
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Repository\LocationRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserCurrentLocationType extends AbstractType
|
||||
{
|
||||
private LocationRepository $locationRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
|
||||
{
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->locationRepository = $locationRepository;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('currentLocation', EntityType::class, [
|
||||
'class' => Location::class,
|
||||
'choices' => $this->locationRepository->findByPublicLocations(),
|
||||
'choice_label' => function (Location $entity) {
|
||||
return $entity->getName() ?
|
||||
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
|
||||
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
|
||||
},
|
||||
'placeholder' => 'Pick a location',
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
]);
|
||||
$builder->add('currentLocation', PickUserLocationType::class);
|
||||
}
|
||||
}
|
||||
|
@@ -43,6 +43,15 @@ final class ScopeRepository implements ScopeRepositoryInterface
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
public function findAllActive(): array
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('s');
|
||||
|
||||
$qb->where('s.active = \'TRUE\'');
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
|
@@ -22,10 +22,15 @@ interface ScopeRepositoryInterface extends ObjectRepository
|
||||
public function find($id, $lockMode = null, $lockVersion = null): ?Scope;
|
||||
|
||||
/**
|
||||
* @return Scope[]
|
||||
* @return array|Scope[]
|
||||
*/
|
||||
public function findAll(): array;
|
||||
|
||||
/**
|
||||
* @return array|Scope[]
|
||||
*/
|
||||
public function findAllActive(): array;
|
||||
|
||||
/**
|
||||
* @param null|mixed $limit
|
||||
* @param null|mixed $offset
|
||||
|
@@ -14,9 +14,8 @@ namespace Chill\MainBundle\Repository;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
class UserJobRepository implements ObjectRepository
|
||||
class UserJobRepository implements UserJobRepositoryInterface
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
@@ -38,6 +37,11 @@ class UserJobRepository implements ObjectRepository
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
public function findAllActive(): array
|
||||
{
|
||||
return $this->repository->findBy(['active' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
@@ -49,12 +53,12 @@ class UserJobRepository implements ObjectRepository
|
||||
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria)
|
||||
public function findOneBy(array $criteria): ?UserJob
|
||||
{
|
||||
return $this->repository->findOneBy($criteria);
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
public function getClassName(): string
|
||||
{
|
||||
return UserJob::class;
|
||||
}
|
||||
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Repository;
|
||||
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
interface UserJobRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
public function find($id): ?UserJob;
|
||||
|
||||
/**
|
||||
* @return array|UserJob[]
|
||||
*/
|
||||
public function findAll(): array;
|
||||
|
||||
/**
|
||||
* @return array|UserJob[]
|
||||
*/
|
||||
public function findAllActive(): array;
|
||||
|
||||
/**
|
||||
* @param mixed|null $limit
|
||||
* @param mixed|null $offset
|
||||
*
|
||||
* @return array|object[]|UserJob[]
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);
|
||||
|
||||
public function findOneBy(array $criteria): ?UserJob;
|
||||
|
||||
public function getClassName(): string;
|
||||
}
|
@@ -1,12 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers.
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
|
@@ -119,7 +119,3 @@ document.addEventListener('DOMContentLoaded', function(e) {
|
||||
loadDynamicPicker(document)
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -20,7 +20,12 @@
|
||||
|
||||
{% block title %}{{ export.title|trans }}{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{{ encore_entry_script_tags('page_export') }}
|
||||
{% if export_alias == 'count_social_work_actions' %}
|
||||
{{ encore_entry_script_tags('vue_export_action_goal_result') }}
|
||||
|
@@ -29,6 +29,18 @@ use function is_string;
|
||||
*/
|
||||
abstract class AbstractAggregatorTest extends KernelTestCase
|
||||
{
|
||||
/**
|
||||
* provide data for `testAliasDidNotDisappears`.
|
||||
*/
|
||||
public function dataProviderAliasDidNotDisappears()
|
||||
{
|
||||
foreach ($this->getQueryBuilders() as $qb) {
|
||||
foreach ($this->getFormData() as $data) {
|
||||
yield [clone $qb, $data];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* provide data for `testAlterQuery`.
|
||||
*/
|
||||
@@ -95,6 +107,28 @@ abstract class AbstractAggregatorTest extends KernelTestCase
|
||||
*/
|
||||
abstract public function getQueryBuilders();
|
||||
|
||||
/**
|
||||
* Compare aliases array before and after that aggregator alter query.
|
||||
*
|
||||
* @dataProvider dataProviderAliasDidNotDisappears
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAliasDidNotDisappears(QueryBuilder $qb, array $data)
|
||||
{
|
||||
$aliases = $qb->getAllAliases();
|
||||
|
||||
$this->getAggregator()->alterQuery($qb, $data);
|
||||
|
||||
$alteredQuery = $qb->getAllAliases();
|
||||
|
||||
$this->assertGreaterThanOrEqual(count($aliases), count($alteredQuery));
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$this->assertContains($alias, $alteredQuery);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test the alteration of query by the filter.
|
||||
*
|
||||
|
@@ -40,6 +40,18 @@ abstract class AbstractFilterTest extends KernelTestCase
|
||||
$this->prophet = $this->getProphet();
|
||||
}
|
||||
|
||||
/**
|
||||
* provide data for `testAliasDidNotDisappears`.
|
||||
*/
|
||||
public function dataProviderAliasDidNotDisappears()
|
||||
{
|
||||
foreach ($this->getQueryBuilders() as $qb) {
|
||||
foreach ($this->getFormData() as $data) {
|
||||
yield [clone $qb, $data];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function dataProviderAlterQuery()
|
||||
{
|
||||
foreach ($this->getQueryBuilders() as $qb) {
|
||||
@@ -87,6 +99,28 @@ abstract class AbstractFilterTest extends KernelTestCase
|
||||
*/
|
||||
abstract public function getQueryBuilders();
|
||||
|
||||
/**
|
||||
* Compare aliases array before and after that filter alter query.
|
||||
*
|
||||
* @dataProvider dataProviderAliasDidNotDisappears
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAliasDidNotDisappears(QueryBuilder $qb, array $data)
|
||||
{
|
||||
$aliases = $qb->getAllAliases();
|
||||
|
||||
$this->getFilter()->alterQuery($qb, $data);
|
||||
|
||||
$alteredQuery = $qb->getAllAliases();
|
||||
|
||||
$this->assertGreaterThanOrEqual(count($aliases), count($alteredQuery));
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$this->assertContains($alias, $alteredQuery);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test the alteration of query by the filter.
|
||||
*
|
||||
|
79
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/AgeTest.php
Normal file
79
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/AgeTest.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Doctrine\DQL;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class AgeTest extends KernelTestCase
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
public function generateQueries(): iterable
|
||||
{
|
||||
yield [
|
||||
'SELECT AGE(a.validFrom, a.validTo) FROM ' . Address::class . ' a',
|
||||
[],
|
||||
];
|
||||
|
||||
yield [
|
||||
'SELECT AGE(:date0, :date1) FROM ' . Address::class . ' a',
|
||||
[
|
||||
'date0' => new DateTimeImmutable('now'),
|
||||
'date1' => new DateTimeImmutable('2020-01-01'),
|
||||
],
|
||||
];
|
||||
|
||||
yield [
|
||||
'SELECT AGE(a.validFrom, :date1) FROM ' . Address::class . ' a',
|
||||
[
|
||||
'date1' => new DateTimeImmutable('now'),
|
||||
],
|
||||
];
|
||||
|
||||
yield [
|
||||
'SELECT AGE(:date0, a.validFrom) FROM ' . Address::class . ' a',
|
||||
[
|
||||
'date0' => new DateTimeImmutable('now'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider generateQueries
|
||||
*/
|
||||
public function testWorking(string $dql, array $args)
|
||||
{
|
||||
$dql = $this->entityManager->createQuery($dql)->setMaxResults(3);
|
||||
|
||||
foreach ($args as $key => $value) {
|
||||
$dql->setParameter($key, $value);
|
||||
}
|
||||
|
||||
$results = $dql->getResult();
|
||||
|
||||
$this->assertIsArray($results);
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DQL;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class JsonbExistsInArrayTest extends KernelTestCase
|
||||
{
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
public function testDQLFunctionWorks()
|
||||
{
|
||||
$result = $this->em
|
||||
->createQuery('SELECT JSONB_EXISTS_IN_ARRAY(u.attributes, :param) FROM ' . User::class . ' u')
|
||||
->setParameter('param', 'fr')
|
||||
->getResult();
|
||||
|
||||
$this->assertIsArray($result);
|
||||
}
|
||||
}
|
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\PreloadedExtension;
|
||||
use Symfony\Component\Form\Test\TypeTestCase;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class ScopePickerTypeTest extends TypeTestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testBuildOneScopeIsSuccessful()
|
||||
{
|
||||
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||
'center' => new Center(),
|
||||
'role' => 'ONE_SCOPE',
|
||||
]);
|
||||
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertContains('hidden', $view['scope']->vars['block_prefixes']);
|
||||
}
|
||||
|
||||
public function testBuildThreeScopesIsSuccessful()
|
||||
{
|
||||
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||
'center' => new Center(),
|
||||
'role' => 'THREE_SCOPE',
|
||||
]);
|
||||
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||
}
|
||||
|
||||
public function testBuildTwoScopesIsSuccessful()
|
||||
{
|
||||
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||
'center' => new Center(),
|
||||
'role' => 'TWO_SCOPE',
|
||||
]);
|
||||
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||
}
|
||||
|
||||
protected function getExtensions()
|
||||
{
|
||||
$user = new User();
|
||||
$role1Scope = 'ONE_SCOPE';
|
||||
$role2Scope = 'TWO_SCOPE';
|
||||
$role3Scope = 'THREE_SCOPE';
|
||||
$scopeA = (new Scope())->setName(['fr' => 'scope a']);
|
||||
$scopeB = (new Scope())->setName(['fr' => 'scope b']);
|
||||
$scopeC = (new Scope())->setName(['fr' => 'scope b'])->setActive(false);
|
||||
|
||||
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class);
|
||||
$authorizationHelper->getReachableScopes($user, $role1Scope, Argument::any())
|
||||
->willReturn([$scopeA]);
|
||||
$authorizationHelper->getReachableScopes($user, $role2Scope, Argument::any())
|
||||
->willReturn([$scopeA, $scopeB]);
|
||||
$authorizationHelper->getReachableScopes($user, $role3Scope, Argument::any())
|
||||
->willReturn([$scopeA, $scopeB, $scopeC]);
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->getUser()->willReturn($user);
|
||||
|
||||
$translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||
$translatableStringHelper->localize(Argument::type('array'))->will(
|
||||
static function ($args) { return $args[0]['fr']; }
|
||||
);
|
||||
|
||||
$type = new ScopePickerType(
|
||||
$authorizationHelper->reveal(),
|
||||
$security->reveal(),
|
||||
$translatableStringHelper->reveal()
|
||||
);
|
||||
|
||||
// add the mocks for creating EntityType
|
||||
$entityManager = DoctrineTestHelper::createTestEntityManager();
|
||||
$em = $this->prophesize(EntityManagerInterface::class);
|
||||
$em->getClassMetadata(Scope::class)->willReturn($entityManager->getClassMetadata(Scope::class));
|
||||
$em->contains(Argument::type(Scope::class))->willReturn(true);
|
||||
$em->initializeObject(Argument::type(Scope::class))->will(static fn ($o) => $o);
|
||||
$emRevealed = $em->reveal();
|
||||
$managerRegistry = $this->prophesize(ManagerRegistry::class);
|
||||
$managerRegistry->getManager(Argument::any())->willReturn($emRevealed);
|
||||
$managerRegistry->getManagerForClass(Scope::class)->willReturn($emRevealed);
|
||||
|
||||
$entityType = $this->prophesize(EntityType::class);
|
||||
$entityType->getParent()->willReturn(ChoiceType::class);
|
||||
|
||||
return [
|
||||
new PreloadedExtension([$type], []),
|
||||
new DoctrineOrmExtension($managerRegistry->reveal()),
|
||||
];
|
||||
}
|
||||
}
|
@@ -91,6 +91,14 @@ services:
|
||||
Chill\MainBundle\Export\ExportManager:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
arguments:
|
||||
$exports: !tagged_iterator { tag: chill.export, index_by: alias }
|
||||
$aggregators: !tagged_iterator { tag: chill.export_aggregator, index_by: alias }
|
||||
$filters: !tagged_iterator { tag: chill.export_filter, index_by: alias }
|
||||
# for an unknown reason, iterator_to_array($formatter) cause a segmentation fault error (php-fpm code 11). removed temporarily
|
||||
# $formatters: !tagged_iterator { tag: chill.export_formatter, index_by: alias }
|
||||
# remove until we can properly test it
|
||||
# $exportElementProvider: !tagged_iterator { tag: chill.export_elements_provider, index_by: prefix }
|
||||
|
||||
Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'
|
||||
|
||||
|
@@ -122,8 +122,6 @@ services:
|
||||
|
||||
Chill\MainBundle\Form\Type\PickAddressType: ~
|
||||
|
||||
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer: ~
|
||||
|
||||
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
@@ -132,10 +130,6 @@ services:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\MainBundle\Form\UserCurrentLocationType:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\MainBundle\Form\Type\LocationFormType: ~
|
||||
|
||||
Chill\MainBundle\Form\WorkflowStepType: ~
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20221010142417 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE scopes DROP active');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Allow a scope to be desactivated';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE scopes ADD active BOOLEAN DEFAULT true NOT NULL');
|
||||
}
|
||||
}
|
@@ -189,6 +189,7 @@ Main scope: Cercle
|
||||
Main center: Centre
|
||||
user job: Métier de l'utilisateur
|
||||
Job: Métier
|
||||
Jobs: Métiers
|
||||
Choose a main center: Choisir un centre
|
||||
Choose a main scope: Choisir un cercle
|
||||
choose a job: Choisir un métier
|
||||
@@ -227,6 +228,7 @@ never: jamais
|
||||
Create a new location: Créer une nouvelle localisation
|
||||
Location list: Liste des localisations
|
||||
Location type: Type de localisation
|
||||
Pick a location type: Choisir un type de localisation
|
||||
Phonenumber1: Numéro de téléphone
|
||||
Phonenumber2: Autre numéro de téléphone
|
||||
Location configuration: Configuration des localisations
|
||||
|
Reference in New Issue
Block a user