Merge branch 'master' into 369-duplicate-evaluation-document

This commit is contained in:
2025-08-20 15:28:19 +02:00
846 changed files with 35209 additions and 38186 deletions

View File

@@ -1,64 +0,0 @@
.test_definition: &test_definition
services:
- chill/database:latest
before_script:
- composer config github-oauth.github.com $GITHUB_TOKEN
- php -d memory_limit=-1 /usr/local/bin/composer install --no-interaction
- cp Resources/test/Fixtures/App/app/config/parameters.gitlab-ci.yml Resources/test/Fixtures/App/app/config/parameters.yml
- php Resources/test/Fixtures/App/app/console doctrine:migrations:migrate --env=test --no-interaction
- php Resources/test/Fixtures/App/app/console doctrine:fixtures:load --env=test --no-interaction
stages:
- deploy
- test
- build-doc
- deploy-doc
test:php-7.2:
stage: test
image: chill/ci-image:php-7.2
<<: *test_definition
script: php vendor/bin/phpunit
deploy-packagist:
stage: deploy
image: chill/ci-image:php-7.2
before_script:
# test that PACKAGIST USERNAME and PACKAGIST_TOKEN variable are set
- if [ -z ${PACKAGIST_USERNAME+x} ]; then echo "Please set PACKAGIST_USERNAME variable"; exit -1; fi
- if [ -z ${PACKAGIST_TOKEN+x} ]; then echo "Please set PACKAGIST_TOKEN variable"; exit -1; fi
script:
- STATUSCODE=$(curl -XPOST -H'content-type:application/json' "https://packagist.org/api/update-package?username=$PACKAGIST_USERNAME&apiToken=$PACKAGIST_TOKEN" -d"{\"repository\":{\"url\":\"$CI_PROJECT_URL.git\"}}" --silent --output /dev/stderr --write-out "%{http_code}")
- if [ $STATUSCODE = "202" ]; then exit 0; else exit $STATUSCODE; fi
# deploy documentation
api-doc-build:
stage: build-doc
environment: api-doc
image: chill/ci-image:php-7.2
before_script:
- mkdir api-doc
script: apigen generate --destination api-doc/$CI_BUILD_REF_NAME/$CI_PROJECT_NAME
artifacts:
paths:
- "api-doc/"
name: api
expire_in: '2h'
only:
- master
- tags
api-doc-deploy:
stage: deploy-doc
image: pallet/swiftclient:latest
before_script:
# test that CONTAINER_API variable is set
- if [ -z ${CONTAINER_API+x} ]; then echo "Please set CONTAINER_API variable"; exit -1; fi
# go to api-doc to have and url with PROJECT/BUILD
- cd api-doc
# upload, and keep files during 1 year
script: "swift upload --header \"X-Delete-After: 31536000\" $CONTAINER_API $CI_BUILD_REF_NAME/$CI_PROJECT_NAME"
only:
- master
- tags

View File

@@ -1,31 +0,0 @@
Version 1.5.1
=============
- [report activity count] fix error: do not show centers which are not selected in results.
Version 1.5.2
=============
- [aggregate by activity type] fix translation in aggregate activity type
- fix some translation in export
- fix error when persons not loaded by other aggregators / filters
- add "filter by activity type" filter
Version 1.5.3
=============
- add privacy events to activity list / show / edit
Version 1.5.4
=============
- [report activity]: add aggregator for activity users
- fix bug: error when extracting activities without filter / aggregators selecting persons
Version 1.5.5
=============
- [activity] replace dropdown for selecting reasons and use chillEntity for reason rendering
- fix bug: error when trying to edit activity of which the type has been deactivated

View File

@@ -48,28 +48,6 @@ class ActivityReasonCategoryController extends AbstractController
]);
}
/**
* Displays a form to edit an existing ActivityReasonCategory entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/edit', name: 'chill_activity_activityreasoncategory_edit')]
public function editAction(mixed $id)
{
$em = $this->managerRegistry->getManager();
$entity = $em->getRepository(ActivityReasonCategory::class)->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
}
$editForm = $this->createEditForm($entity);
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
'entity' => $entity,
'edit_form' => $editForm->createView(),
]);
}
/**
* Lists all ActivityReasonCategory entities.
*/
@@ -100,29 +78,10 @@ class ActivityReasonCategoryController extends AbstractController
]);
}
/**
* Finds and displays a ActivityReasonCategory entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/show', name: 'chill_activity_activityreasoncategory_show')]
public function showAction(mixed $id)
{
$em = $this->managerRegistry->getManager();
$entity = $em->getRepository(ActivityReasonCategory::class)->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
}
return $this->render('@ChillActivity/ActivityReasonCategory/show.html.twig', [
'entity' => $entity,
]);
}
/**
* Edits an existing ActivityReasonCategory entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update', methods: ['POST', 'PUT'])]
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update')]
public function updateAction(Request $request, mixed $id)
{
$em = $this->managerRegistry->getManager();
@@ -139,7 +98,7 @@ class ActivityReasonCategoryController extends AbstractController
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em->flush();
return $this->redirectToRoute('chill_activity_activityreasoncategory_edit', ['id' => $id]);
return $this->redirectToRoute('chill_activity_activityreasoncategory', ['id' => $id]);
}
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
@@ -178,7 +137,7 @@ class ActivityReasonCategoryController extends AbstractController
{
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreasoncategory_update', ['id' => $entity->getId()]),
'method' => 'PUT',
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);

View File

@@ -17,7 +17,6 @@ use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* ActivityReason controller.
@@ -50,28 +49,6 @@ class ActivityReasonController extends AbstractController
]);
}
/**
* Displays a form to edit an existing ActivityReason entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/edit', name: 'chill_activity_activityreason_edit')]
public function editAction(mixed $id)
{
$em = $this->managerRegistry->getManager();
$entity = $em->getRepository(ActivityReason::class)->find($id);
if (null === $entity) {
throw new NotFoundHttpException('Unable to find ActivityReason entity.');
}
$editForm = $this->createEditForm($entity);
return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [
'entity' => $entity,
'edit_form' => $editForm->createView(),
]);
}
/**
* Lists all ActivityReason entities.
*/
@@ -102,29 +79,10 @@ class ActivityReasonController extends AbstractController
]);
}
/**
* Finds and displays a ActivityReason entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/show', name: 'chill_activity_activityreason_show')]
public function showAction(mixed $id)
{
$em = $this->managerRegistry->getManager();
$entity = $em->getRepository(ActivityReason::class)->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ActivityReason entity.');
}
return $this->render('@ChillActivity/ActivityReason/show.html.twig', [
'entity' => $entity,
]);
}
/**
* Edits an existing ActivityReason entity.
*/
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update', methods: ['POST', 'PUT'])]
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update')]
public function updateAction(Request $request, mixed $id)
{
$em = $this->managerRegistry->getManager();
@@ -180,7 +138,7 @@ class ActivityReasonController extends AbstractController
{
$form = $this->createForm(ActivityReasonType::class, $entity, [
'action' => $this->generateUrl('chill_activity_activityreason_update', ['id' => $entity->getId()]),
'method' => 'PUT',
'method' => 'POST',
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);

View File

@@ -24,7 +24,7 @@ class ByActivityNumberAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb
->addSelect('(SELECT COUNT(activity.id) FROM '.Activity::class.' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator')
@@ -41,12 +41,27 @@ class ByActivityNumberAggregator implements AggregatorInterface
// No form needed
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return static function ($value) {
if ('_header' === $value) {

View File

@@ -33,7 +33,7 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
private TranslatableStringHelperInterface $translatableStringHelper,
) {}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('after_date', PickRollingDateType::class, [
@@ -46,6 +46,21 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['after_date' => $formData['after_date']->normalize(), 'before_date' => $formData['before_date']->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['after_date' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['after_date']), 'before_date' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['before_date'])];
}
public function getFormDefaultData(): array
{
return [
@@ -54,7 +69,7 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
];
}
public function getLabels($key, array $values, mixed $data)
public function getLabels($key, array $values, mixed $data): callable
{
return function (int|string|null $value): string {
if ('_header' === $value) {
@@ -69,12 +84,12 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return [self::PREFIX.'_actype_id'];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aggregator.acp.by_activity_type.title';
}
@@ -84,7 +99,7 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -115,7 +130,7 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
->addGroupBy("{$p}_actype_id");
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}

View File

@@ -27,7 +27,7 @@ class BySocialActionAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actsocialaction', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.socialActions', 'actsocialaction');
@@ -42,17 +42,32 @@ class BySocialActionAggregator implements AggregatorInterface
return Declarations::ACTIVITY_ACP;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value) {
if ('_header' === $value) {

View File

@@ -27,7 +27,7 @@ class BySocialIssueAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actsocialissue', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.socialIssues', 'actsocialissue');
@@ -42,17 +42,32 @@ class BySocialIssueAggregator implements AggregatorInterface
return Declarations::ACTIVITY_ACP;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -25,7 +25,7 @@ final readonly class ActivityLocationAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actloc', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.location', 'actloc');
@@ -39,17 +39,32 @@ final readonly class ActivityLocationAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form required for this aggregator
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data): \Closure
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {
@@ -69,7 +84,7 @@ final readonly class ActivityLocationAggregator implements AggregatorInterface
return [self::KEY];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aggregator.activity.by_location.Title';
}

View File

@@ -22,14 +22,29 @@ final readonly class ActivityPresenceAggregator implements AggregatorInterface
{
public function __construct(private ActivityPresenceRepositoryInterface $activityPresenceRepository, private TranslatableStringHelperInterface $translatableStringHelper) {}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
public function getLabels($key, array $values, mixed $data): callable
{
return function (int|string|null $value): string {
if ('_header' === $value) {
@@ -44,7 +59,7 @@ final readonly class ActivityPresenceAggregator implements AggregatorInterface
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['activity_presence_aggregator_attendee'];
}
@@ -59,13 +74,13 @@ final readonly class ActivityPresenceAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->addSelect('IDENTITY(activity.attendee) AS activity_presence_aggregator_attendee');
$qb->addGroupBy('activity_presence_aggregator_attendee');
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}

View File

@@ -36,7 +36,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
// add select element
if ('reasons' === $data['level']) {
@@ -72,7 +72,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add(
'level',
@@ -89,6 +89,21 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['level' => $formData['level']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['level' => $formData['level']];
}
public function getFormDefaultData(): array
{
return [
@@ -96,7 +111,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value) use ($data) {
if ('_header' === $value) {
@@ -125,7 +140,7 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
// add select element
if ('reasons' === $data['level']) {
@@ -139,12 +154,12 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
throw new \RuntimeException('The data provided are not recognised.');
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Aggregate by activity reason';
}
public function validateForm($data, ExecutionContextInterface $context)
public function validateForm($data, ExecutionContextInterface $context): void
{
if (null === $data['level']) {
$context

View File

@@ -29,7 +29,7 @@ class ActivityTypeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('acttype', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.activityType', 'acttype');
@@ -44,17 +44,32 @@ class ActivityTypeAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form required for this aggregator
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data): \Closure
public function getLabels($key, array $values, $data): callable
{
return function (int|string|null $value): string {
if ('_header' === $value) {
@@ -74,7 +89,7 @@ class ActivityTypeAggregator implements AggregatorInterface
return [self::KEY];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Aggregate by activity type';
}

View File

@@ -29,7 +29,7 @@ class ActivityUserAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
// add select element
$qb->addSelect(sprintf('IDENTITY(activity.user) AS %s', self::KEY));
@@ -43,17 +43,32 @@ class ActivityUserAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// nothing to add
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, $values, $data): \Closure
public function getLabels($key, $values, $data): callable
{
return function ($value) {
if ('_header' === $value) {
@@ -70,7 +85,7 @@ class ActivityUserAggregator implements AggregatorInterface
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return [self::KEY];
}

View File

@@ -27,7 +27,7 @@ class ActivityUsersAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actusers', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.users', 'actusers');
@@ -43,17 +43,32 @@ class ActivityUsersAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// nothing to add on the form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value) {
if ('_header' === $value) {
@@ -70,12 +85,12 @@ class ActivityUsersAggregator implements AggregatorInterface
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['activity_users_aggregator'];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Aggregate by activity users';
}

View File

@@ -34,7 +34,7 @@ class ActivityUsersJobAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,14 +65,29 @@ class ActivityUsersJobAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -34,7 +34,7 @@ class ActivityUsersScopeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,14 +65,29 @@ class ActivityUsersScopeAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -27,7 +27,7 @@ class ByCreatorAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->addSelect('IDENTITY(activity.createdBy) AS creator_aggregator');
$qb->addGroupBy('creator_aggregator');
@@ -38,17 +38,32 @@ class ByCreatorAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -27,7 +27,7 @@ class ByThirdpartyAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('acttparty', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.thirdParties', 'acttparty');
@@ -42,17 +42,32 @@ class ByThirdpartyAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -34,7 +34,7 @@ class CreatorJobAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,14 +65,29 @@ class CreatorJobAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -34,7 +34,7 @@ class CreatorScopeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,14 +65,29 @@ class CreatorScopeAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -32,7 +32,7 @@ class DateAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$order = null;
@@ -67,7 +67,7 @@ class DateAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('frequency', ChoiceType::class, [
'choices' => self::CHOICES,
@@ -76,12 +76,27 @@ class DateAggregator implements AggregatorInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['frequency' => $formData['frequency']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['frequency' => $formData['frequency']];
}
public function getFormDefaultData(): array
{
return ['frequency' => self::DEFAULT_CHOICE];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return static function ($value) use ($data): string {
if ('_header' === $value) {

View File

@@ -27,7 +27,7 @@ class LocationTypeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actloc', $qb->getAllAliases(), true)) {
$qb->leftJoin('activity.location', 'actloc');
@@ -42,17 +42,32 @@ class LocationTypeAggregator implements AggregatorInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -24,17 +24,32 @@ final readonly class HouseholdAggregator implements AggregatorInterface
{
public function __construct(private HouseholdRepository $householdRepository) {}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// nothing to add here
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
public function getLabels($key, array $values, mixed $data): callable
{
return function (int|string|null $value): string|int {
if ('_header' === $value) {
@@ -49,12 +64,12 @@ final readonly class HouseholdAggregator implements AggregatorInterface
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['activity_household_agg'];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aggregator.person.by_household.title';
}
@@ -64,7 +79,7 @@ final readonly class HouseholdAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->join(
HouseholdMember::class,
@@ -92,7 +107,7 @@ final readonly class HouseholdAggregator implements AggregatorInterface
->addGroupBy('activity_household_agg');
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY_PERSON;
}

View File

@@ -21,27 +21,42 @@ final readonly class PersonAggregator implements AggregatorInterface
{
public function __construct(private LabelPersonHelper $labelPersonHelper) {}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// nothing to add here
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
public function getLabels($key, array $values, mixed $data): callable
{
return $this->labelPersonHelper->getLabel($key, $values, 'export.aggregator.person.by_person.person');
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['activity_by_person_agg'];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aggregator.person.by_person.title';
}
@@ -51,14 +66,14 @@ final readonly class PersonAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb
->addSelect('IDENTITY(activity.person) AS activity_by_person_agg')
->addGroupBy('activity_by_person_agg');
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY_PERSON;
}

View File

@@ -27,17 +27,32 @@ final readonly class PersonsAggregator implements AggregatorInterface
public function __construct(private LabelPersonHelper $labelPersonHelper) {}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// nothing to add here
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, mixed $data)
public function getLabels($key, array $values, mixed $data): callable
{
if ($key !== self::PREFIX.'_pid') {
throw new \UnexpectedValueException('this key should not be handled: '.$key);
@@ -46,12 +61,12 @@ final readonly class PersonsAggregator implements AggregatorInterface
return $this->labelPersonHelper->getLabel($key, $values, 'export.aggregator.activity.by_persons.Persons');
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return [self::PREFIX.'_pid'];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aggregator.activity.by_persons.Group activity by persons';
}
@@ -61,7 +76,7 @@ final readonly class PersonsAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -71,7 +86,7 @@ final readonly class PersonsAggregator implements AggregatorInterface
->addGroupBy("{$p}_pid");
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}

View File

@@ -26,7 +26,7 @@ class SentReceivedAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->addSelect('activity.sentReceived AS activity_sentreceived_aggregator')
->addGroupBy('activity_sentreceived_aggregator');
@@ -42,6 +42,21 @@ class SentReceivedAggregator implements AggregatorInterface
// No form needed
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
@@ -38,6 +39,21 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -72,7 +88,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
return ['export_avg_activity_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -87,7 +103,7 @@ class AvgActivityDuration implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\FormatterInterface;
use Chill\MainBundle\Export\GroupedExportInterface;
@@ -46,6 +47,21 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
// TODO: Implement buildForm() method.
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -80,7 +96,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return ['export_avg_activity_visit_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -95,7 +111,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -43,6 +43,21 @@ class CountActivity implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -77,7 +92,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return ['export_count_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -92,7 +107,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -44,6 +44,21 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -78,7 +93,7 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
return ['export_count_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -93,7 +108,7 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -43,6 +43,21 @@ class CountPersonsOnActivity implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -77,7 +92,7 @@ class CountPersonsOnActivity implements ExportInterface, GroupedExportInterface
return ['export_count_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -92,7 +107,7 @@ class CountPersonsOnActivity implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -17,6 +17,7 @@ use Chill\ActivityBundle\Export\Export\ListActivityHelper;
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Export\AccompanyingCourseExportHelper;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Export\Helper\TranslatableStringExportLabelHelper;
use Chill\MainBundle\Export\ListInterface;
@@ -38,6 +39,21 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
$this->helper->buildForm($builder);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -73,7 +89,7 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return
array_merge(
@@ -85,25 +101,23 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
);
}
public function getResult($query, $data)
public function getResult($query, $data, ExportGenerationContext $context): array
{
return $this->helper->getResult($query, $data);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return ListActivityHelper::MSG_KEY.'List activity linked to a course';
}
public function getType()
public function getType(): string
{
return $this->helper->getType();
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);
$qb = $this->entityManager->createQueryBuilder();
$qb
@@ -114,7 +128,7 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
->leftJoin('acppart.person', 'person')
->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL');
$this->filterListAccompanyingPeriodHelper->addFilterAccompanyingPeriods($qb, $requiredModifiers, $acl, $data);
$this->filterListAccompanyingPeriodHelper->addFilterAccompanyingPeriods($qb, $requiredModifiers, $acl, $context->byUser, $data);
$qb
// some grouping are necessary

View File

@@ -40,9 +40,21 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
// TODO: Implement buildForm() method.
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
@@ -79,7 +91,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
return ['export_sum_activity_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -94,7 +106,7 @@ class SumActivityDuration implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -40,9 +40,21 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
// TODO: Implement buildForm() method.
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
@@ -79,7 +91,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return ['export_sum_activity_visit_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -94,7 +106,7 @@ class SumActivityVisitDuration implements ExportInterface, GroupedExportInterfac
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -35,6 +35,21 @@ class CountActivity implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -64,17 +79,17 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return static fn ($value) => '_header' === $value ? 'Number of activities linked to a person' : $value;
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['export_count_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Count activities linked to a person';
}
@@ -84,7 +99,7 @@ class CountActivity implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -36,6 +36,21 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -65,17 +80,17 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
return static fn ($value) => '_header' === $value ? 'export.export.count_household_on_activity_person.header' : $value;
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['export_count_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.export.count_household_on_activity_person.title';
}
@@ -85,7 +100,7 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -78,6 +78,21 @@ class ListActivity implements ListInterface, GroupedExportInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['fields' => $formData['fields']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['fields' => $formData['fields']];
}
public function getFormDefaultData(): array
{
return [];
@@ -167,17 +182,17 @@ class ListActivity implements ListInterface, GroupedExportInterface
}
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return $data['fields'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'List activity linked to a person';
}
@@ -187,7 +202,7 @@ class ListActivity implements ListInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(static fn ($el) => $el['center'], $acl);

View File

@@ -49,6 +49,21 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -84,17 +99,17 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
return static fn (string $value) => '_header' === $value ? $header : $value;
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return ['export_stat_activity'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
if (self::SUM === $this->action) {
return 'Sum activity linked to a person duration';
@@ -108,7 +123,7 @@ class StatActivityDuration implements ExportInterface, GroupedExportInterface
return Declarations::ACTIVITY;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$centers = array_map(
static fn (array $el): Center => $el['center'],

View File

@@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Form\FormBuilderInterface;
final readonly class ActivityTypeFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const BASE_EXISTS = 'SELECT 1 FROM '.Activity::class.' act_type_filter_activity WHERE act_type_filter_activity.accompanyingPeriod = acp';
public function __construct(
@@ -38,7 +40,7 @@ final readonly class ActivityTypeFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$exists = self::BASE_EXISTS;
@@ -62,12 +64,12 @@ final readonly class ActivityTypeFilter implements FilterInterface
}
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_activitytypes', EntityType::class, [
'class' => ActivityType::class,
@@ -92,6 +94,21 @@ final readonly class ActivityTypeFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_activitytypes' => $this->normalizeDoctrineEntity($formData['accepted_activitytypes']), 'date_after' => $formData['date_after']?->normalize(), 'date_before' => $formData['date_before']?->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_activitytypes' => $this->denormalizeDoctrineEntity($formData['accepted_activitytypes'], $this->activityTypeRepository), 'date_after' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['date_after']), 'date_before' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['date_before'])];
}
public function getFormDefaultData(): array
{
return [
@@ -101,7 +118,7 @@ final readonly class ActivityTypeFilter implements FilterInterface
];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$types = [];

View File

@@ -12,23 +12,28 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportDataNormalizerTrait;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Form\Type\PickSocialActionType;
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class BySocialActionFilter implements FilterInterface
{
public function __construct(private readonly SocialActionRender $actionRender) {}
use ExportDataNormalizerTrait;
public function __construct(private readonly SocialActionRender $actionRender, private readonly SocialActionRepository $socialActionRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actsocialaction', $qb->getAllAliases(), true)) {
$qb->join('activity.socialActions', 'actsocialaction');
@@ -48,19 +53,36 @@ class BySocialActionFilter implements FilterInterface
return Declarations::ACTIVITY_ACP;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_socialactions', PickSocialActionType::class, [
'multiple' => true,
]);
}
public function getFormDefaultData(): array
public function getNormalizationVersion(): int
{
return [];
return 1;
}
public function describeAction($data, $format = 'string'): array
public function normalizeFormData(array $formData): array
{
return ['accepted_socialactions' => $this->normalizeDoctrineEntity($formData['accepted_socialactions'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_socialactions' => $this->denormalizeDoctrineEntity($formData['accepted_socialactions'], $this->socialActionRepository)];
}
public function getFormDefaultData(): array
{
return [
'accepted_socialactions' => [],
];
}
public function describeAction($data, ExportGenerationContext $context): array
{
$actions = [];

View File

@@ -12,23 +12,28 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportDataNormalizerTrait;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Form\Type\PickSocialIssueType;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class BySocialIssueFilter implements FilterInterface
{
public function __construct(private readonly SocialIssueRender $issueRender) {}
use ExportDataNormalizerTrait;
public function __construct(private readonly SocialIssueRender $issueRender, private readonly SocialIssueRepository $issueRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actsocialissue', $qb->getAllAliases(), true)) {
$qb->join('activity.socialIssues', 'actsocialissue');
@@ -48,19 +53,34 @@ class BySocialIssueFilter implements FilterInterface
return Declarations::ACTIVITY_ACP;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_socialissues', PickSocialIssueType::class, [
'multiple' => true,
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_socialissues' => $this->normalizeDoctrineEntity($formData['accepted_socialissues'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_socialissues' => $this->denormalizeDoctrineEntity($formData['accepted_socialissues'], $this->issueRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$issues = [];

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
@@ -27,7 +28,7 @@ class HasNoActivityFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$qb
->andWhere('
@@ -43,17 +44,32 @@ class HasNoActivityFilter implements FilterInterface
return Declarations::ACP_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form needed
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
return ['Filtered acp which has no activities', []];
}

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
@@ -25,12 +26,12 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
private RollingDateConverterInterface $rollingDateConverter,
) {}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.filter.activity.course_having_activity_between_date.Title';
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('start_date', PickRollingDateType::class, [
@@ -41,6 +42,21 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['start_date' => $formData['start_date']->normalize(), 'end_date' => $formData['end_date']->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date'])];
}
public function getFormDefaultData(): array
{
return [
@@ -49,7 +65,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
return [
'export.filter.activity.course_having_activity_between_date.Only course having an activity between from and to',
@@ -65,7 +81,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$alias = 'act_period_having_act_betw_date_alias';
$from = 'act_period_having_act_betw_date_start';
@@ -82,7 +98,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
->setParameter($to, $this->rollingDateConverter->convert($data['end_date']));
}
public function applyOn()
public function applyOn(): string
{
return \Chill\PersonBundle\Export\Declarations::ACP_TYPE;
}

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
@@ -30,7 +31,7 @@ class ActivityDateFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->between(
@@ -61,7 +62,7 @@ class ActivityDateFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('date_from', PickRollingDateType::class, [
@@ -72,12 +73,27 @@ class ActivityDateFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['date_from' => $formData['date_from']->normalize(), 'date_to' => $formData['date_to']->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['date_from' => RollingDate::fromNormalized($formData['date_from']), 'date_to' => RollingDate::fromNormalized($formData['date_to'])];
}
public function getFormDefaultData(): array
{
return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
return [
'Filtered by date of activity: only between %date_from% and %date_to%',
@@ -88,7 +104,7 @@ class ActivityDateFilter implements FilterInterface
];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Filtered by date activity';
}

View File

@@ -13,6 +13,8 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\ActivityPresence;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityPresenceRepositoryInterface;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\Common\Collections\Collection;
@@ -23,17 +25,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
final readonly class ActivityPresenceFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(
private TranslatableStringHelperInterface $translatableStringHelper,
private TranslatorInterface $translator,
private ActivityPresenceRepositoryInterface $activityPresenceRepository,
) {}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.filter.activity.by_presence.Filter activity by activity presence';
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('presences', EntityType::class, [
'class' => ActivityPresence::class,
@@ -45,12 +50,27 @@ final readonly class ActivityPresenceFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['presences' => $this->normalizeDoctrineEntity($formData['presences'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['presences' => $this->denormalizeDoctrineEntity($formData['presences'], $this->activityPresenceRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
$presences = array_map(
fn (ActivityPresence $presence) => $this->translatableStringHelper->localize($presence->getName()),
@@ -68,14 +88,14 @@ final readonly class ActivityPresenceFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$qb
->andWhere('activity.attendee IN (:activity_presence_filter_presences)')
->setParameter('activity_presence_filter_presences', $data['presences']);
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\ActivityType;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityTypeRepositoryInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\ORM\QueryBuilder;
@@ -24,6 +25,8 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(
protected TranslatableStringHelperInterface $translatableStringHelper,
protected ActivityTypeRepositoryInterface $activityTypeRepository,
@@ -34,7 +37,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$clause = $qb->expr()->in('activity.activityType', ':selected_activity_types');
@@ -47,7 +50,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('types', EntityType::class, [
'choices' => $this->activityTypeRepository->findAllActive(),
@@ -70,12 +73,27 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['types' => $this->normalizeDoctrineEntity($formData['types'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['types' => $this->denormalizeDoctrineEntity($formData['types'], $this->activityTypeRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
// collect all the reasons'name used in this filter in one array
$reasonsNames = array_map(
@@ -88,12 +106,12 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
]];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Filter by activity type';
}
public function validateForm($data, ExecutionContextInterface $context)
public function validateForm($data, ExecutionContextInterface $context): void
{
if (null === $data['types'] || 0 === \count($data['types'])) {
$context

View File

@@ -12,26 +12,30 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Form\Type\PickUserOrMeDynamicType;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ActivityUsersFilter implements FilterInterface
final readonly class ActivityUsersFilter implements FilterInterface
{
public function __construct(private readonly UserRender $userRender) {}
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(private UserRender $userRender, private UserRepositoryInterface $userRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$orX = $qb->expr()->orX();
foreach ($data['accepted_users'] as $key => $user) {
foreach ($this->userOrMe($data['accepted_users'], $exportGenerationContext) as $key => $user) {
$orX->add($qb->expr()->isMemberOf(':activity_users_filter_u'.$key, 'activity.users'));
$qb->setParameter('activity_users_filter_u'.$key, $user);
}
@@ -39,29 +43,44 @@ class ActivityUsersFilter implements FilterInterface
$qb->andWhere($orX);
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_users', PickUserDynamicType::class, [
$builder->add('accepted_users', PickUserOrMeDynamicType::class, [
'multiple' => true,
'label' => 'Users',
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_users' => $this->normalizeUserOrMe($formData['accepted_users'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_users' => $this->denormalizeUserOrMe($formData['accepted_users'], $this->userRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
$users = [];
foreach ($data['accepted_users'] as $u) {
foreach ($this->userOrMe($data['accepted_users'], $context) as $u) {
$users[] = $this->userRender->renderString($u, []);
}

View File

@@ -12,28 +12,32 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Form\Type\PickUserOrMeDynamicType;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ByCreatorFilter implements FilterInterface
{
public function __construct(private readonly UserRender $userRender) {}
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(private readonly UserRender $userRender, private readonly UserRepositoryInterface $userRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$qb
->andWhere(
$qb->expr()->in('activity.createdBy', ':users')
)
->setParameter('users', $data['accepted_users']);
->setParameter('users', $this->userOrMe($data['accepted_users'], $exportGenerationContext));
}
public function applyOn(): string
@@ -41,23 +45,38 @@ class ByCreatorFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_users', PickUserDynamicType::class, [
$builder->add('accepted_users', PickUserOrMeDynamicType::class, [
'multiple' => true,
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_users' => $this->normalizeUserOrMe($formData['accepted_users'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_users' => $this->denormalizeUserOrMe($formData['accepted_users'], $this->userRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$users = [];
foreach ($data['accepted_users'] as $u) {
foreach ($this->userOrMe($data['accepted_users'], $context) as $u) {
$users[] = $this->userRender->renderString($u, []);
}

View File

@@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\User\UserJobHistory;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
@@ -26,6 +27,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
final readonly class CreatorJobFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'acp_act_filter_creator_job';
public function __construct(
@@ -39,7 +41,7 @@ final readonly class CreatorJobFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -75,7 +77,7 @@ final readonly class CreatorJobFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('jobs', EntityType::class, [
@@ -90,7 +92,22 @@ final readonly class CreatorJobFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string'): array
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['jobs' => $this->normalizeDoctrineEntity($formData['jobs'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['jobs' => $this->denormalizeDoctrineEntity($formData['jobs'], $this->userJobRepository)];
}
public function describeAction($data, ExportGenerationContext $context): array
{
$jobs = array_map(
fn (UserJob $job) => $this->translatableStringHelper->localize($job->getLabel()),

View File

@@ -14,6 +14,7 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
@@ -24,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class CreatorScopeFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'acp_act_filter_creator_scope';
public function __construct(
@@ -36,7 +38,7 @@ class CreatorScopeFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -72,7 +74,7 @@ class CreatorScopeFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('scopes', EntityType::class, [
@@ -86,7 +88,22 @@ class CreatorScopeFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string'): array
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['scopes' => $this->normalizeDoctrineEntity($formData['scopes'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['scopes' => $this->denormalizeDoctrineEntity($formData['scopes'], $this->scopeRepository)];
}
public function describeAction($data, ExportGenerationContext $context): array
{
$scopes = [];

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
@@ -35,7 +36,7 @@ class EmergencyFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$where = $qb->getDQLPart('where');
@@ -56,7 +57,7 @@ class EmergencyFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_emergency', ChoiceType::class, [
'choices' => self::CHOICES,
@@ -66,12 +67,27 @@ class EmergencyFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_emergency' => $formData['accepted_emergency']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_emergency' => $formData['accepted_emergency']];
}
public function getFormDefaultData(): array
{
return ['accepted_emergency' => self::DEFAULT_CHOICE];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
return [
'Filtered by emergency: only %emergency%', [

View File

@@ -12,19 +12,27 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserLocationType;
use Chill\MainBundle\Repository\LocationRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class LocationFilter implements FilterInterface
final readonly class LocationFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(
private LocationRepository $locationRepository,
) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$qb->andWhere(
$qb->expr()->in('activity.location', ':location')
@@ -38,7 +46,7 @@ class LocationFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_location', PickUserLocationType::class, [
'multiple' => true,
@@ -46,12 +54,27 @@ class LocationFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_location' => $this->normalizeDoctrineEntity($formData['accepted_location'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_location' => $this->denormalizeDoctrineEntity($formData['accepted_location'], $this->locationRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$locations = [];

View File

@@ -12,8 +12,11 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportDataNormalizerTrait;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickLocationTypeType;
use Chill\MainBundle\Repository\LocationTypeRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
@@ -21,14 +24,16 @@ use Symfony\Component\Form\FormBuilderInterface;
class LocationTypeFilter implements FilterInterface
{
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {}
use ExportDataNormalizerTrait;
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper, private LocationTypeRepository $locationTypeRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('actloc', $qb->getAllAliases(), true)) {
$qb->join('activity.location', 'actloc');
@@ -52,7 +57,7 @@ class LocationTypeFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_locationtype', PickLocationTypeType::class, [
'multiple' => true,
@@ -60,12 +65,27 @@ class LocationTypeFilter implements FilterInterface
]);
}
public function getFormDefaultData(): array
public function getNormalizationVersion(): int
{
return [];
return 1;
}
public function describeAction($data, $format = 'string'): array
public function normalizeFormData(array $formData): array
{
return ['accepted_locationtype' => $this->normalizeDoctrineEntity($formData['accepted_locationtype'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_locationtype' => $this->denormalizeDoctrineEntity($formData['accepted_locationtype'], $this->locationTypeRepository)];
}
public function getFormDefaultData(): array
{
return ['accepted_locationtype' => []];
}
public function describeAction($data, ExportGenerationContext $context): array
{
$types = [];

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\Common\Collections\Collection;
@@ -26,6 +27,8 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(protected TranslatableStringHelper $translatableStringHelper, protected ActivityReasonRepository $activityReasonRepository) {}
public function addRole(): ?string
@@ -33,7 +36,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$where = $qb->getDQLPart('where');
$join = $qb->getDQLPart('join');
@@ -58,7 +61,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
return Declarations::ACTIVITY_PERSON;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('reasons', EntityType::class, [
'class' => ActivityReason::class,
@@ -70,12 +73,27 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['reasons' => $this->normalizeDoctrineEntity($formData['reasons'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['reasons' => $this->denormalizeDoctrineEntity($formData['reasons'], $this->activityReasonRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
// collect all the reasons'name used in this filter in one array
$reasonsNames = array_map(
@@ -91,12 +109,12 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'Filter by reason';
}
public function validateForm($data, ExecutionContextInterface $context)
public function validateForm($data, ExecutionContextInterface $context): void
{
if (null === $data['reasons'] || 0 === \count($data['reasons'])) {
$context

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
@@ -39,7 +40,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
// create a subquery for activity
$sqb = $qb->getEntityManager()->createQueryBuilder();
@@ -92,7 +93,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
return Declarations::PERSON_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('date_from_rolling', PickRollingDateType::class, [
'label' => 'export.filter.activity.person_between_dates.Implied in an activity after this date',
@@ -116,6 +117,21 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
}
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['date_from_rolling' => $formData['date_from_rolling']->normalize(), 'date_to_rolling' => $formData['date_to_rolling']->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['date_from_rolling' => RollingDate::fromNormalized($formData['date_from_rolling']), 'date_to_rolling' => RollingDate::fromNormalized($formData['date_to_rolling'])];
}
public function getFormDefaultData(): array
{
return [
@@ -125,7 +141,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
return [
[] === $data['reasons'] ?
@@ -150,7 +166,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
return 'export.filter.activity.person_between_dates.title';
}
public function validateForm($data, ExecutionContextInterface $context)
public function validateForm($data, ExecutionContextInterface $context): void
{
if ($this->rollingDateConverter->convert($data['date_from_rolling'])
>= $this->rollingDateConverter->convert($data['date_to_rolling'])) {

View File

@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Tests\Export\Filter\PersonsFilterTest;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
@@ -33,7 +34,7 @@ final readonly class PersonsFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -47,12 +48,12 @@ final readonly class PersonsFilter implements FilterInterface
$qb->andWhere($orX);
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_persons', PickPersonDynamicType::class, [
'multiple' => true,
@@ -60,6 +61,21 @@ final readonly class PersonsFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_persons' => $formData['accepted_persons']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_persons' => $formData['accepted_persons']];
}
public function getFormDefaultData(): array
{
return [
@@ -67,7 +83,7 @@ final readonly class PersonsFilter implements FilterInterface
];
}
public function describeAction($data, $format = 'string')
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
$users = [];

View File

@@ -13,6 +13,7 @@ namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
@@ -36,7 +37,7 @@ class SentReceivedFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$where = $qb->getDQLPart('where');
@@ -57,7 +58,7 @@ class SentReceivedFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_sentreceived', ChoiceType::class, [
'choices' => self::CHOICES,
@@ -68,12 +69,27 @@ class SentReceivedFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_sentreceived' => $formData['accepted_sentreceived']];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_sentreceived' => $formData['accepted_sentreceived']];
}
public function getFormDefaultData(): array
{
return ['accepted_sentreceived' => self::DEFAULT_CHOICE];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$sentreceived = array_flip(self::CHOICES)[$data['accepted_sentreceived']];

View File

@@ -12,23 +12,27 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Filter;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Form\Type\PickUserOrMeDynamicType;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class UserFilter implements FilterInterface
final readonly class UserFilter implements FilterInterface
{
public function __construct(private readonly UserRender $userRender) {}
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(private UserRender $userRender, private UserRepositoryInterface $userRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$where = $qb->getDQLPart('where');
@@ -41,7 +45,7 @@ class UserFilter implements FilterInterface
}
$qb->add('where', $where);
$qb->setParameter('users', $data['accepted_users']);
$qb->setParameter('users', $this->userOrMe($data['accepted_users'], $exportGenerationContext));
}
public function applyOn(): string
@@ -49,24 +53,39 @@ class UserFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_users', PickUserDynamicType::class, [
$builder->add('accepted_users', PickUserOrMeDynamicType::class, [
'multiple' => true,
'label' => 'Creators',
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_users' => $this->normalizeUserOrMe($formData['accepted_users'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_users' => $this->denormalizeUserOrMe($formData['accepted_users'], $this->userRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$users = [];
foreach ($data['accepted_users'] as $u) {
foreach ($this->userOrMe($data['accepted_users'], $context) as $u) {
$users[] = $this->userRender->renderString($u, []);
}

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\User\UserJobHistory;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class UsersJobFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'act_filter_user_job';
public function __construct(
@@ -37,7 +39,7 @@ class UsersJobFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -60,12 +62,12 @@ class UsersJobFilter implements FilterInterface
);
}
public function applyOn()
public function applyOn(): string
{
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('jobs', EntityType::class, [
@@ -77,7 +79,22 @@ class UsersJobFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string')
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['jobs' => $this->normalizeDoctrineEntity($formData['jobs'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['jobs' => $this->denormalizeDoctrineEntity($formData['jobs'], $this->userJobRepository)];
}
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
return ['export.filter.activity.by_users_job.Filtered activity by users job: only %jobs%', [
'%jobs%' => implode(
@@ -97,7 +114,7 @@ class UsersJobFilter implements FilterInterface
];
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.filter.activity.by_users_job.Filter by users job';
}

View File

@@ -15,6 +15,7 @@ use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class UsersScopeFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'act_filter_user_scope';
public function __construct(
@@ -37,7 +39,7 @@ class UsersScopeFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,7 +67,7 @@ class UsersScopeFilter implements FilterInterface
return Declarations::ACTIVITY;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('scopes', EntityType::class, [
@@ -77,7 +79,22 @@ class UsersScopeFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string'): array
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['scopes' => $this->normalizeDoctrineEntity($formData['scopes'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['scopes' => $this->denormalizeDoctrineEntity($formData['scopes'], $this->scopeRepository)];
}
public function describeAction($data, ExportGenerationContext $context): array
{
return ['export.filter.activity.by_users_scope.Filtered activity by users scope: only %scopes%', [
'%scopes%' => implode(

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -23,22 +24,30 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(protected Security $security, protected TranslatorInterface $translator) {}
public function __construct(
protected Security $security,
protected TranslatorInterface $translator,
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$period = $parameters['accompanyingCourse'];
$activities = $this->managerRegistry->getManager()->getRepository(Activity::class)->findBy(
['accompanyingPeriod' => $period]
);
if (
AccompanyingPeriod::STEP_DRAFT !== $period->getStep()
&& $this->security->isGranted(ActivityVoter::SEE, $period)
) {
$menu->addChild($this->translator->trans('Activity'), [
$menu->addChild($this->translator->trans('Activities'), [
'route' => 'chill_activity_activity_list',
'routeParameters' => [
'accompanying_period_id' => $period->getId(),
], ])
->setExtras(['order' => 40]);
->setExtras(['order' => 40, 'counter' => count($activities) > 0 ? count($activities) : null]);
}
}

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Entity\Person;
@@ -23,13 +24,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(private AuthorizationCheckerInterface $authorizationChecker, private TranslatorInterface $translator) {}
public function __construct(
private readonly ActivityACLAwareRepositoryInterface $activityACLAwareRepository,
private AuthorizationCheckerInterface $authorizationChecker,
private TranslatorInterface $translator,
) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/** @var Person $person */
$person = $parameters['person'];
$count = $this->activityACLAwareRepository->countByPerson($person, ActivityVoter::SEE);
if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) {
$menu->addChild(
$this->translator->trans('Activities'),
@@ -38,7 +46,7 @@ final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface
'routeParameters' => ['person_id' => $person->getId()],
]
)
->setExtra('order', 201);
->setExtras(['order' => 201, 'counter' => $count > 0 ? $count : null]);
}
}

View File

@@ -12,8 +12,9 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Repository;
use Chill\ActivityBundle\Entity\ActivityPresence;
use Doctrine\Persistence\ObjectRepository;
interface ActivityPresenceRepositoryInterface
interface ActivityPresenceRepositoryInterface extends ObjectRepository
{
public function find($id): ?ActivityPresence;

View File

@@ -120,3 +120,34 @@ li.document-list-item {
vertical-align: baseline;
}
}
.badge-activity-type-simple {
@extend .badge;
display: inline-block;
margin: 0.2rem 0;
padding-left: 0;
padding-right: 0.5rem;
border-left: 20px groove #9acd32;
border-radius: $badge-border-radius;
color: black;
font-weight: normal;
font-size: unset;
max-width: 100%;
background-color: $gray-100;
overflow: hidden;
text-overflow: ellipsis;
text-indent: 5px hanging;
text-align: left;
&::before {
margin-right: 3px;
position: relative;
left: -0.5px;
font-family: ForkAwesome;
content: '\f04b';
color: #9acd32;
}
}

View File

@@ -33,6 +33,7 @@
import { mapState, mapGetters } from "vuex";
import VueMultiselect from "vue-multiselect";
import NewLocation from "./Location/NewLocation.vue";
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
import {
trans,
ACTIVITY_LOCATION,
@@ -77,15 +78,15 @@ export default {
},
methods: {
labelAccompanyingCourseLocation(value) {
return `${value.address.text} (${value.locationType.title.fr})`;
return `${value.address.text} (${localizeString(value.locationType.title)})`;
},
customLabel(value) {
return value.locationType
? value.name
? value.name === "__AccompanyingCourseLocation__"
? this.labelAccompanyingCourseLocation(value)
: `${value.name} (${value.locationType.title.fr})`
: value.locationType.title.fr
: `${value.name} (${localizeString(value.locationType.title)})`
: localizeString(value.locationType.title)
: "";
},
},

View File

@@ -44,7 +44,7 @@
:value="t"
:key="t.id"
>
{{ t.title.fr }}
{{ localizeString(t.title) }}
</option>
</select>
<label>{{
@@ -126,6 +126,7 @@ import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue"
import { mapState } from "vuex";
import { getLocationTypes } from "../../api";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
import {
SAVE,
ACTIVITY_LOCATION_FIELDS_EMAIL,
@@ -270,6 +271,7 @@ export default {
this.getLocationTypesList();
},
methods: {
localizeString,
checkForm() {
let cond = true;
this.errors = [];

View File

@@ -41,9 +41,7 @@ const i18nGendoc = _createI18n({});
document.querySelectorAll("div[data-docgen-template-picker]").forEach((el) => {
fetchTemplates(el.dataset.entityClass).then((templates) => {
const picker = {
template:
'<pick-template :templates="this.templates" :preventDefaultMoveToGenerate="true" ' +
':entityClass="faked" @go-to-generate-document="generateDoc"></pick-template>',
template: `<pick-template :templates="this.templates" :preventDefaultMoveToGenerate="true" @go-to-generate-document="generateDoc"></pick-template>`,
components: {
PickTemplate,
},
@@ -54,7 +52,7 @@ document.querySelectorAll("div[data-docgen-template-picker]").forEach((el) => {
};
},
methods: {
generateDoc({ event, link, template }) {
generateDoc({ link, template }) {
console.log("generateDoc");
console.log("link", link);
console.log("template", template);

View File

@@ -2,7 +2,7 @@ import "es6-promise/auto";
import { createStore } from "vuex";
import { postLocation } from "./api";
import prepareLocations from "./store.locations.js";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import { fetchResults, makeFetch } from "ChillMainAssets/lib/api/apiMethods";
const debug = process.env.NODE_ENV !== "production";
//console.log('window.activity', window.activity);
@@ -365,11 +365,11 @@ const store = createStore({
const accompanyingPeriodId = state.activity.accompanyingPeriod.id;
const url = `/api/1.0/person/accompanying-course/${accompanyingPeriodId}/works.json`;
try {
const works = await makeFetch("GET", url);
// console.log("works", works);
const works = await fetchResults(url);
// console.log('works', works);
commit("setAccompanyingPeriodWorks", works);
} catch (error) {
console.error("Failed to fetch accompanying period works:", error);
console.error("Failed to fetch works:", error);
}
},
getWhoAmI({ commit }) {

View File

@@ -3,7 +3,7 @@
{% block admin_content %}
<h1>{{ 'ActivityReason list'|trans }}</h1>
<table class="records_list">
<table class="table table-bordered border-dark align-middle">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
@@ -29,10 +29,7 @@
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_activity_activityreason_show', { 'id': entity.id }) }}" class="btn btn-show" title="{{ 'show'|trans }}"></a>
</li>
<li>
<a href="{{ path('chill_activity_activityreason_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
<a href="{{ path('chill_activity_activityreason_update', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
</li>
</ul>
</td>

View File

@@ -3,7 +3,7 @@
{% block admin_content %}
<h1>{{ 'ActivityReasonCategory list'|trans }}</h1>
<table class="records_list">
<table class="table table-bordered border-dark align-middle">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
@@ -23,10 +23,7 @@
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_activity_activityreasoncategory_show', { 'id': entity.id }) }}" class="btn btn-show" title="{{ 'show'|trans }}"></a>
</li>
<li>
<a href="{{ path('chill_activity_activityreasoncategory_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
<a href="{{ path('chill_activity_activityreasoncategory_update', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
</li>
</ul>
</td>

View File

@@ -13,44 +13,44 @@
{% endif %}
<div class="item-row">
<div class="item-col" style="width: unset">
{% if document.isPending %}
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
{% elseif document.isFailure %}
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
{% endif %}
<div>
{% if activity.accompanyingPeriod is not null and context == 'person' %}
<span class="badge bg-primary">
<i class="fa fa-random"></i> {{ activity.accompanyingPeriod.id }}
</span>&nbsp;
<div class="item-two-col-grid">
<div class="title">
{% if document.isPending %}
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
{% elseif document.isFailure %}
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
{% endif %}
<div class="badge-activity-type">
<span class="title_label"></span>
<span class="title_action">
{{ activity.type.name | localize_translatable_string }}
<div>
<div>
<div class="badge-activity-type-simple">
{{ activity.type.name | localize_translatable_string }}
</div>
{% if activity.emergency %}
<span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span>
{% endif %}
</span>
</div>
</div>
</div>
<div class="denomination h2">
{{ document.title|chill_print_or_message("No title") }}
</div>
{% if document.hasTemplate %}
<div>
<p>{{ document.template.name|localize_translatable_string }}</p>
<div class="denomination h2">
{{ document.title|chill_print_or_message("No title") }}
</div>
{% endif %}
</div>
<div class="item-col">
<div class="container">
{% if document.hasTemplate %}
<div>
<p>{{ document.template.name|localize_translatable_string }}</p>
</div>
{% endif %}
</div>
<div class="aside">
<div class="dates row text-end">
<span>{{ document.createdAt|format_date('short') }}</span>
</div>
{% if activity.accompanyingPeriod is not null and context == 'person' %}
<div class="text-end">
<span class="badge bg-primary">
<i class="fa fa-random"></i> {{ activity.accompanyingPeriod.id }}
</span>&nbsp;
</div>
{% endif %}
</div>
</div>
</div>

View File

@@ -22,6 +22,52 @@ use Symfony\Component\Security\Core\Role\Role;
*/
final class ActivityControllerTest extends WebTestCase
{
/**
* @dataProvider getSecuredPagesUnauthenticated
*/
public function testAccessIsDeniedForUnauthenticated(mixed $url)
{
$client = $this->createClient();
$client->request('GET', $url);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertTrue(
$client->getResponse()->isRedirect('http://localhost/login'),
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
);
}
/**
* Provide a client unauthenticated and.
*/
public function getSecuredPagesUnauthenticated()
{
self::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
return [
[sprintf('fr/person/%d/activity/', $person->getId())],
[sprintf('fr/person/%d/activity/new', $person->getId())],
[sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())],
[sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())],
];
}
/**
* @dataProvider getSecuredPagesAuthenticated
*
* @param type $client
* @param type $url
*/
public function testAccessIsDeniedForUnauthorized($client, $url)
{
$client->request('GET', $url);
$this->assertEquals(403, $client->getResponse()->getStatusCode());
}
public function getSecuredPagesAuthenticated()
{
self::bootKernel();
@@ -55,52 +101,6 @@ final class ActivityControllerTest extends WebTestCase
];
}
/**
* Provide a client unauthenticated and.
*/
public function getSecuredPagesUnauthenticated()
{
self::bootKernel();
$person = $this->getPersonFromFixtures();
$activities = $this->getActivitiesForPerson($person);
return [
[sprintf('fr/person/%d/activity/', $person->getId())],
[sprintf('fr/person/%d/activity/new', $person->getId())],
[sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())],
[sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())],
];
}
/**
* @dataProvider getSecuredPagesUnauthenticated
*/
public function testAccessIsDeniedForUnauthenticated(mixed $url)
{
$client = $this->createClient();
$client->request('GET', $url);
$this->assertEquals(302, $client->getResponse()->getStatusCode());
$this->assertTrue(
$client->getResponse()->isRedirect('http://localhost/login'),
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
);
}
/**
* @dataProvider getSecuredPagesAuthenticated
*
* @param type $client
* @param type $url
*/
public function testAccessIsDeniedForUnauthorized($client, $url)
{
$client->request('GET', $url);
$this->assertEquals(403, $client->getResponse()->getStatusCode());
}
public function testCompleteScenario()
{
// Create a new client to browse the application

View File

@@ -45,14 +45,20 @@ final class ByCreatorFilterTest extends AbstractFilterTest
->from(User::class, 'u')
->select('u')
->getQuery()
->setMaxResults(1)
->getResult();
$data = [];
foreach ($array as $a) {
$data[] = [
'accepted_users' => $a,
];
}
$data[] = [
'accepted_users' => 'me',
];
return $data;
}

View File

@@ -55,6 +55,10 @@ final class UserFilterTest extends AbstractFilterTest
];
}
$data[] = [
'accepted_users' => 'me',
];
return $data;
}

View File

@@ -137,6 +137,64 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase
self::assertIsArray($actual);
}
public function provideDataFindByAccompanyingPeriod(): iterable
{
$this->setUp();
if (null === $period = $this->entityManager
->createQueryBuilder()
->select('a')
->from(AccompanyingPeriod::class, 'a')
->setMaxResults(1)
->getQuery()
->getSingleResult()) {
throw new \RuntimeException('no period found');
}
if ([] === $types = $this->entityManager
->createQueryBuilder()
->select('t')
->from(ActivityType::class, 't')
->setMaxResults(2)
->getQuery()
->getResult()) {
throw new \RuntimeException('no types');
}
if ([] === $jobs = $this->entityManager
->createQueryBuilder()
->select('j')
->from(UserJob::class, 'j')
->setMaxResults(2)
->getQuery()
->getResult()
) {
$job = new UserJob();
$job->setLabel(['fr' => 'test']);
$this->entityManager->persist($job);
$this->entityManager->flush();
}
if (null === $user = $this->entityManager
->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->setMaxResults(1)
->getQuery()
->getSingleResult()
) {
throw new \RuntimeException('no user found');
}
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['my_activities' => true]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['types' => $types]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['jobs' => $jobs]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
}
/**
* @dataProvider provideDataFindByPerson
*/
@@ -291,62 +349,4 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
}
public function provideDataFindByAccompanyingPeriod(): iterable
{
$this->setUp();
if (null === $period = $this->entityManager
->createQueryBuilder()
->select('a')
->from(AccompanyingPeriod::class, 'a')
->setMaxResults(1)
->getQuery()
->getSingleResult()) {
throw new \RuntimeException('no period found');
}
if ([] === $types = $this->entityManager
->createQueryBuilder()
->select('t')
->from(ActivityType::class, 't')
->setMaxResults(2)
->getQuery()
->getResult()) {
throw new \RuntimeException('no types');
}
if ([] === $jobs = $this->entityManager
->createQueryBuilder()
->select('j')
->from(UserJob::class, 'j')
->setMaxResults(2)
->getQuery()
->getResult()
) {
$job = new UserJob();
$job->setLabel(['fr' => 'test']);
$this->entityManager->persist($job);
$this->entityManager->flush();
}
if (null === $user = $this->entityManager
->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->setMaxResults(1)
->getQuery()
->getSingleResult()
) {
throw new \RuntimeException('no user found');
}
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['my_activities' => true]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['types' => $types]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['jobs' => $jobs]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
}
}

View File

@@ -57,6 +57,46 @@ final class ActivityVoterTest extends KernelTestCase
$this->prophet = new \Prophecy\Prophet();
}
public function testNullUser()
{
$token = $this->prepareToken();
$center = $this->prepareCenter(1, 'center');
$person = $this->preparePerson($center);
$scope = $this->prepareScope(1, 'default');
$activity = $this->prepareActivity($scope, $person);
$this->assertEquals(
VoterInterface::ACCESS_DENIED,
$this->voter->vote($token, $activity, ['CHILL_ACTIVITY_SEE']),
'assert that a null user is not allowed to see'
);
}
/**
* @dataProvider dataProvider_testVoteAction
*
* @param type $expectedResult
* @param string $attribute
* @param string $message
*/
public function testVoteAction(
$expectedResult,
User $user,
Scope $scope,
Center $center,
$attribute,
$message,
) {
$token = $this->prepareToken($user);
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
$this->assertEquals(
$expectedResult,
$this->voter->vote($token, $activity, [$attribute]),
$message
);
}
public function dataProvider_testVoteAction()
{
$centerA = $this->prepareCenter(1, 'center A');
@@ -110,46 +150,6 @@ final class ActivityVoterTest extends KernelTestCase
];
}
public function testNullUser()
{
$token = $this->prepareToken();
$center = $this->prepareCenter(1, 'center');
$person = $this->preparePerson($center);
$scope = $this->prepareScope(1, 'default');
$activity = $this->prepareActivity($scope, $person);
$this->assertEquals(
VoterInterface::ACCESS_DENIED,
$this->voter->vote($token, $activity, ['CHILL_ACTIVITY_SEE']),
'assert that a null user is not allowed to see'
);
}
/**
* @dataProvider dataProvider_testVoteAction
*
* @param type $expectedResult
* @param string $attribute
* @param string $message
*/
public function testVoteAction(
$expectedResult,
User $user,
Scope $scope,
Center $center,
$attribute,
$message,
) {
$token = $this->prepareToken($user);
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
$this->assertEquals(
$expectedResult,
$this->voter->vote($token, $activity, [$attribute]),
$message
);
}
/**
* prepare a token interface with correct rights.
*

View File

@@ -30,7 +30,7 @@ class ActivityValidity extends Constraint
public $socialIssuesMessage = 'For this type of activity, you must add at least one social issue';
public function getTargets()
public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}

View File

@@ -1,10 +0,0 @@
# configuration for apigen
source:
- .
exclude:
- vendor/*
- Test*
title: Chill Activity Bundle

View File

@@ -1,40 +0,0 @@
{
"name": "chill-project/activity",
"description": "This bundle extend chill for recording the different activities of the user",
"type": "symfony-bundle",
"license": "AGPL-3.0",
"keywords" : ["chill", "social work"],
"homepage" : "https://github.com/Chill-project/Activity",
"autoload": {
"psr-4": { "Chill\\ActivityBundle\\": "" }
},
"autoload-dev": {
"classmap": [ "Resources/test/Fixtures/App/app/AppKernel.php" ]
},
"authors": [
{
"name": "Champs-Libres",
"email": "info@champs-libres.coop"
}
],
"require": {
},
"require-dev": {
},
"scripts": {
"post-install-cmd": [
"ComposerBundleMigration\\Composer\\Migrations::synchronizeMigrations",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap"
],
"post-update-cmd": [
"ComposerBundleMigration\\Composer\\Migrations::synchronizeMigrations",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap"
]
},
"extra": {
"app-migrations-dir": "Resources/test/Fixtures/App/app/DoctrineMigrations",
"symfony-app-dir": "Test/Fixtures/App/app/"
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./Resources/test/Fixtures/App/app/autoload.php" colors="true">
<testsuites>
<testsuite name="ChillActivityBundle test suite">
<directory suffix="Test.php">./Tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./</directory>
<exclude>
<directory>./Resources</directory>
<directory>./Tests</directory>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
<php>
<server name="KERNEL_DIR" value="Resources/test/Fixtures/App/app/" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
</php>
</phpunit>

View File

@@ -30,7 +30,7 @@ class ByActivityTypeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->addSelect('IDENTITY(aside.type) AS by_aside_activity_type_aggregator')
->addGroupBy('by_aside_activity_type_aggregator');
@@ -41,17 +41,32 @@ class ByActivityTypeAggregator implements AggregatorInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// No form needed
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -26,12 +26,27 @@ class ByLocationAggregator implements AggregatorInterface
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {
@@ -60,7 +75,7 @@ class ByLocationAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$qb->addSelect('IDENTITY(aside.location) AS by_aside_activity_location_aggregator')
->addGroupBy('by_aside_activity_location_aggregator');

View File

@@ -34,7 +34,7 @@ class ByUserJobAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,14 +65,29 @@ class ByUserJobAggregator implements AggregatorInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -34,7 +34,7 @@ class ByUserScopeAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -64,14 +64,29 @@ class ByUserScopeAggregator implements AggregatorInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder) {}
public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data)
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -26,6 +26,21 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -60,7 +75,7 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac
return ['export_avg_aside_activity_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -75,7 +90,7 @@ class AvgAsideActivityDuration implements ExportInterface, GroupedExportInterfac
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$qb = $this->repository->createQueryBuilder('aside');

View File

@@ -26,6 +26,21 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -63,7 +78,7 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface
return ['export_result'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -78,7 +93,7 @@ class CountAsideActivity implements ExportInterface, GroupedExportInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$qb = $this->repository->createQueryBuilder('aside');

View File

@@ -46,6 +46,21 @@ final readonly class ListAsideActivity implements ListInterface, GroupedExportIn
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -142,7 +157,7 @@ final readonly class ListAsideActivity implements ListInterface, GroupedExportIn
};
}
public function getQueryKeys($data)
public function getQueryKeys($data): array
{
return [
'id',
@@ -160,12 +175,12 @@ final readonly class ListAsideActivity implements ListInterface, GroupedExportIn
];
}
public function getResult($query, $data): array
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
}
public function getTitle()
public function getTitle(): string|\Symfony\Contracts\Translation\TranslatableInterface
{
return 'export.aside_activity.List of aside activities';
}
@@ -175,7 +190,7 @@ final readonly class ListAsideActivity implements ListInterface, GroupedExportIn
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$qb = $this->em->createQueryBuilder()
->from(AsideActivity::class, 'aside')

View File

@@ -26,6 +26,21 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac
public function buildForm(FormBuilderInterface $builder) {}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
@@ -60,7 +75,7 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac
return ['export_sum_aside_activity_duration'];
}
public function getResult($query, $data)
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
{
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
}
@@ -75,7 +90,7 @@ class SumAsideActivityDuration implements ExportInterface, GroupedExportInterfac
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
{
$qb = $this->repository
->createQueryBuilder('aside');

View File

@@ -15,6 +15,7 @@ use Chill\AsideActivityBundle\Entity\AsideActivityCategory;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository;
use Chill\AsideActivityBundle\Templating\Entity\CategoryRender;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Doctrine\Common\Collections\Collection;
@@ -24,10 +25,13 @@ use Symfony\Component\Form\FormBuilderInterface;
class ByActivityTypeFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(
private readonly CategoryRender $categoryRender,
private readonly TranslatableStringHelperInterface $translatableStringHelper,
private readonly AsideActivityCategoryRepository $asideActivityTypeRepository,
private readonly AsideActivityCategoryRepository $asideActivityCategoryRepository,
) {}
public function addRole(): ?string
@@ -35,7 +39,7 @@ class ByActivityTypeFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$clause = $qb->expr()->in('aside.type', ':types');
@@ -48,7 +52,7 @@ class ByActivityTypeFilter implements FilterInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('types', EntityType::class, [
@@ -68,12 +72,27 @@ class ByActivityTypeFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['types' => $this->normalizeDoctrineEntity($formData['types'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['types' => $this->denormalizeDoctrineEntity($formData['types'], $this->asideActivityCategoryRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$types = array_map(
fn (AsideActivityCategory $t): string => $this->translatableStringHelper->localize($t->getTitle()),

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\AsideActivityBundle\Export\Filter;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickRollingDateType;
use Chill\MainBundle\Service\RollingDate\RollingDate;
@@ -29,7 +30,7 @@ class ByDateFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$clause = $qb->expr()->between(
'aside.date',
@@ -53,7 +54,7 @@ class ByDateFilter implements FilterInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('date_from', PickRollingDateType::class, [
@@ -64,6 +65,21 @@ class ByDateFilter implements FilterInterface
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['date_from' => $formData['date_from']->normalize(), 'date_to' => $formData['date_to']->normalize()];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['date_from' => RollingDate::fromNormalized($formData['date_from']), 'date_to' => RollingDate::fromNormalized($formData['date_to'])];
}
public function getFormDefaultData(): array
{
return [
@@ -72,7 +88,7 @@ class ByDateFilter implements FilterInterface
];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
return ['export.filter.Filtered by aside activities between %dateFrom% and %dateTo%', [
'%dateFrom%' => $this->rollingDateConverter->convert($data['date_from'])->format('d-m-Y'),

View File

@@ -14,8 +14,10 @@ namespace Chill\AsideActivityBundle\Export\Filter;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserLocationType;
use Chill\MainBundle\Repository\LocationRepository;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
@@ -23,8 +25,11 @@ use Symfony\Component\Security\Core\Security;
final readonly class ByLocationFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(
private Security $security,
private LocationRepository $locationRepository,
) {}
public function getTitle(): string
@@ -38,6 +43,21 @@ final readonly class ByLocationFilter implements FilterInterface
->add('locations', PickUserLocationType::class);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['locations' => $this->normalizeDoctrineEntity($formData['locations'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['locations' => $this->denormalizeDoctrineEntity($formData['locations'], $this->locationRepository)];
}
public function getFormDefaultData(): array
{
$user = $this->security->getUser();
@@ -53,7 +73,7 @@ final readonly class ByLocationFilter implements FilterInterface
];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$extractFunction = fn (Location $l): string => $l->getName();
if ($data['locations'] instanceof Collection) {
@@ -72,7 +92,7 @@ final readonly class ByLocationFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data): void
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$clause = $qb->expr()->in('aside.location', ':locations');

View File

@@ -12,28 +12,32 @@ declare(strict_types=1);
namespace Chill\AsideActivityBundle\Export\Filter;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Form\Type\PickUserDynamicType;
use Chill\MainBundle\Form\Type\PickUserOrMeDynamicType;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Entity\UserRender;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ByUserFilter implements FilterInterface
final readonly class ByUserFilter implements FilterInterface
{
public function __construct(private readonly UserRender $userRender) {}
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
public function __construct(private UserRender $userRender, private UserRepository $userRepository) {}
public function addRole(): ?string
{
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$clause = $qb->expr()->in('aside.agent', ':users');
$qb
->andWhere($clause)
->setParameter('users', $data['accepted_users']);
->setParameter('users', $this->userOrMe($data['accepted_users'], $exportGenerationContext));
}
public function applyOn(): string
@@ -41,24 +45,39 @@ class ByUserFilter implements FilterInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder->add('accepted_users', PickUserDynamicType::class, [
$builder->add('accepted_users', PickUserOrMeDynamicType::class, [
'multiple' => true,
'label' => 'Creators',
]);
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['accepted_users' => $this->normalizeUserOrMe($formData['accepted_users'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['accepted_users' => $this->denormalizeUserOrMe($formData['accepted_users'], $this->userRepository)];
}
public function getFormDefaultData(): array
{
return [];
}
public function describeAction($data, $format = 'string'): array
public function describeAction($data, ExportGenerationContext $context): array
{
$users = [];
foreach ($data['accepted_users'] as $u) {
foreach ($this->userOrMe($data['accepted_users'], $context) as $u) {
$users[] = $this->userRender->renderString($u, []);
}

View File

@@ -15,6 +15,7 @@ use Chill\AsideActivityBundle\Entity\AsideActivity;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\User\UserJobHistory;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\UserJobRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class ByUserJobFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'aside_act_filter_user_job';
public function __construct(
@@ -37,7 +39,7 @@ class ByUserJobFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,7 +67,7 @@ class ByUserJobFilter implements FilterInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('jobs', EntityType::class, [
@@ -77,7 +79,22 @@ class ByUserJobFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string'): array
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['jobs' => $this->normalizeDoctrineEntity($formData['jobs'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['jobs' => $this->denormalizeDoctrineEntity($formData['jobs'], $this->userJobRepository)];
}
public function describeAction($data, ExportGenerationContext $context): array
{
return ['export.filter.by_user_job.Filtered aside activities by user jobs: only %jobs%', [
'%jobs%' => implode(

View File

@@ -15,6 +15,7 @@ use Chill\AsideActivityBundle\Entity\AsideActivity;
use Chill\AsideActivityBundle\Export\Declarations;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User\UserScopeHistory;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
@@ -25,6 +26,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class ByUserScopeFilter implements FilterInterface
{
use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
private const PREFIX = 'aside_act_filter_user_scope';
public function __construct(
@@ -37,7 +39,7 @@ class ByUserScopeFilter implements FilterInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{
$p = self::PREFIX;
@@ -65,7 +67,7 @@ class ByUserScopeFilter implements FilterInterface
return Declarations::ASIDE_ACTIVITY_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
$builder
->add('scopes', EntityType::class, [
@@ -77,7 +79,22 @@ class ByUserScopeFilter implements FilterInterface
]);
}
public function describeAction($data, $format = 'string')
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return ['scopes' => $this->normalizeDoctrineEntity($formData['scopes'])];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return ['scopes' => $this->denormalizeDoctrineEntity($formData['scopes'], $this->scopeRepository)];
}
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{
return ['export.filter.by_user_scope.Filtered aside activities by user scope: only %scopes%', [
'%scopes%' => implode(

View File

@@ -30,6 +30,18 @@ final class AsideActivityControllerTest extends WebTestCase
self::ensureKernelShutdown();
}
/**
* @dataProvider generateAsideActivityId
*/
public function testEditWithoutUsers(int $asideActivityId)
{
self::ensureKernelShutdown();
$client = $this->getClientAuthenticated();
$client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit");
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
public static function generateAsideActivityId(): iterable
{
self::bootKernel();
@@ -58,18 +70,6 @@ final class AsideActivityControllerTest extends WebTestCase
self::ensureKernelShutdown();
}
/**
* @dataProvider generateAsideActivityId
*/
public function testEditWithoutUsers(int $asideActivityId)
{
self::ensureKernelShutdown();
$client = $this->getClientAuthenticated();
$client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit");
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
public function testIndexWithoutUsers()
{
self::ensureKernelShutdown();

View File

@@ -12,6 +12,8 @@ declare(strict_types=1);
namespace Chill\AsideActivityBundle\Tests\Export\Export;
use Chill\AsideActivityBundle\Export\Export\ListAsideActivity;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\ExportGenerationContext;
use Doctrine\ORM\AbstractQuery;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
@@ -33,7 +35,7 @@ class ListAsideActivityTest extends KernelTestCase
public function testExecuteQuery(): void
{
$qb = $this->listAsideActivity->initiateQuery([], [], [])
$qb = $this->listAsideActivity->initiateQuery([], [], [], new ExportGenerationContext(new User()))
->setMaxResults(1);
$results = $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);

View File

@@ -1,30 +0,0 @@
{
"name": "chill-project/budget",
"description": "This bundle extend chill for recording element of a budget for peoples",
"type": "symfony-bundle",
"license": "AGPL-3.0",
"keywords" : ["chill", "social work"],
"homepage" : "https://framagit.org/Chill-project/BudgetBundle",
"autoload": {
"psr-4": { "Chill\\BudgetBundle\\": "" }
},
"autoload-dev": {
"classmap": [ "Resources/test/Fixtures/App/app/AppKernel.php" ]
},
"authors": [
{
"name": "Champs-Libres",
"email": "info@champs-libres.coop"
}
],
"require": {
},
"require-dev": {
},
"extra": {
"app-migrations-dir": "Resources/test/Fixtures/App/app/DoctrineMigrations",
"symfony-app-dir": "Test/Fixtures/App/app/"
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@@ -1,11 +0,0 @@
composer.lock
vendor/*
parameters.yml
*~
*.DS_Store
*.sass-cache
Resources/node_modules/
Tests/Fixtures/App/app/config/parameters.yml
/nbproject/private/
Resources/test/Fixtures/App/bootstrap.php.cache

View File

@@ -27,7 +27,7 @@ final readonly class AgentAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
if (!\in_array('caluser', $qb->getAllAliases(), true)) {
$qb->join('cal.mainUser', 'caluser');
@@ -42,17 +42,32 @@ final readonly class AgentAggregator implements AggregatorInterface
return Declarations::CALENDAR_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data): \Closure
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

View File

@@ -27,7 +27,7 @@ class CancelReasonAggregator implements AggregatorInterface
return null;
}
public function alterQuery(QueryBuilder $qb, $data)
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
{
// TODO: still needs to take into account calendars without a cancel reason somehow
if (!\in_array('calcancel', $qb->getAllAliases(), true)) {
@@ -43,17 +43,32 @@ class CancelReasonAggregator implements AggregatorInterface
return Declarations::CALENDAR_TYPE;
}
public function buildForm(FormBuilderInterface $builder)
public function buildForm(FormBuilderInterface $builder): void
{
// no form
}
public function getNormalizationVersion(): int
{
return 1;
}
public function normalizeFormData(array $formData): array
{
return [];
}
public function denormalizeFormData(array $formData, int $fromVersion): array
{
return [];
}
public function getFormDefaultData(): array
{
return [];
}
public function getLabels($key, array $values, $data): \Closure
public function getLabels($key, array $values, $data): callable
{
return function ($value): string {
if ('_header' === $value) {

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