* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\PersonBundle\Widget; use Chill\MainBundle\Templating\Widget\WidgetInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\Expr; use Doctrine\DBAL\Types\Type; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Symfony\Component\Security\Core\Role\Role; use Doctrine\ORM\EntityManager; use Chill\CustomFieldsBundle\Entity\CustomField; use Twig\Environment; /** * add a widget with person list. * * The configuration is defined by `PersonListWidgetFactory` * * If the options 'custom_fields' is used, the custom fields entity will be * queried from the db and transmitted to the view under the `customFields` variable. */ class PersonListWidget implements WidgetInterface { /** * Repository for persons * * @var EntityRepository */ protected $personRepository; /** * The entity manager * * @var EntityManager */ protected $entityManager; /** * the authorization helper * * @var AuthorizationHelper; */ protected $authorizationHelper; /** * * @var TokenStorage */ protected $tokenStorage; /** * * @var UserInterface */ protected $user; public function __construct( EntityRepository $personRepostory, EntityManager $em, AuthorizationHelper $authorizationHelper, TokenStorage $tokenStorage ) { $this->personRepository = $personRepostory; $this->authorizationHelper = $authorizationHelper; $this->tokenStorage = $tokenStorage; $this->entityManager = $em; } /** * * @param type $place * @param array $context * @param array $config * @return string */ public function render(Environment $env, $place, array $context, array $config) { $numberOfItems = $config['number_of_items'] ?? 20; $qb = $this->personRepository ->createQueryBuilder('person'); // show only the person from the authorized centers $and = $qb->expr()->andX(); $centers = $this->authorizationHelper ->getReachableCenters($this->getUser(), new Role(PersonVoter::SEE)); $and->add($qb->expr()->in('person.center', ':centers')); $qb->setParameter('centers', $centers); // add the "only active" query if (\array_key_exists('only_active', $config) && $config['only_active'] === true) { $qb->join('person.accompanyingPeriods', 'ap'); $or = new Expr\Orx(); // add the case where closingDate IS NULL $andWhenClosingDateIsNull = new Expr\Andx(); $andWhenClosingDateIsNull->add((new Expr())->isNull('ap.closingDate')); $andWhenClosingDateIsNull->add((new Expr())->gte(':now', 'ap.openingDate')); $or->add($andWhenClosingDateIsNull); // add the case when closingDate is in the future $or->add( (new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate') ); $and->add($or); $qb->setParameter('now', new \DateTime(), Type::DATE); } if (\array_key_exists('filtering_class', $config) && $config['filtering_class'] !== NULL) { $filteringClass = new $config['filtering_class']; if ( ! $filteringClass instanceof PersonListWidget\PersonFilteringInterface) { throw new \UnexpectedValueException(sprintf("the class %s does not " . "implements %s", $config['filtering_class'], PersonListWidget\PersonFilteringInterface::class)); } $ids = $filteringClass->getPersonIds($this->entityManager, $this->getUser()); $in = (new Expr())->in('person.id', ':ids'); $and->add($in); $qb->setParameter('ids', $ids); } // adding the where clause to the query $qb->where($and); // ordering the query by lastname, firstname $qb->addOrderBy('person.lastName', 'ASC') ->addOrderBy('person.firstName', 'ASC'); $qb->setFirstResult(0)->setMaxResults($numberOfItems); $persons = $qb->getQuery()->getResult(); // get some custom field when the view is overriden and we want to // show some custom field in the overriden view. $cfields = array(); if (isset($config['custom_fields'])) { if (count($config['custom_fields']) > 0) { $cfs = $this->entityManager ->getRepository('ChillCustomFieldsBundle:CustomField') ->findBy(array('slug' => $config['custom_fields'])); // store the custom fields in a array foreach($cfs as $cf) { $cfields[$cf->getSlug()] = $cf; } } } return $env->render( 'ChillPersonBundle:Widget:homepage_person_list.html.twig', array( 'persons' => $persons, 'customFields' => $cfields ) ); } /** * * @return UserInterface * @throws \RuntimeException */ private function getUser() { $token = $this->tokenStorage->getToken(); if ($token === null) { throw new \RuntimeException("the token should not be null"); } $user = $token->getUser(); if (!$user instanceof UserInterface || $user == null) { throw new \RuntimeException("the user should implement UserInterface. " . "Are you logged in ?"); } return $user; } }