Compare commits

...

6 Commits

Author SHA1 Message Date
Marc Ducobu
1de370bab1 Notification with paginitation 2021-06-30 12:02:18 +02:00
Marc Ducobu
559d3dd756 Rmq Julien & Pol 2021-06-30 11:33:19 +02:00
Marc Ducobu
4fd733dca7 Adding feature for AccompanyingPeriodNotif 2021-06-18 18:05:27 +02:00
Marc Ducobu
1ecb0a1dbe Display notification using services (draft) 2021-06-18 18:05:02 +02:00
Marc Ducobu
6ea5a3088c Add findAllForAttendee method in NotificationRepository 2021-06-18 17:19:39 +02:00
Marc Ducobu
e50bfd5129 Add center a_social to an activityNotif feature 2021-06-18 17:18:07 +02:00
19 changed files with 332 additions and 20 deletions

View File

@@ -22,6 +22,7 @@ class LoadActivityNotifications extends AbstractFixture implements DependentFixt
'entityRef' => 'activity_gerard depardieu', 'entityRef' => 'activity_gerard depardieu',
'sender' => 'center a_social', 'sender' => 'center a_social',
'addressees' => [ 'addressees' => [
'center a_social',
'center a_administrative', 'center a_administrative',
'center a_direction', 'center a_direction',
'multi_center' 'multi_center'

View File

@@ -55,6 +55,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
$loader->load('services/controller.yaml'); $loader->load('services/controller.yaml');
$loader->load('services/form.yaml'); $loader->load('services/form.yaml');
$loader->load('services/templating.yaml'); $loader->load('services/templating.yaml');
$loader->load('services/notification.yaml');
} }
public function prepend(ContainerBuilder $container) public function prepend(ContainerBuilder $container)

View File

@@ -0,0 +1,24 @@
<?php
namespace Chill\ActivityBundle\Notification;
use Chill\MainBundle\Entity\Notification;
use Chill\ActivityBundle\Entity\Activity;
final class ActivityNotificationRenderer
{
public function supports(Notification $notification, array $options = []): bool
{
return $notification->getRelatedEntityClass() == Activity::class;
}
public function getTemplate()
{
return '@ChillActivity/Activity/showInNotification.html.twig';
}
public function getTemplateData(Notification $notification)
{
return ['notification' => $notification];
}
}

View File

@@ -0,0 +1,4 @@
{{ dump(notification) }}
<a href="{{ path('chill_activity_activity_show', {'id': notification.relatedEntityId }) }}">Go to Activity</a>

View File

@@ -0,0 +1,4 @@
services:
Chill\ActivityBundle\Notification\ActivityNotificationRenderer:
autoconfigure: true
autowire: true

View File

@@ -0,0 +1,59 @@
<?php
namespace Chill\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Chill\MainBundle\Repository\NotificationRepository;
use Chill\MainBundle\Notification\NotificationRenderer;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\Annotation\Route;
use Chill\MainBundle\Pagination\PaginatorFactory;
/**
* @Route("/{_locale}/notification")
*/
class NotificationController extends AbstractController
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
/**
* @Route("/show", name="chill_main_notification_show")
*/
public function showAction(
NotificationRepository $notificationRepository, NotificationRenderer $notificationRenderer,
PaginatorFactory $paginatorFactory)
{
$currentUser = $this->security->getUser();
$notificationsNbr = $notificationRepository->countAllForAttendee(($currentUser));
$paginator = $paginatorFactory->create($notificationsNbr);
$notifications = $notificationRepository->findAllForAttendee(
$currentUser,
$limit=$paginator->getItemsPerPage(),
$offset= $paginator->getCurrentPage()->getFirstItemNumber());
$templateData = array();
foreach ($notifications as $notification) {
$data = [
'template' => $notificationRenderer->getTemplate($notification),
'template_data' => $notificationRenderer->getTemplateData($notification),
'notification' => $notification
];
$templateData[] = $data;
}
return $this->render('@ChillMain/Notification/show.html.twig', [
'datas' => $templateData,
'notifications' => $notifications,
'paginator' => $paginator,
]);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Chill\MainBundle\Notification;
use Chill\MainBundle\Entity\Notification;
use Chill\PersonBundle\Notification\AccompanyingPeriodNotificationRenderer;
use Chill\ActivityBundle\Notification\ActivityNotificationRenderer;
final class NotificationRenderer
{
private array $renderers;
public function __construct(
AccompanyingPeriodNotificationRenderer $accompanyingPeriodNotificationRenderer,
ActivityNotificationRenderer $activityNotificationRenderer)
{
// TODO configure automatically
// TODO CREER UNE INTERFACE POUR ETRE SUR QUE LES RENDERERS SONT OK
$this->renderers[] = $accompanyingPeriodNotificationRenderer;
$this->renderers[] = $activityNotificationRenderer;
}
private function getRenderer(Notification $notification)
{
foreach ($this->renderers as $renderer) {
if($renderer->supports($notification)) {
return $renderer;
}
}
throw new \Exception('No renderer for '. $notification);
}
public function getTemplate(Notification $notification)
{
return $this->getRenderer($notification)->getTemplate();
}
public function getTemplateData(Notification $notification)
{
return $this->getRenderer($notification)->getTemplateData($notification);
}
}

View File

@@ -23,6 +23,8 @@ use Chill\MainBundle\Entity\Notification;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\ObjectRepository;
use Chill\MainBundle\Entity\User;
use Doctrine\ORM\Query;
final class NotificationRepository implements ObjectRepository final class NotificationRepository implements ObjectRepository
{ {
@@ -59,8 +61,54 @@ final class NotificationRepository implements ObjectRepository
return $this->repository->findBy($criteria, $orderBy, $limit, $offset); return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
} }
private function queryAllForAttendee(User $addressee, bool $countQuery=False): Query
{
$qb = $this->repository->createQueryBuilder('n');
$select = 'n';
if($countQuery) {
$select = 'count(n)';
}
$qb
->select($select)
->join('n.addressees', 'a')
->where('a = :addressee')
->setParameter('addressee', $addressee);
return $qb->getQuery();
}
/**
* @return int
*/
public function countAllForAttendee(User $addressee): int // TODO passer à attendees avec S
{
$query = $this->queryAllForAttendee($addressee, $countQuery=True);
return $query->getSingleScalarResult();
}
/**
* @return Notification[]
*/
public function findAllForAttendee(User $addressee, $limit = null, $offset = null): array // TODO passer à attendees avec S
{
$query = $this->queryAllForAttendee($addressee);
if($limit) {
$query = $query->setMaxResults($limit);
}
if($offset) {
$query = $query->setFirstResult($offset);
}
return $query->getResult();
}
public function getClassName() { public function getClassName() {
return Notification::class; return Notification::class;
} }
} }

View File

@@ -0,0 +1,42 @@
{% extends "@ChillMain/layout.html.twig" %}
{% block content %}
<div id="container content">
<div class="grid-8 centered">
<h1>{{ "Notifications list" | trans }}</h1>
<!-- TODO : UNREAD & READ -->
{%for data in datas %}
{% set notification = data.notification %}
<dl class="chill_view_data">
<dt class="inline">{{ 'Message'|trans }}</dt>
<dd>{{ notification.message }}</dd>
</dl>
<dl class="chill_view_data">
<dt class="inline">{{ 'Date'|trans }}</dt>
<dd>{{ notification.date | date('long') }}</dd>
</dl>
<dl class="chill_view_data">
<dt class="inline">{{ 'Sender'|trans }}</dt>
<dd>{{ notification.sender }}</dd>
</dl>
<dl class="chill_view_data">
<dt class="inline">{{ 'Addressees'|trans }}</dt>
<dd>{{ notification.addressees |join(', ') }}</dd>
</dl>
<dl class="chill_view_data">
<dt class="inline">{{ 'Entity'|trans }}</dt>
<dd>
{% include data.template with data.template_data %}
</dd>
</dl>
{% endfor %}
</div>
</div>
{% endblock content %}

View File

@@ -34,6 +34,10 @@ chill_password_recover:
resource: "@ChillMainBundle/config/routes/password_recover.yaml" resource: "@ChillMainBundle/config/routes/password_recover.yaml"
prefix: "public/{_locale}/password" prefix: "public/{_locale}/password"
chill_main_notification:
resource: "@ChillMainBundle/config/routes/notification.yaml"
prefix: "{_locale}/notification"
chill_crud: chill_crud:
resource: "@ChillMainBundle" resource: "@ChillMainBundle"
type: CRUD type: CRUD

View File

@@ -33,3 +33,8 @@ services:
$logger: '@Psr\Log\LoggerInterface' $logger: '@Psr\Log\LoggerInterface'
$validator: '@Symfony\Component\Validator\Validator\ValidatorInterface' $validator: '@Symfony\Component\Validator\Validator\ValidatorInterface'
tags: ['controller.service_arguments'] tags: ['controller.service_arguments']
Chill\MainBundle\Controller\NotificationController:
arguments:
$security: '@Symfony\Component\Security\Core\Security'
tags: ['controller.service_arguments']

View File

@@ -4,7 +4,11 @@ services:
$logger: '@Psr\Log\LoggerInterface' $logger: '@Psr\Log\LoggerInterface'
$twig: '@Twig\Environment' $twig: '@Twig\Environment'
$mailer: '@swiftmailer.mailer.default' $mailer: '@swiftmailer.mailer.default'
# $mailerTransporter: '@swiftmailer.transport' # $mailerTransporter: '@swiftmailer.transport'
$router: '@Symfony\Component\Routing\RouterInterface' $router: '@Symfony\Component\Routing\RouterInterface'
$translator: '@Symfony\Component\Translation\TranslatorInterface' $translator: '@Symfony\Component\Translation\TranslatorInterface'
$routeParameters: '%chill_main.notifications%' $routeParameters: '%chill_main.notifications%'
Chill\MainBundle\Notification\NotificationRenderer:
autoconfigure: true
autowire: true

View File

@@ -2,13 +2,15 @@ services:
chill_main.paginator_factory: chill_main.paginator_factory:
class: Chill\MainBundle\Pagination\PaginatorFactory class: Chill\MainBundle\Pagination\PaginatorFactory
public: true public: true
autowire: true
autoconfigure: true
arguments: arguments:
- "@request_stack" - "@request_stack"
- "@router" - "@router"
- "%chill_main.pagination.item_per_page%" - "%chill_main.pagination.item_per_page%"
Chill\MainBundle\Pagination\PaginatorFactory: '@chill_main.paginator_factory' Chill\MainBundle\Pagination\PaginatorFactory: '@chill_main.paginator_factory'
chill_main.paginator.twig_extensions: chill_main.paginator.twig_extensions:
class: Chill\MainBundle\Pagination\ChillPaginationTwig class: Chill\MainBundle\Pagination\ChillPaginationTwig
tags: tags:

View File

@@ -0,0 +1,39 @@
<?php
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;
use Chill\PersonBundle\DataFixtures\ORM\LoadAccompanyingPeriod;
/**
* Load notififications into database
*/
class LoadAccompanyingPeriodNotifications extends AbstractFixture implements DependentFixtureInterface
{
use LoadAbstractNotificationsTrait;
public $notifs = [
[
'message' => 'Hello !',
'entityClass' => AccompanyingPeriod::class,
'entityRef' => LoadAccompanyingPeriod::ACCOMPANYING_PERIOD,
'sender' => 'center a_social',
'addressees' => [
'center a_social',
'center a_administrative',
'center a_direction',
'multi_center'
],
]
];
public function getDependencies()
{
return [
LoadAccompanyingPeriod::class,
];
}
}

View File

@@ -74,6 +74,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader->load('services/form.yaml'); $loader->load('services/form.yaml');
$loader->load('services/alt_names.yaml'); $loader->load('services/alt_names.yaml');
$loader->load('services/household.yaml'); $loader->load('services/household.yaml');
$loader->load('services/notification.yaml');
// We can get rid of this file when the service 'chill.person.repository.person' is no more used. // We can get rid of this file when the service 'chill.person.repository.person' is no more used.
// We should use the PersonRepository service instead of a custom service name. // We should use the PersonRepository service instead of a custom service name.
$loader->load('services/repository.yaml'); $loader->load('services/repository.yaml');
@@ -201,7 +202,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'workflows' => [ 'workflows' => [
'accompanying_period_lifecycle' => [ 'accompanying_period_lifecycle' => [
'type' => 'state_machine', 'type' => 'state_machine',
'audit_trail' => [ 'audit_trail' => [
'enabled' => true 'enabled' => true
], ],
'marking_store' => [ 'marking_store' => [
@@ -354,15 +355,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class, 'controller' => \Chill\PersonBundle\Controller\AccompanyingCourseApiController::class,
'actions' => [ 'actions' => [
'_entity' => [ '_entity' => [
'roles' => [ 'roles' => [
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_PATCH => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_PATCH => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_PUT => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_PUT => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
], ],
'methods' => [ 'methods' => [
Request::METHOD_GET => true, Request::METHOD_GET => true,
Request::METHOD_PUT => true, Request::METHOD_PUT => true,
Request::METHOD_PATCH => true, Request::METHOD_PATCH => true,
] ]
], ],
'participation' => [ 'participation' => [
@@ -379,61 +380,61 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
], ],
'resource' => [ 'resource' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_DELETE => true, Request::METHOD_DELETE => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
] ]
], ],
'comment' => [ 'comment' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_DELETE => true, Request::METHOD_DELETE => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
] ]
], ],
'requestor' => [ 'requestor' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_DELETE => true, Request::METHOD_DELETE => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
] ]
], ],
'scope' => [ 'scope' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_DELETE => true, Request::METHOD_DELETE => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
] ]
], ],
'socialissue' => [ 'socialissue' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_DELETE => true, Request::METHOD_DELETE => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'controller_action' => 'socialIssueApi', 'controller_action' => 'socialIssueApi',
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
] ]
@@ -441,11 +442,11 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'confirm' => [ 'confirm' => [
'methods' => [ 'methods' => [
Request::METHOD_POST => true, Request::METHOD_POST => true,
Request::METHOD_GET => false, Request::METHOD_GET => false,
Request::METHOD_HEAD => false, Request::METHOD_HEAD => false,
], ],
'roles' => [ 'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE, Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
] ]
], ],

View File

@@ -0,0 +1,24 @@
<?php
namespace Chill\PersonBundle\Notification;
use Chill\MainBundle\Entity\Notification;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
final class AccompanyingPeriodNotificationRenderer
{
public function supports(Notification $notification)
{
return $notification->getRelatedEntityClass() == AccompanyingPeriod::class;
}
public function getTemplate()
{
return 'ChillPersonBundle:AccompanyingPeriod:showInNotification.html.twig';
}
public function getTemplateData(Notification $notification)
{
return ['notification' => $notification];
}
}

View File

@@ -0,0 +1,3 @@
<a href="{{ path('chill_person_accompanying_course_index', {'accompanying_period_id': notification.relatedEntityId }) }}">
Go to Acc. period.
</a>

View File

@@ -0,0 +1,3 @@
services:
Chill\PersonBundle\Notification\AccompanyingPeriodNotificationRenderer:
autowire: true