diff --git a/.gitignore b/.gitignore
index f1b94a9ff..f69dfba9b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ parameters.yml
Resources/node_modules/
Tests/Fixtures/App/app/config/parameters.yml
+/nbproject/private/
\ No newline at end of file
diff --git a/DependencyInjection/ChillPersonExtension.php b/DependencyInjection/ChillPersonExtension.php
index 253948399..925aa940e 100644
--- a/DependencyInjection/ChillPersonExtension.php
+++ b/DependencyInjection/ChillPersonExtension.php
@@ -89,6 +89,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
public function prepend(ContainerBuilder $container)
{
$this->prependRoleHierarchy($container);
+ $this->prependHomepageWidget($container);
$bundles = $container->getParameter('kernel.bundles');
//add ChillMain to assetic-enabled bundles
@@ -125,6 +126,31 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
));
}
+ /**
+ *
+ * Add a widget "add a person" on the homepage, automatically
+ *
+ * @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
+ */
+ protected function prependHomepageWidget(containerBuilder $container)
+ {
+ $container->prependExtensionConfig('chill_main', array(
+ 'widgets' => array(
+ 'homepage' => array(
+ array(
+ 'widget_alias' => 'add_person',
+ 'order' => 2
+ )
+ )
+ )
+ ));
+ }
+
+ /**
+ * Add role hierarchy.
+ *
+ * @param ContainerBuilder $container
+ */
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml
index 7566c0e98..e377cf36c 100644
--- a/Resources/config/routing.yml
+++ b/Resources/config/routing.yml
@@ -20,9 +20,6 @@ chill_person_new:
defaults: {_controller: ChillPersonBundle:Person:new }
options:
menus:
- homepage:
- order: 10
- label: Add a person
section:
order: 10
label: Add a person
diff --git a/Resources/config/services/widgets.yml b/Resources/config/services/widgets.yml
index 9d0f126ae..7ea920cc2 100644
--- a/Resources/config/services/widgets.yml
+++ b/Resources/config/services/widgets.yml
@@ -3,11 +3,12 @@ services:
class: Chill\PersonBundle\Widget\PersonListWidget
arguments:
- "@chill.person.repository.person"
+ - "@doctrine.orm.entity_manager"
- "@chill.main.security.authorization.helper"
- "@security.token_storage"
# this widget is defined by the PersonListWidgetFactory
chill_person.widget.add_person:
- class: Chill\PersonBundle\Widget\AddPersonWidget
+ class: Chill\PersonBundle\Widget\AddAPersonWidget
tags:
- { name: chill_widget, alias: add_person, place: homepage }
\ No newline at end of file
diff --git a/Resources/views/Widget/homepage_add_a_person.html.twig b/Resources/views/Widget/homepage_add_a_person.html.twig
new file mode 100644
index 000000000..6bdbbff04
--- /dev/null
+++ b/Resources/views/Widget/homepage_add_a_person.html.twig
@@ -0,0 +1,8 @@
+
+
diff --git a/Widget/AddAPersonWidget.php b/Widget/AddAPersonWidget.php
new file mode 100644
index 000000000..a7988ed2a
--- /dev/null
+++ b/Widget/AddAPersonWidget.php
@@ -0,0 +1,28 @@
+render("ChillPersonBundle:Widget:homepage_add_a_person.html.twig");
+ }
+}
diff --git a/Widget/PersonListWidget.php b/Widget/PersonListWidget.php
index 46a4a5361..18e55a017 100644
--- a/Widget/PersonListWidget.php
+++ b/Widget/PersonListWidget.php
@@ -28,6 +28,7 @@ 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;
/**
* add a widget with person list.
@@ -44,6 +45,13 @@ class PersonListWidget implements WidgetInterface
*/
protected $personRepository;
+ /**
+ * The entity manager
+ *
+ * @var EntityManager
+ */
+ protected $entityManager;
+
/**
* the authorization helper
*
@@ -65,13 +73,14 @@ class PersonListWidget implements WidgetInterface
public function __construct(
EntityRepository $personRepostory,
+ EntityManager $em,
AuthorizationHelper $authorizationHelper,
TokenStorage $tokenStorage
) {
$this->personRepository = $personRepostory;
$this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage;
-
+ $this->entityManager = $em;
}
/**
@@ -94,7 +103,7 @@ class PersonListWidget implements WidgetInterface
$qb->setParameter('centers', $centers);
-
+ // add the "only active" query
if ($config['only_active'] === true) {
$qb->join('person.accompanyingPeriods', 'ap');
$or = new Expr\Orx();
@@ -110,6 +119,23 @@ class PersonListWidget implements WidgetInterface
$and->add($or);
$qb->setParameter('now', new \DateTime(), Type::DATE);
}
+
+
+ if ($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);
diff --git a/Widget/PersonListWidget/PersonFilteringInterface.php b/Widget/PersonListWidget/PersonFilteringInterface.php
new file mode 100644
index 000000000..555884cc1
--- /dev/null
+++ b/Widget/PersonListWidget/PersonFilteringInterface.php
@@ -0,0 +1,85 @@
+
+ *
+ * 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\PersonListWidget;
+
+use Doctrine\ORM\EntityManager;
+use Chill\MainBundle\Entity\User;
+
+
+/**
+ * Interface to implement on classes called in configuration for
+ * PersonListWidget (`person_list`), under the key `filtering_class` :
+ *
+ * ```
+ * widgets:
+ * homepage:
+ * person_list:
+ * # where \FQDN\To\Class implements PersonFiltering
+ * class_filtering: \FQDN\To\Class
+ * ```
+ *
+ */
+interface PersonFilteringInterface
+{
+ /**
+ * Return an array of persons id to show.
+ *
+ * Those ids are inserted into the query like this (where ids is the array
+ * returned by this class) :
+ *
+ * ```
+ * SELECT p FROM ChillPersonBundle:Persons p
+ * WHERE p.id IN (:ids)
+ * AND
+ * -- security/authorization statement: restraint person to authorized centers
+ * p.center in :authorized_centers
+ * ```
+ *
+ * Example of use : filtering based on custom field data :
+ * ```
+
+ class HomepagePersonFiltering implements PersonFilteringInterface {
+
+ public function getPersonIds(EntityManager $em, User $user)
+ {
+ $rsmBuilder = new ResultSetMappingBuilder($em);
+ $rsmBuilder->addScalarResult('id', 'id', Type::BIGINT);
+
+ $personTable = $em->getClassMetadata('ChillPersonBundle:Person')
+ ->getTableName();
+ $personIdColumn = $em->getClassMetadata('ChillPersonBundle:Person')
+ ->getColumnName('id');
+ $personCfDataColumn = $em->getClassMetadata('ChillPersonBundle:Person')
+ ->getColumnName('cfData');
+
+ return $em->createNativeQuery(sprintf("SELECT %s FROM %s WHERE "
+ . "jsonb_exists(%s, 'school-2fb5440e-192c-11e6-b2fd-74d02b0c9b55')",
+ $personIdColumn, $personTable, $personCfDataColumn), $rsmBuilder)
+ ->getScalarResult();
+ }
+}
+ * ```
+ *
+ * @param EntityManager $em
+ * @return int[] an array of persons id to show
+ */
+ public function getPersonIds(EntityManager $em, User $user);
+}
diff --git a/Widget/PersonListWidgetFactory.php b/Widget/PersonListWidgetFactory.php
index 98933a86d..760764fcb 100644
--- a/Widget/PersonListWidgetFactory.php
+++ b/Widget/PersonListWidgetFactory.php
@@ -19,12 +19,8 @@
namespace Chill\PersonBundle\Widget;
-use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
use Chill\MainBundle\DependencyInjection\Widget\Factory\AbstractWidgetFactory;
-use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Definition;
-use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
/**
@@ -40,6 +36,9 @@ class PersonListWidgetFactory extends AbstractWidgetFactory
$node->integerNode('number_of_items')
->defaultValue(50)
->end();
+ $node->scalarNode('filtering_class')
+ ->defaultNull()
+ ->end();
}