mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-28 17:44:58 +00:00
Compare commits
16 Commits
refactorin
...
dune-risky
Author | SHA1 | Date | |
---|---|---|---|
915a2e7284 | |||
cb99074d1f | |||
cfd9f1bab1 | |||
358410cde1 | |||
06c74ed5ed | |||
25c986cc61 | |||
cad8174333 | |||
75c586fbf8 | |||
2cb9dfc250 | |||
5350a09951 | |||
9b1a66c992 | |||
74541f360b | |||
ea477a9842 | |||
73653744d7 | |||
c3ef8d112c | |||
|
8c98f2cf6e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,8 +1,8 @@
|
||||
.composer/*
|
||||
composer.phar
|
||||
composer.lock
|
||||
|
||||
docs/build/
|
||||
.php_cs.cache
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
@@ -19,3 +19,4 @@ docs/build/
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
"Chill\\EventBundle\\": "src/Bundle/ChillEventBundle",
|
||||
"Chill\\FamilyMemberBundle\\": "src/Bundle/ChillFamilyMemberBundle",
|
||||
"Chill\\MainBundle\\": "src/Bundle/ChillMainBundle",
|
||||
"Chill\\PersonBundle\\": "src/Bundle/ChillPersonBundle/src",
|
||||
"Chill\\PersonBundle\\": "src/Bundle/ChillPersonBundle",
|
||||
"Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle",
|
||||
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
|
||||
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle"
|
||||
|
@@ -97,7 +97,7 @@ The has the following signature :
|
||||
*
|
||||
* @param string $context
|
||||
* @param mixed[] $args the argument to the context.
|
||||
* @return string[]
|
||||
* @return TimelineSingleQuery
|
||||
* @throw \LogicException if the context is not supported
|
||||
*/
|
||||
public function fetchQuery($context, array $args);
|
||||
@@ -163,18 +163,16 @@ The has the following signature :
|
||||
The `fetchQuery` function
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The fetchQuery function help to build the UNION query to gather events. This function should return an associative array MUST have the following key :
|
||||
The fetchQuery function help to build the UNION query to gather events. This function should return an instance of :code:`TimelineSingleQuery`. For you convenience, this object may be build using an associative array with the following keys:
|
||||
|
||||
* `id` : the name of the id column
|
||||
* `type`: a string to indicate the type
|
||||
* `date`: the name of the datetime column, used to order entities by date
|
||||
* `FROM` (in capital) : the FROM clause. May contains JOIN instructions
|
||||
* `FROM`: the FROM clause. May contains JOIN instructions
|
||||
* `WHERE`: the WHERE clause;
|
||||
* `parameters`: the parameters to pass to the query
|
||||
|
||||
Those key are optional:
|
||||
|
||||
* `WHERE` (in capital) : the WHERE clause.
|
||||
|
||||
Where relevant, the data must be quoted to avoid SQL injection.
|
||||
The parameters should be replaced into the query by :code:`?`. They will be replaced into the query using prepared statements.
|
||||
|
||||
`$context` and `$args` are defined by the bundle which will call the timeline rendering. You may use them to build a different query depending on this context.
|
||||
|
||||
@@ -186,6 +184,15 @@ For instance, if the context is `'person'`, the args will be this array :
|
||||
'person' => $person //a \Chill\PersonBundle\Entity\Person entity
|
||||
);
|
||||
|
||||
For the context :code:`center`, the args will be:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
array(
|
||||
'centers' => [ ] // an array of \Chill\MainBundle\Entity\Center entities
|
||||
);
|
||||
|
||||
|
||||
You should find in the bundle documentation which contexts are arguments the bundle defines.
|
||||
|
||||
.. note::
|
||||
@@ -199,13 +206,12 @@ Example of an implementation :
|
||||
namespace Chill\ReportBundle\Timeline;
|
||||
|
||||
use Chill\MainBundle\Timeline\TimelineProviderInterface;
|
||||
use Chill\MainBundle\Timeline\TimelineSingleQuery;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* Provide report for inclusion in timeline
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @author Champs Libres <info@champs-libres.coop>
|
||||
*/
|
||||
class TimelineReportProvider implements TimelineProviderInterface
|
||||
{
|
||||
@@ -227,16 +233,17 @@ Example of an implementation :
|
||||
|
||||
$metadata = $this->em->getClassMetadata('ChillReportBundle:Report');
|
||||
|
||||
return array(
|
||||
return TimelineSingleQuery::fromArray([
|
||||
'id' => $metadata->getColumnName('id'),
|
||||
'type' => 'report',
|
||||
'date' => $metadata->getColumnName('date'),
|
||||
'FROM' => $metadata->getTableName(),
|
||||
'WHERE' => sprintf('%s = %d',
|
||||
'WHERE' => sprintf('%s = ?',
|
||||
$metadata
|
||||
->getAssociationMapping('person')['joinColumns'][0]['name'],
|
||||
$args['person']->getId())
|
||||
);
|
||||
->getAssociationMapping('person')['joinColumns'][0]['name'])
|
||||
)
|
||||
'parameters' => [ $args['person']->getId() ]
|
||||
]);
|
||||
}
|
||||
|
||||
//....
|
||||
|
@@ -38,7 +38,7 @@ use Chill\MainBundle\Validator\Constraints\Entity\UserCircleConsistency;
|
||||
* Class Activity
|
||||
*
|
||||
* @package Chill\ActivityBundle\Entity
|
||||
* @ORM\Entity()
|
||||
* @ORM\Entity(repositoryClass="Chill\ActivityBundle\Repository\ActivityRepository")
|
||||
* @ORM\Table(name="activity")
|
||||
* @ORM\HasLifecycleCallbacks()
|
||||
* @UserCircleConsistency(
|
||||
|
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
|
||||
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\ActivityBundle\Repository;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ActivityBundle\Repository\ActivityRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Query\Expr\Orx;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
|
||||
final class ActivityACLAwareRepository
|
||||
{
|
||||
private AuthorizationHelper $authorizationHelper;
|
||||
|
||||
private TokenStorageInterface $tokenStorage;
|
||||
|
||||
private ActivityRepository $repository;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationHelper $authorizationHelper,
|
||||
TokenStorageInterface $tokenStorage,
|
||||
ActivityRepository $repository,
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
$this->repository = $repository;
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function queryTimelineIndexer(string $context, array $args = []): array
|
||||
{
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
|
||||
$from = $this->getFromClauseCenter($args);
|
||||
[$where, $parameters] = $this->getWhereClause($context, $args);
|
||||
|
||||
return [
|
||||
'id' => $metadataActivity->getTableName()
|
||||
.'.'.$metadataActivity->getColumnName('id'),
|
||||
'type' => 'activity',
|
||||
'date' => $metadataActivity->getTableName()
|
||||
.'.'.$metadataActivity->getColumnName('date'),
|
||||
'FROM' => $from,
|
||||
'WHERE' => $where,
|
||||
'parameters' => $parameters
|
||||
];
|
||||
}
|
||||
|
||||
private function getFromClauseCenter(array $args): string
|
||||
{
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
$metadataPerson = $this->em->getClassMetadata(Person::class);
|
||||
$associationMapping = $metadataActivity->getAssociationMapping('person');
|
||||
|
||||
return $metadataActivity->getTableName().' JOIN '
|
||||
.$metadataPerson->getTableName().' ON '
|
||||
.$metadataPerson->getTableName().'.'.
|
||||
$associationMapping['joinColumns'][0]['referencedColumnName']
|
||||
.' = '
|
||||
.$associationMapping['joinColumns'][0]['name']
|
||||
;
|
||||
}
|
||||
|
||||
private function getWhereClause(string $context, array $args): array
|
||||
{
|
||||
$where = '';
|
||||
$parameters = [];
|
||||
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
$metadataPerson = $this->em->getClassMetadata(Person::class);
|
||||
$activityToPerson = $metadataActivity->getAssociationMapping('person')['joinColumns'][0]['name'];
|
||||
$activityToScope = $metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'];
|
||||
$personToCenter = $metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'];
|
||||
|
||||
|
||||
// acls:
|
||||
$role = new Role(ActivityVoter::SEE);
|
||||
$reachableCenters = $this->authorizationHelper->getReachableCenters($this->tokenStorage->getToken()->getUser(),
|
||||
$role);
|
||||
|
||||
if (count($reachableCenters) === 0) {
|
||||
// insert a dummy condition
|
||||
return 'FALSE = TRUE';
|
||||
}
|
||||
|
||||
if ($context === 'person') {
|
||||
// we start with activities having the person_id linked to person
|
||||
$where .= sprintf('%s = ? AND ', $activityToPerson);
|
||||
$parameters[] = $person->getId();
|
||||
}
|
||||
|
||||
// we add acl (reachable center and scopes)
|
||||
$where .= '('; // first loop for the for centers
|
||||
$centersI = 0; // like centers#i
|
||||
foreach ($reachableCenters as $center) {
|
||||
// we pass if not in centers
|
||||
if (!\in_array($center, $args['centers'])) {
|
||||
continue;
|
||||
}
|
||||
// we get all the reachable scopes for this center
|
||||
$reachableScopes = $this->authorizationHelper->getReachableScopes($this->tokenStorage->getToken()->getUser(), $role, $center);
|
||||
// we get the ids for those scopes
|
||||
$reachablesScopesId = array_map(
|
||||
function(Scope $scope) { return $scope->getId(); },
|
||||
$reachableScopes
|
||||
);
|
||||
|
||||
// if not the first center
|
||||
if ($centersI > 0) {
|
||||
$where .= ') OR (';
|
||||
}
|
||||
|
||||
// condition for the center
|
||||
$where .= sprintf(' %s.%s = ? ', $metadataPerson->getTableName(), $personToCenter);
|
||||
$parameters[] = $center->getId();
|
||||
|
||||
// begin loop for scopes
|
||||
$where .= ' AND (';
|
||||
$scopesI = 0; //like scope#i
|
||||
|
||||
foreach ($reachablesScopesId as $scopeId) {
|
||||
if ($scopesI > 0) {
|
||||
$where .= ' OR ';
|
||||
}
|
||||
$where .= sprintf(' %s.%s = ? ', $metadataActivity->getTableName(), $activityToScope);
|
||||
$parameters[] = $scopeId;
|
||||
$scopesI ++;
|
||||
}
|
||||
// close loop for scopes
|
||||
$where .= ') ';
|
||||
$centersI++;
|
||||
}
|
||||
// close loop for centers
|
||||
$where .= ')';
|
||||
|
||||
return [$where, $parameters];
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
|
||||
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\ActivityBundle\Repository;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method AccompanyingPeriodParticipation|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method AccompanyingPeriodParticipation|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method AccompanyingPeriodParticipation[] findAll()
|
||||
* @method AccompanyingPeriodParticipation[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ActivityRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Activity::class);
|
||||
}
|
||||
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %}
|
||||
|
||||
<div>
|
||||
<h3>{{ activity.date|format_date('long') }}<span class="activity"> / {{ 'Activity'|trans }}</span></h3>
|
||||
<h3>{{ activity.date|format_date('long') }}<span class="activity"> / {{ 'Activity'|trans }}</span>{% if 'person' != context %} / {{ activity.person|chill_entity_render_box({'addLink': true}) }}{% endif %}</h3>
|
||||
<div class="statement">
|
||||
<span class="statement">{{ '%user% has done an %activity_type%'|trans(
|
||||
{
|
||||
'%user%' : user,
|
||||
'%user%' : activity.user,
|
||||
'%activity_type%': activity.type.name|localize_translatable_string,
|
||||
'%date%' : activity.date|format_date('long') }
|
||||
) }}</span>
|
||||
@@ -29,13 +29,13 @@
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('chill_activity_activity_show', { 'person_id': person.id, 'id': activity.id} ) }}" class="sc-button bt-view">
|
||||
<a href="{{ path('chill_activity_activity_show', { 'person_id': activity.person.id, 'id': activity.id} ) }}" class="sc-button bt-view">
|
||||
{{ 'Show the activity'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_ACTIVITY_UPDATE', activity) %}
|
||||
<li>
|
||||
<a href="{{ path('chill_activity_activity_edit', { 'person_id': person.id, 'id': activity.id} ) }}" class="sc-button bt-edit">
|
||||
<a href="{{ path('chill_activity_activity_edit', { 'person_id': activity.person.id, 'id': activity.id} ) }}" class="sc-button bt-edit">
|
||||
{{ 'Edit the activity'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
namespace Chill\ActivityBundle\Timeline;
|
||||
|
||||
use Chill\MainBundle\Timeline\TimelineProviderInterface;
|
||||
use Chill\ActivityBundle\Repository\ActivityACLAwareRepository;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
@@ -28,13 +29,13 @@ use Symfony\Component\Security\Core\Role\Role;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\MainBundle\Timeline\TimelineSingleQuery;
|
||||
|
||||
/**
|
||||
* Provide activity for inclusion in timeline
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @author Champs Libres <info@champs-libres.coop>
|
||||
*/
|
||||
*/
|
||||
class TimelineActivityProvider implements TimelineProviderInterface
|
||||
{
|
||||
|
||||
@@ -56,6 +57,10 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
protected ActivityACLAwareRepository $aclAwareRepository;
|
||||
|
||||
private const SUPPORTED_CONTEXTS = [ 'center', 'person'];
|
||||
|
||||
/**
|
||||
* TimelineActivityProvider constructor.
|
||||
*
|
||||
@@ -66,11 +71,13 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
public function __construct(
|
||||
EntityManager $em,
|
||||
AuthorizationHelper $helper,
|
||||
TokenStorageInterface $storage
|
||||
TokenStorageInterface $storage,
|
||||
ActivityACLAwareRepository $aclAwareRepository
|
||||
)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->helper = $helper;
|
||||
$this->aclAwareRepository = $aclAwareRepository;
|
||||
|
||||
if (!$storage->getToken()->getUser() instanceof \Chill\MainBundle\Entity\User)
|
||||
{
|
||||
@@ -86,67 +93,69 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
*/
|
||||
public function fetchQuery($context, array $args)
|
||||
{
|
||||
$this->checkContext($context);
|
||||
if ('center' === $context) {
|
||||
return TimelineSingleQuery::fromArray($this->aclAwareRepository
|
||||
->queryTimelineIndexer($context, $args));
|
||||
}
|
||||
|
||||
$metadataActivity = $this->em->getClassMetadata('ChillActivityBundle:Activity');
|
||||
$metadataPerson = $this->em->getClassMetadata('ChillPersonBundle:Person');
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
|
||||
return array(
|
||||
[$where, $parameters] = $this->getWhereClauseForPerson($args['person']);
|
||||
|
||||
return TimelineSingleQuery::fromArray([
|
||||
'id' => $metadataActivity->getTableName()
|
||||
.'.'.$metadataActivity->getColumnName('id'),
|
||||
'type' => 'activity',
|
||||
'date' => $metadataActivity->getTableName()
|
||||
.'.'.$metadataActivity->getColumnName('date'),
|
||||
'FROM' => $this->getFromClause($metadataActivity, $metadataPerson),
|
||||
'WHERE' => $this->getWhereClause($metadataActivity, $metadataPerson,
|
||||
$args['person'])
|
||||
);
|
||||
'FROM' => $this->getFromClausePerson($args['person']),
|
||||
'WHERE' => $where,
|
||||
'parameters' => $parameters
|
||||
]);
|
||||
}
|
||||
|
||||
private function getWhereClause(ClassMetadata $metadataActivity,
|
||||
ClassMetadata $metadataPerson, Person $person)
|
||||
private function getWhereClauseForPerson(Person $person)
|
||||
{
|
||||
$role = new Role('CHILL_ACTIVITY_SEE');
|
||||
$reachableCenters = $this->helper->getReachableCenters($this->user,
|
||||
$role);
|
||||
$parameters = [];
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
$associationMapping = $metadataActivity->getAssociationMapping('person');
|
||||
$role = new Role('CHILL_ACTIVITY_SEE');
|
||||
$reachableScopes = $this->helper->getReachableScopes($this->user,
|
||||
$role, $person->getCenter());
|
||||
$whereClause = sprintf(' {activity.person_id} = ? AND {activity.scope_id} IN ({scopes_ids}) ');
|
||||
$scopes_ids = [];
|
||||
|
||||
if (count($reachableCenters) === 0) {
|
||||
return 'FALSE = TRUE';
|
||||
// first parameter: activity.person_id
|
||||
$parameters[] = $person->getId();
|
||||
|
||||
// loop on reachable scopes
|
||||
foreach ($reachableScopes as $scope) {
|
||||
if (\in_array($scope->getId(), $scopes_ids)) {
|
||||
continue;
|
||||
}
|
||||
$scopes_ids[] = '?';
|
||||
$parameters[] = $scope->getId();
|
||||
}
|
||||
|
||||
// we start with activities having the person_id linked to person
|
||||
// (currently only context "person" is supported)
|
||||
$whereClause = sprintf('%s = %d',
|
||||
$associationMapping['joinColumns'][0]['name'],
|
||||
$person->getId());
|
||||
|
||||
// we add acl (reachable center and scopes)
|
||||
$centerAndScopeLines = array();
|
||||
foreach ($reachableCenters as $center) {
|
||||
$reachablesScopesId = array_map(
|
||||
function(Scope $scope) { return $scope->getId(); },
|
||||
$this->helper->getReachableScopes($this->user, $role,
|
||||
$person->getCenter())
|
||||
);
|
||||
|
||||
$centerAndScopeLines[] = sprintf('(%s = %d AND %s IN (%s))',
|
||||
$metadataPerson->getTableName().'.'.
|
||||
$metadataPerson->getAssociationMapping('center')['joinColumns'][0]['name'],
|
||||
$center->getId(),
|
||||
$metadataActivity->getTableName().'.'.
|
||||
return [
|
||||
\strtr(
|
||||
$whereClause,
|
||||
[
|
||||
'{activity.person_id}' => $associationMapping['joinColumns'][0]['name'],
|
||||
'{activity.scope_id}' => $metadataActivity->getTableName().'.'.
|
||||
$metadataActivity->getAssociationMapping('scope')['joinColumns'][0]['name'],
|
||||
implode(',', $reachablesScopesId));
|
||||
|
||||
}
|
||||
$whereClause .= ' AND ('.implode(' OR ', $centerAndScopeLines).')';
|
||||
|
||||
return $whereClause;
|
||||
'{scopes_ids}' => \implode(", ", $scopes_ids)
|
||||
,
|
||||
]
|
||||
),
|
||||
$parameters
|
||||
];
|
||||
}
|
||||
|
||||
private function getFromClause(ClassMetadata $metadataActivity,
|
||||
ClassMetadata $metadataPerson)
|
||||
private function getFromClausePerson()
|
||||
{
|
||||
$metadataActivity = $this->em->getClassMetadata(Activity::class);
|
||||
$metadataPerson = $this->em->getClassMetadata(Person::class);
|
||||
$associationMapping = $metadataActivity->getAssociationMapping('person');
|
||||
|
||||
return $metadataActivity->getTableName().' JOIN '
|
||||
@@ -164,7 +173,7 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
*/
|
||||
public function getEntities(array $ids)
|
||||
{
|
||||
$activities = $this->em->getRepository('ChillActivityBundle:Activity')
|
||||
$activities = $this->em->getRepository(Activity::class)
|
||||
->findBy(array('id' => $ids));
|
||||
|
||||
$result = array();
|
||||
@@ -183,14 +192,13 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
{
|
||||
$this->checkContext($context);
|
||||
|
||||
return array(
|
||||
return [
|
||||
'template' => 'ChillActivityBundle:Timeline:activity_person_context.html.twig',
|
||||
'template_data' => array(
|
||||
'template_data' => [
|
||||
'activity' => $entity,
|
||||
'person' => $args['person'],
|
||||
'user' => $entity->getUser()
|
||||
)
|
||||
);
|
||||
'context' => $context
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +218,7 @@ class TimelineActivityProvider implements TimelineProviderInterface
|
||||
*/
|
||||
private function checkContext($context)
|
||||
{
|
||||
if ($context !== 'person') {
|
||||
if (FALSE === \in_array($context, self::SUPPORTED_CONTEXTS)) {
|
||||
throw new \LogicException("The context '$context' is not "
|
||||
. "supported. Currently only 'person' is supported");
|
||||
}
|
||||
|
@@ -22,6 +22,8 @@ services:
|
||||
- '@doctrine.orm.entity_manager'
|
||||
- '@chill.main.security.authorization.helper'
|
||||
- '@security.token_storage'
|
||||
- '@Chill\ActivityBundle\Repository\ActivityACLAwareRepository'
|
||||
public: true
|
||||
tags:
|
||||
- { name: chill.timeline, context: 'person' }
|
||||
- { name: chill.timeline, context: 'center' }
|
||||
|
@@ -1,3 +1,4 @@
|
||||
---
|
||||
services:
|
||||
chill_activity.repository.activity_type:
|
||||
class: Doctrine\ORM\EntityRepository
|
||||
@@ -16,3 +17,16 @@ services:
|
||||
factory: ['@doctrine.orm.entity_manager', getRepository]
|
||||
arguments:
|
||||
- 'Chill\ActivityBundle\Entity\ActivityReasonCategory'
|
||||
|
||||
Chill\ActivityBundle\Repository\ActivityRepository:
|
||||
tags: [doctrine.repository_service]
|
||||
arguments:
|
||||
- '@Doctrine\Persistence\ManagerRegistry'
|
||||
|
||||
Chill\ActivityBundle\Repository\ActivityACLAwareRepository:
|
||||
arguments:
|
||||
$tokenStorage: '@Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'
|
||||
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
|
||||
$repository: '@Chill\ActivityBundle\Repository\ActivityRepository'
|
||||
$em: '@Doctrine\ORM\EntityManagerInterface'
|
||||
|
||||
|
@@ -22,13 +22,12 @@ class ChoiceWithOtherType extends AbstractType
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
|
||||
//add an 'other' entry in choices array
|
||||
$options['choices'][$this->otherValueLabel] = '_other';
|
||||
//ChoiceWithOther must always be expanded
|
||||
$options['expanded'] = true;
|
||||
// adding a default value for choice
|
||||
$options['empty_data'] = null;
|
||||
$options['empty_data'] = $options['multiple'] ? [] : null;
|
||||
|
||||
$builder
|
||||
->add('_other', TextType::class, array('required' => false))
|
||||
|
@@ -23,6 +23,7 @@ namespace Chill\EventBundle\Timeline;
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Timeline\TimelineProviderInterface;
|
||||
use Chill\MainBundle\Timeline\TimelineSingleQuery;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
@@ -88,13 +89,14 @@ class TimelineEventProvider implements TimelineProviderInterface
|
||||
$metadataParticipation = $this->em->getClassMetadata('ChillEventBundle:Participation');
|
||||
$metadataPerson = $this->em->getClassMetadata('ChillPersonBundle:Person');
|
||||
|
||||
$query = array(
|
||||
$query = TimelineSingleQuery::fromArray([
|
||||
'id' => $metadataEvent->getTableName().'.'.$metadataEvent->getColumnName('id'),
|
||||
'type' => 'event',
|
||||
'date' => $metadataEvent->getTableName().'.'.$metadataEvent->getColumnName('date'),
|
||||
'FROM' => $this->getFromClause($metadataEvent, $metadataParticipation, $metadataPerson),
|
||||
'WHERE' => $this->getWhereClause($metadataEvent, $metadataParticipation, $metadataPerson, $args['person'])
|
||||
);
|
||||
'WHERE' => $this->getWhereClause($metadataEvent, $metadataParticipation, $metadataPerson, $args['person']),
|
||||
'parameters' => []
|
||||
]);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Chill\MainBundle\Timeline\TimelineBuilder;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class TimelineCenterController extends AbstractController
|
||||
{
|
||||
|
||||
protected TimelineBuilder $timelineBuilder;
|
||||
|
||||
protected PaginatorFactory $paginatorFactory;
|
||||
|
||||
private Security $security;
|
||||
|
||||
public function __construct(
|
||||
TimelineBuilder $timelineBuilder,
|
||||
PaginatorFactory $paginatorFactory,
|
||||
Security $security
|
||||
) {
|
||||
$this->timelineBuilder = $timelineBuilder;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/center/timeline",
|
||||
* name="chill_center_timeline",
|
||||
* methods={"GET"}
|
||||
* )
|
||||
*/
|
||||
public function centerAction(Request $request)
|
||||
{
|
||||
// collect reachable center for each group
|
||||
$user = $this->security->getUser();
|
||||
$centers = [];
|
||||
foreach ($user->getGroupCenters() as $group) {
|
||||
$centers[] = $group->getCenter();
|
||||
}
|
||||
|
||||
if (0 === count($centers)) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$nbItems = $this->timelineBuilder->countItems('center',
|
||||
[ 'centers' => $centers ]
|
||||
);
|
||||
|
||||
$paginator = $this->paginatorFactory->create($nbItems);
|
||||
|
||||
return $this->render('@ChillMain/Timeline/index.html.twig', array
|
||||
(
|
||||
'timeline' => $this->timelineBuilder->getTimelineHTML(
|
||||
'center',
|
||||
[ 'centers' => $centers ],
|
||||
$paginator->getCurrentPage()->getFirstItemNumber(),
|
||||
$paginator->getItemsPerPage()
|
||||
),
|
||||
'nb_items' => $nbItems,
|
||||
'paginator' => $paginator
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
<div class="timeline">
|
||||
{% for result in results %}
|
||||
<div class="timeline-item {% if loop.index0 is even %}even{% else %}odd{% endif %}">
|
||||
{% include result.template with result.template_data %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
@@ -1,7 +1,15 @@
|
||||
<div class="timeline">
|
||||
{% for result in results %}
|
||||
<div class="timeline-item {% if loop.index0 is even %}even{% else %}odd{% endif %}">
|
||||
{% include result.template with result.template_data %}
|
||||
{% extends "@ChillMain/layout.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div id="container content">
|
||||
<div class="grid-8 centered">
|
||||
<h1>{{ 'Global timeline'|trans }}</h1>
|
||||
|
||||
{{ timeline|raw }}
|
||||
|
||||
{% if nb_items > paginator.getItemsPerPage %}
|
||||
{{ chill_pagination(paginator) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
@@ -69,6 +69,14 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||
'order' => 0
|
||||
]);
|
||||
|
||||
$menu->addChild($this->translator->trans('Global timeline'), [
|
||||
'route' => 'chill_center_timeline',
|
||||
])
|
||||
->setExtras([
|
||||
'order' => 10
|
||||
]
|
||||
);
|
||||
|
||||
if ($this->authorizationChecker->isGranted(ChillExportVoter::EXPORT)) {
|
||||
$menu->addChild($this->translator->trans('Export Menu'), [
|
||||
'route' => 'chill_main_export_index'
|
||||
|
@@ -38,7 +38,7 @@ use Chill\MainBundle\Entity\RoleScope;
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
class AuthorizationHelper
|
||||
{
|
||||
/**
|
||||
*
|
||||
@@ -110,8 +110,6 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
$role = ($attribute instanceof Role) ? $attribute : new Role($attribute);
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
//filter on center
|
||||
if ($groupCenter->getCenter()->getId() === $entity->getCenter()->getId()) {
|
||||
@@ -119,8 +117,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role allow to reach the required role
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))){
|
||||
if ($this->isRoleReached($attribute, $roleScope->getRole())) {
|
||||
//if yes, we have a right on something...
|
||||
// perform check on scope if necessary
|
||||
if ($entity instanceof HasScopeInterface) {
|
||||
@@ -149,12 +146,15 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
* and optionnaly Scope
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param string|Role $role
|
||||
* @param null|Scope $scope
|
||||
* @return Center[]
|
||||
*/
|
||||
public function getReachableCenters(User $user, Role $role, Scope $scope = null)
|
||||
public function getReachableCenters(User $user, $role, Scope $scope = null)
|
||||
{
|
||||
if ($role instanceof Role) {
|
||||
$role = $role->getRole();
|
||||
}
|
||||
$centers = array();
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
@@ -162,8 +162,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role is in the reachable roles
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))) {
|
||||
if ($this->isRoleReached($role, $roleScope->getRole())) {
|
||||
if ($scope === null) {
|
||||
$centers[] = $groupCenter->getCenter();
|
||||
break 1;
|
||||
@@ -181,6 +180,30 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
return $centers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter an array of centers, return only center which are reachable
|
||||
*
|
||||
* @param User $user The user
|
||||
* @param array $centers a list of centers which are going to be filtered
|
||||
* @param string|Center $role
|
||||
*/
|
||||
public function filterReachableCenters(User $user, array $centers, $role): array
|
||||
{
|
||||
$results = [];
|
||||
|
||||
if ($role instanceof Role) {
|
||||
$role = $role->getRole();
|
||||
}
|
||||
|
||||
foreach ($centers as $center) {
|
||||
if ($this->userCanReachCenter($user, $center, $role)) {
|
||||
$results[] = $center;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all reachable scope for a given user, center and role
|
||||
*
|
||||
@@ -191,8 +214,12 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
* @param Center $center
|
||||
* @return Scope[]
|
||||
*/
|
||||
public function getReachableScopes(User $user, Role $role, Center $center)
|
||||
public function getReachableScopes(User $user, $role, Center $center)
|
||||
{
|
||||
if ($role instanceof Role) {
|
||||
$role = $role->getRole();
|
||||
}
|
||||
|
||||
return $this->getReachableCircles($user, $role, $center);
|
||||
}
|
||||
|
||||
@@ -200,12 +227,15 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
* Return all reachable circle for a given user, center and role
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param string|Role $role
|
||||
* @param Center $center
|
||||
* @return Scope[]
|
||||
*/
|
||||
public function getReachableCircles(User $user, Role $role, Center $center)
|
||||
public function getReachableCircles(User $user, $role, Center $center)
|
||||
{
|
||||
if ($role instanceof Role) {
|
||||
$role = $role->getRole();
|
||||
}
|
||||
$scopes = array();
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
@@ -215,9 +245,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role is in the reachable roles
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))) {
|
||||
|
||||
if ($this->isRoleReached($role, $roleScope->getRole())) {
|
||||
$scopes[] = $roleScope->getScope();
|
||||
}
|
||||
}
|
||||
@@ -269,10 +297,10 @@ class AuthorizationHelper implements AuthorizationHelperInterface
|
||||
* @param Role $parentRole The role which should give access to $childRole
|
||||
* @return boolean true if the child role is granted by parent role
|
||||
*/
|
||||
protected function isRoleReached(Role $childRole, Role $parentRole)
|
||||
protected function isRoleReached($childRole, $parentRole)
|
||||
{
|
||||
$reachableRoles = $this->roleHierarchy
|
||||
->getReachableRoles([$parentRole]);
|
||||
->getReachableRoleNames([$parentRole]);
|
||||
|
||||
return in_array($childRole, $reachableRoles);
|
||||
}
|
||||
|
@@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
|
||||
interface AuthorizationHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Determines if a user is active on this center
|
||||
*
|
||||
* @param User $user
|
||||
* @param Center $center
|
||||
* @return bool
|
||||
*/
|
||||
public function userCanReachCenter(User $user, Center $center);
|
||||
|
||||
/**
|
||||
*
|
||||
* Determines if the user has access to the given entity.
|
||||
*
|
||||
* if the entity implements Chill\MainBundle\Entity\HasScopeInterface,
|
||||
* the scope is taken into account.
|
||||
*
|
||||
* @param User $user
|
||||
* @param HasCenterInterface $entity the entity may also implement HasScopeInterface
|
||||
* @param string|Role $attribute
|
||||
* @return boolean true if the user has access
|
||||
*/
|
||||
public function userHasAccess(User $user, HasCenterInterface $entity, $attribute);
|
||||
|
||||
/**
|
||||
* Get reachable Centers for the given user, role,
|
||||
* and optionnaly Scope
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param null|Scope $scope
|
||||
* @return Center[]
|
||||
*/
|
||||
public function getReachableCenters(User $user, Role $role, Scope $scope = null);
|
||||
|
||||
/**
|
||||
* Return all reachable scope for a given user, center and role
|
||||
*
|
||||
* @deprecated Use getReachableCircles
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @return Scope[]
|
||||
*/
|
||||
public function getReachableScopes(User $user, Role $role, Center $center);
|
||||
|
||||
/**
|
||||
* Return all reachable circle for a given user, center and role
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @return Scope[]
|
||||
*/
|
||||
public function getReachableCircles(User $user, Role $role, Center $center);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @param Scope $circle
|
||||
* @return Users
|
||||
*/
|
||||
public function findUsersReaching(Role $role, Center $center, Scope $circle = null);
|
||||
|
||||
/**
|
||||
* Return all the role which give access to the given role. Only the role
|
||||
* which are registered into Chill are taken into account.
|
||||
*
|
||||
* @param Role $role
|
||||
* @return Role[] the role which give access to the given $role
|
||||
*/
|
||||
public function getParentRoles(Role $role);
|
||||
}
|
@@ -28,7 +28,7 @@ use Twig\TwigFilter;
|
||||
*
|
||||
* @package Chill\MainBundle\Templating\Entity
|
||||
*/
|
||||
class ChillEntityRenderExtension extends AbstractExtension implements ChillEntityRenderExtensionInterface
|
||||
class ChillEntityRenderExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @var ChillEntityRenderInterface
|
||||
|
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Templating\Entity;
|
||||
|
||||
use Twig\Extension\ExtensionInterface;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
interface ChillEntityRenderExtensionInterface extends ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @return array|TwigFilter[]
|
||||
*/
|
||||
public function getFilters();
|
||||
|
||||
/**
|
||||
* @param $entity
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function renderString($entity, array $options = []): string;
|
||||
|
||||
/**
|
||||
* @param $entity
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function renderBox($entity, array $options = []): string;
|
||||
|
||||
/**
|
||||
* @param ChillEntityRenderInterface $render
|
||||
*/
|
||||
public function addRender(ChillEntityRenderInterface $render);
|
||||
}
|
@@ -29,7 +29,7 @@ use Symfony\Component\Translation\Translator;
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
*/
|
||||
class TranslatableStringHelper implements TranslatableStringHelperInterface
|
||||
class TranslatableStringHelper
|
||||
{
|
||||
/**
|
||||
*
|
||||
|
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Templating;
|
||||
|
||||
interface TranslatableStringHelperInterface
|
||||
{
|
||||
/**
|
||||
* return the string in current locale if it exists.
|
||||
*
|
||||
* If it does not exists; return the name in the first language available.
|
||||
*
|
||||
* Return a blank string if any strings are available.
|
||||
* Return NULL if $translatableString is NULL
|
||||
*
|
||||
* @param array $translatableStrings
|
||||
* @return string
|
||||
*/
|
||||
public function localize(array $translatableStrings);
|
||||
}
|
@@ -23,13 +23,13 @@ use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\NativeQuery;
|
||||
|
||||
/**
|
||||
* Build timeline
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterface
|
||||
class TimelineBuilder implements ContainerAwareInterface
|
||||
{
|
||||
|
||||
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
@@ -78,14 +78,14 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
*/
|
||||
public function getTimelineHTML($context, array $args, $firstItem = 0, $number = 20)
|
||||
{
|
||||
$union = $this->buildUnionQuery($context, $args);
|
||||
list($union, $parameters) = $this->buildUnionQuery($context, $args);
|
||||
|
||||
//add ORDER BY clause and LIMIT
|
||||
$query = $union . sprintf(' ORDER BY date DESC LIMIT %d OFFSET %d',
|
||||
$number, $firstItem);
|
||||
|
||||
// run query and handle results
|
||||
$fetched = $this->runUnionQuery($query);
|
||||
$fetched = $this->runUnionQuery($query, $parameters);
|
||||
$entitiesByKey = $this->getEntities($fetched, $context);
|
||||
|
||||
return $this->render($fetched, $entitiesByKey, $context, $args);
|
||||
@@ -100,16 +100,18 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
*/
|
||||
public function countItems($context, array $args)
|
||||
{
|
||||
$union = $this->buildUnionQuery($context, $args);
|
||||
|
||||
// embed the union query inside a count query
|
||||
$count = sprintf('SELECT COUNT(sq.id) AS total FROM (%s) as sq', $union);
|
||||
|
||||
$rsm = (new ResultSetMapping())
|
||||
->addScalarResult('total', 'total', Type::INTEGER);
|
||||
|
||||
return $this->em->createNativeQuery($count, $rsm)
|
||||
->getSingleScalarResult();
|
||||
list($select, $parameters) = $this->buildUnionQuery($context, $args);
|
||||
|
||||
// embed the union query inside a count query
|
||||
$countQuery = sprintf('SELECT COUNT(sq.id) AS total FROM (%s) as sq', $select);
|
||||
|
||||
$nq = $this->em->createNativeQuery($countQuery, $rsm);
|
||||
$nq->setParameters($parameters);
|
||||
|
||||
return $nq->getSingleScalarResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,40 +156,59 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
*
|
||||
* @uses self::buildSelectQuery to build individual SELECT queries
|
||||
*
|
||||
* @param string $context
|
||||
* @param mixed $args
|
||||
* @param int $page
|
||||
* @param int $number
|
||||
* @return string
|
||||
* @throws \LogicException if no builder have been defined for this context
|
||||
* @return array, where first element is the query, the second one an array with the parameters
|
||||
*/
|
||||
private function buildUnionQuery($context, array $args)
|
||||
private function buildUnionQuery(string $context, array $args): array
|
||||
{
|
||||
//append SELECT queries with UNION keyword between them
|
||||
$union = '';
|
||||
$parameters = [];
|
||||
|
||||
foreach($this->getProvidersByContext($context) as $provider) {
|
||||
$select = $this->buildSelectQuery($provider, $context, $args);
|
||||
$append = ($union === '') ? $select : ' UNION '.$select;
|
||||
$data = $provider->fetchQuery($context, $args);
|
||||
list($select, $selectParameters) = $this->buildSelectQuery($data);
|
||||
$append = empty($union) ? $select : ' UNION '.$select;
|
||||
$union .= $append;
|
||||
$parameters = array_merge($parameters, $selectParameters);
|
||||
}
|
||||
|
||||
return $union;
|
||||
return [$union, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack to replace the arbitrary "AS" statement in DQL
|
||||
* into proper SQL query
|
||||
* TODO remove
|
||||
private function replaceASInDQL(string $dql): string
|
||||
{
|
||||
$pattern = '/^(SELECT\s+[a-zA-Z0-9\_\.\']{1,}\s+)(AS [a-z0-9\_]{1,})(\s{0,},\s{0,}[a-zA-Z0-9\_\.\']{1,}\s+)(AS [a-z0-9\_]{1,})(\s{0,},\s{0,}[a-zA-Z0-9\_\.\']{1,}\s+)(AS [a-z0-9\_]{1,})(\s+FROM.*)/';
|
||||
$replacements = '${1} AS id ${3} AS type ${5} AS date ${7}';
|
||||
|
||||
$s = \preg_replace($pattern, $replacements, $dql, 1);
|
||||
|
||||
if (NULL === $s) {
|
||||
throw new \RuntimeException('Could not replace the "AS" statement produced by '.
|
||||
'DQL with normal SQL AS: '.$dql);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* return the SQL SELECT query as a string,
|
||||
*
|
||||
* @uses TimelineProfiderInterface::fetchQuery use the fetchQuery function
|
||||
* @param \Chill\MainBundle\Timeline\TimelineProviderInterface $provider
|
||||
* @param string $context
|
||||
* @param mixed[] $args
|
||||
* @return string
|
||||
* @return array: first parameter is the sql string, second an array with parameters
|
||||
*/
|
||||
private function buildSelectQuery(TimelineProviderInterface $provider, $context, array $args)
|
||||
private function buildSelectQuery($data): array
|
||||
{
|
||||
$data = $provider->fetchQuery($context, $args);
|
||||
return [$data->buildSql(), $data->getParameters()];
|
||||
|
||||
return sprintf(
|
||||
// dead code
|
||||
$parameters = [];
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT %s AS id, '
|
||||
. '%s AS "date", '
|
||||
. "'%s' AS type "
|
||||
@@ -197,16 +218,19 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
$data['date'],
|
||||
$data['type'],
|
||||
$data['FROM'],
|
||||
$data['WHERE']);
|
||||
is_string($data['WHERE']) ? $data['WHERE'] : $data['WHERE'][0]
|
||||
);
|
||||
|
||||
return [$sql, $data['WHERE'][1]];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* run the UNION query and return result as an array
|
||||
*
|
||||
* @param string $query
|
||||
* @return array
|
||||
* @return array an array with the results
|
||||
*/
|
||||
private function runUnionQuery($query)
|
||||
private function runUnionQuery(string $query, array $parameters): array
|
||||
{
|
||||
$resultSetMapping = (new ResultSetMapping())
|
||||
->addScalarResult('id', 'id')
|
||||
@@ -214,6 +238,7 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
->addScalarResult('date', 'date');
|
||||
|
||||
return $this->em->createNativeQuery($query, $resultSetMapping)
|
||||
->setParameters($parameters)
|
||||
->getArrayResult();
|
||||
}
|
||||
|
||||
@@ -274,7 +299,7 @@ class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterfa
|
||||
}
|
||||
|
||||
return $this->container->get('templating')
|
||||
->render('@ChillMain/Timeline/index.html.twig', array(
|
||||
->render('@ChillMain/Timeline/chain_timelines.html.twig', array(
|
||||
'results' => $timelineEntries
|
||||
));
|
||||
|
||||
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Timeline;
|
||||
|
||||
interface TimelineBuilderInterface
|
||||
{
|
||||
}
|
155
src/Bundle/ChillMainBundle/Timeline/TimelineSingleQuery.php
Normal file
155
src/Bundle/ChillMainBundle/Timeline/TimelineSingleQuery.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Timeline;
|
||||
|
||||
|
||||
class TimelineSingleQuery
|
||||
{
|
||||
private ?string $id;
|
||||
|
||||
private ?string $date;
|
||||
|
||||
private ?string $key;
|
||||
|
||||
private ?string $from;
|
||||
|
||||
private ?string $where;
|
||||
|
||||
private array $parameters = [];
|
||||
|
||||
private bool $distinct = false;
|
||||
|
||||
public function __construct(
|
||||
string $id = null,
|
||||
string $date = null,
|
||||
string $key = null,
|
||||
string $from = null,
|
||||
string $where = null,
|
||||
array $parameters = []
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->date = $date;
|
||||
$this->key = $key;
|
||||
$this->from = $from;
|
||||
$this->where = $where;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
public static function fromArray(array $a)
|
||||
{
|
||||
return new TimelineSingleQuery(
|
||||
$a['id'] ?? null,
|
||||
$a['date'] ?? null,
|
||||
$a['type'] ?? $a['key'] ?? null,
|
||||
$a['FROM'] ?? $a['from'] ?? null,
|
||||
$a['WHERE'] ?? $a['where'] ?? null,
|
||||
$a['parameters'] ?? null);
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(string $id): self
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDate(): string
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function setDate(string $date): self
|
||||
{
|
||||
$this->date = $date;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function setKey(string $key): self
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFrom(): string
|
||||
{
|
||||
return $this->from;
|
||||
}
|
||||
|
||||
public function setFrom(string $from): self
|
||||
{
|
||||
$this->from = $from;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWhere(): string
|
||||
{
|
||||
return $this->where;
|
||||
}
|
||||
|
||||
public function setWhere(string $where): self
|
||||
{
|
||||
$this->where = $where;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
public function setParameters(array $parameters): self
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDistinct(bool $distinct): self
|
||||
{
|
||||
$this->distinct = $distinct;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isDistinct(): bool
|
||||
{
|
||||
return $this->distinct;
|
||||
}
|
||||
|
||||
public function buildSql(): string
|
||||
{
|
||||
$parameters = [];
|
||||
|
||||
$sql = \strtr(
|
||||
'SELECT {distinct} {id} AS id, '
|
||||
. '{date} AS "date", '
|
||||
. "'{key}' AS type "
|
||||
. 'FROM {from} '
|
||||
. 'WHERE {where}',
|
||||
[
|
||||
'{distinct}' => $this->distinct ? 'DISTINCT' : '',
|
||||
'{id}' => $this->getId(),
|
||||
'{date}' => $this->getDate(),
|
||||
'{key}' => $this->getKey(),
|
||||
'{from}' => $this->getFrom(),
|
||||
'{where}' => $this->getWhere(),
|
||||
]
|
||||
);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
@@ -1,3 +1,7 @@
|
||||
chill_main_controllers:
|
||||
resource: '../Controller/'
|
||||
type: annotation
|
||||
|
||||
chill_main_admin_permissionsgroup:
|
||||
resource: "@ChillMainBundle/config/routes/permissionsgroup.yaml"
|
||||
prefix: "{_locale}/admin/permissionsgroup"
|
||||
|
@@ -10,7 +10,6 @@ services:
|
||||
- "@translator.default"
|
||||
|
||||
Chill\MainBundle\Templating\TranslatableStringHelper: '@chill.main.helper.translatable_string'
|
||||
Chill\MainBundle\Templating\TranslatableStringHelperInterface: Chill\MainBundle\Templating\TranslatableStringHelper
|
||||
|
||||
chill.main.twig.translatable_string:
|
||||
class: Chill\MainBundle\Templating\TranslatableStringTwig
|
||||
|
@@ -6,7 +6,6 @@ services:
|
||||
$hierarchy: "%security.role_hierarchy.roles%"
|
||||
$em: '@Doctrine\ORM\EntityManagerInterface'
|
||||
Chill\MainBundle\Security\Authorization\AuthorizationHelper: '@chill.main.security.authorization.helper'
|
||||
Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface: Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
||||
|
||||
chill.main.role_provider:
|
||||
class: Chill\MainBundle\Security\RoleProvider
|
||||
|
@@ -30,7 +30,6 @@ services:
|
||||
Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension:
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
Chill\MainBundle\Templating\Entity\ChillEntityRenderExtensionInterface: Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension
|
||||
|
||||
Chill\MainBundle\Templating\Entity\CommentRender:
|
||||
arguments:
|
||||
|
@@ -5,5 +5,6 @@ services:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
calls:
|
||||
- [ setContainer, ["@service_container"]]
|
||||
# alias:
|
||||
Chill\MainBundle\Timeline\TimelineBuilder: '@chill_main.timeline_builder'
|
||||
|
||||
Chill\MainBundle\Timeline\TimelineBuilderInterface: "@chill_main.timeline_builder"
|
||||
|
@@ -46,6 +46,11 @@ Back to the list: Retour à la liste
|
||||
#interval
|
||||
Years: Années
|
||||
|
||||
# misc date
|
||||
Since %date%: Depuis le %date%
|
||||
since %date%: depuis le %date%
|
||||
Until %date%: Jusqu'au %date%
|
||||
until %date%: jusqu'au %date%
|
||||
#elements used in software
|
||||
centers: centres
|
||||
Centers: Centres
|
||||
@@ -78,6 +83,9 @@ Results %start%-%end% of %total%: Résultats %start%-%end% sur %total%
|
||||
See all results: Voir tous les résultats
|
||||
Advanced search: Recherche avancée
|
||||
|
||||
# timeline
|
||||
Global timeline: Historique global
|
||||
|
||||
#admin
|
||||
Create: Créer
|
||||
show: voir
|
||||
|
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
namespace Chill\PersonBundle\Actions;
|
||||
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Event triggered when an entity attached to a person is removed.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ActionEvent implements Event
|
||||
class ActionEvent extends Event
|
||||
{
|
||||
const DELETE = 'CHILL_PERSON.DELETE_ASSOCIATED_ENTITY';
|
||||
const MOVE = 'CHILL_PERSON.MOVE_ASSOCIATED_ENTITY';
|
@@ -40,7 +40,6 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\Form\FormFactory;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
|
||||
/**
|
||||
* Class ImportPeopleFromCSVCommand
|
||||
@@ -131,7 +130,7 @@ class ImportPeopleFromCSVCommand extends Command
|
||||
protected static $defaultDateInterpreter = "%d/%m/%Y|%e/%m/%y|%d/%m/%Y|%e/%m/%Y";
|
||||
|
||||
/**
|
||||
* @var FormFactoryInterface
|
||||
* @var FormFactory
|
||||
*/
|
||||
protected $formFactory;
|
||||
|
||||
@@ -143,7 +142,7 @@ class ImportPeopleFromCSVCommand extends Command
|
||||
* @param EntityManagerInterface $em
|
||||
* @param CustomFieldProvider $customFieldProvider
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
* @param FormFactoryInterface $formFactory
|
||||
* @param FormFactory $formFactory
|
||||
*/
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
@@ -151,7 +150,7 @@ class ImportPeopleFromCSVCommand extends Command
|
||||
EntityManagerInterface $em,
|
||||
CustomFieldProvider $customFieldProvider,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
FormFactoryInterface $formFactory
|
||||
FormFactory $formFactory
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->helper = $helper;
|
@@ -8,7 +8,7 @@ namespace Chill\PersonBundle\Config;
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ConfigPersonAltNamesHelper implements ConfigPersonAltNamesHelperInterface
|
||||
class ConfigPersonAltNamesHelper
|
||||
{
|
||||
/**
|
||||
* the raw config, directly from the container parameter
|
@@ -26,7 +26,7 @@ use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Form\Type\AccompanyingPeriodType;
|
||||
use Chill\PersonBundle\Form\AccompanyingPeriodType;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
@@ -65,12 +65,6 @@ class AccompanyingPeriodController extends AbstractController
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_list",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period"
|
||||
* )
|
||||
*/
|
||||
public function listAction(int $person_id): Response
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
@@ -87,12 +81,6 @@ class AccompanyingPeriodController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_create",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period/create"
|
||||
* )
|
||||
*/
|
||||
public function createAction(int $person_id, Request $request): Response
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
@@ -151,10 +139,7 @@ class AccompanyingPeriodController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_update",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period/{period_id}/update"
|
||||
* )
|
||||
* @throws Exception
|
||||
*/
|
||||
public function updateAction(int $person_id, int $period_id, Request $request): Response
|
||||
{
|
||||
@@ -221,10 +206,7 @@ class AccompanyingPeriodController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_close",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period/close"
|
||||
* )
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function closeAction(int $person_id, Request $request): Response
|
||||
{
|
||||
@@ -326,12 +308,6 @@ class AccompanyingPeriodController extends AbstractController
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_open",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period/open"
|
||||
* )
|
||||
*/
|
||||
public function openAction(int $person_id, Request $request): Response
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
@@ -409,12 +385,6 @@ class AccompanyingPeriodController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_accompanying_period_re_open",
|
||||
* path="/{_locale}/person/{person_id}/accompanying-period/re-open"
|
||||
* )
|
||||
*/
|
||||
public function reOpenAction(int $person_id, int $period_id, Request $request): Response
|
||||
{
|
||||
/** @var Person $person */
|
@@ -13,10 +13,8 @@ use Symfony\Component\Routing\Annotation\Route;
|
||||
class AdminController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_admin",
|
||||
* path="/{_locale}/admin/person"
|
||||
* )
|
||||
* @param $_locale
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction($_locale)
|
||||
{
|
||||
@@ -24,18 +22,7 @@ class AdminController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_admin_redirect_to_admin_index",
|
||||
* path="/{_locale}/admin/person_redirect_to_main",
|
||||
* options={
|
||||
* menus={
|
||||
* admin_person={
|
||||
* order="0",
|
||||
* label="Main admin menu"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
||||
*/
|
||||
public function redirectToAdminIndexAction()
|
||||
{
|
@@ -30,7 +30,6 @@ use Chill\MainBundle\Entity\Address;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* Class PersonAddressController
|
||||
@@ -57,12 +56,6 @@ class PersonAddressController extends AbstractController
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_address_list",
|
||||
* path="/{_locale}/person/{person_id}/address/list"
|
||||
* )
|
||||
*/
|
||||
public function listAction($person_id)
|
||||
{
|
||||
$person = $this->getDoctrine()->getManager()
|
||||
@@ -85,13 +78,6 @@ class PersonAddressController extends AbstractController
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_address_create",
|
||||
* path="/{_locale}/person/{person_id}/address/create",
|
||||
* methods={"POST"}
|
||||
* )
|
||||
*/
|
||||
public function newAction($person_id)
|
||||
{
|
||||
$person = $this->getDoctrine()->getManager()
|
||||
@@ -119,12 +105,6 @@ class PersonAddressController extends AbstractController
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_address_new",
|
||||
* path="/{_locale}/person/{person_id}/address/new"
|
||||
* )
|
||||
*/
|
||||
public function createAction($person_id, Request $request)
|
||||
{
|
||||
$person = $this->getDoctrine()->getManager()
|
||||
@@ -181,12 +161,6 @@ class PersonAddressController extends AbstractController
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_address_edit",
|
||||
* path="/{_locale}/person/{person_id}/address/{address_id}/edit"
|
||||
* )
|
||||
*/
|
||||
public function editAction($person_id, $address_id)
|
||||
{
|
||||
$person = $this->getDoctrine()->getManager()
|
||||
@@ -215,12 +189,6 @@ class PersonAddressController extends AbstractController
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_address_update",
|
||||
* path="/{_locale}/person/{person_id}/address/{address_id}/update"
|
||||
* )
|
||||
*/
|
||||
public function updateAction($person_id, $address_id, Request $request)
|
||||
{
|
||||
$person = $this->getDoctrine()->getManager()
|
@@ -34,14 +34,12 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Chill\PersonBundle\Search\SimilarPersonMatcher;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Chill\MainBundle\Search\SearchProvider;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final class PersonController extends AbstractController
|
||||
{
|
||||
@@ -119,12 +117,6 @@ final class PersonController extends AbstractController
|
||||
return $cFGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_view",
|
||||
* path="/{_locale}/person/{person_id}/general"
|
||||
* )
|
||||
*/
|
||||
public function viewAction($person_id)
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
@@ -148,12 +140,6 @@ final class PersonController extends AbstractController
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_general_edit",
|
||||
* path="/{_locale}/person/{person_id}/general/edit"
|
||||
* )
|
||||
*/
|
||||
public function editAction($person_id)
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
@@ -177,13 +163,7 @@ final class PersonController extends AbstractController
|
||||
array('person' => $person, 'form' => $form->createView()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_general_update",
|
||||
* path="/{_locale}/person/{person_id}/general/update"
|
||||
* )
|
||||
*/
|
||||
public function updateAction($person_id, Request $request, TranslatorInterface $translator)
|
||||
public function updateAction($person_id, Request $request)
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
|
||||
@@ -212,7 +192,7 @@ final class PersonController extends AbstractController
|
||||
|
||||
$this->get('session')->getFlashBag()
|
||||
->add('success',
|
||||
$translator
|
||||
$this->get('translator')
|
||||
->trans('The person data has been updated')
|
||||
);
|
||||
|
||||
@@ -226,12 +206,6 @@ final class PersonController extends AbstractController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_new",
|
||||
* path="/{_locale}/person/new"
|
||||
* )
|
||||
*/
|
||||
public function newAction()
|
||||
{
|
||||
// this is a dummy default center.
|
||||
@@ -316,13 +290,7 @@ final class PersonController extends AbstractController
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_review",
|
||||
* path="/{_locale}/person/review"
|
||||
* )
|
||||
*/
|
||||
public function reviewAction(Request $request, PersonNotDuplicateRepository $personNotDuplicateRepository)
|
||||
public function reviewAction(Request $request)
|
||||
{
|
||||
if ($request->getMethod() !== 'POST') {
|
||||
$r = new Response("You must send something to review the creation of a new Person");
|
||||
@@ -374,7 +342,8 @@ final class PersonController extends AbstractController
|
||||
|
||||
$this->em->persist($person);
|
||||
|
||||
$alternatePersons = $this->similarPersonMatcher->matchPerson($person, $personNotDuplicateRepository);
|
||||
$alternatePersons = $this->similarPersonMatcher
|
||||
->matchPerson($person);
|
||||
|
||||
if (count($alternatePersons) === 0) {
|
||||
return $this->forward('ChillPersonBundle:Person:create');
|
||||
@@ -398,12 +367,6 @@ final class PersonController extends AbstractController
|
||||
'form' => $form->createView()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_create",
|
||||
* path="/{_locale}/person/create"
|
||||
* )
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
|
@@ -12,17 +12,16 @@ use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
use Chill\PersonBundle\Search\SimilarPersonMatcher;
|
||||
use http\Exception\InvalidArgumentException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||
use Chill\EventBundle\Entity\Participation;
|
||||
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
|
||||
use Chill\TaskBundle\Entity\SingleTask;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
||||
class PersonDuplicateController extends AbstractController
|
||||
class PersonDuplicateController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Chill\PersonBundle\Search\SimilarPersonMatcher
|
||||
@@ -63,13 +62,7 @@ class PersonDuplicateController extends AbstractController
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_duplicate_view",
|
||||
* path="/{_locale}/person/{person_id}/duplicate/view"
|
||||
* )
|
||||
*/
|
||||
public function viewAction($person_id, PersonNotDuplicateRepository $personNotDuplicateRepository)
|
||||
public function viewAction($person_id)
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
||||
if ($person === null) {
|
||||
@@ -83,7 +76,8 @@ class PersonDuplicateController extends AbstractController
|
||||
$duplicatePersons = $this->similarPersonMatcher->
|
||||
matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
|
||||
|
||||
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
|
||||
$notDuplicatePersons = $this->getDoctrine()->getRepository(PersonNotDuplicate::class)
|
||||
->findNotDuplicatePerson($person);
|
||||
|
||||
return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
|
||||
'person' => $person,
|
||||
@@ -92,12 +86,6 @@ class PersonDuplicateController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_duplicate_confirm",
|
||||
* path="/{_locale}/person/{person1_id}/duplicate/{person2_id}/confirm"
|
||||
* )
|
||||
*/
|
||||
public function confirmAction($person1_id, $person2_id, Request $request)
|
||||
{
|
||||
if ($person1_id === $person2_id) {
|
||||
@@ -155,12 +143,6 @@ class PersonDuplicateController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_duplicate_not_duplicate",
|
||||
* path="/{_locale}/person/{person1_id}/duplicate/{person2_id}/not-duplicate"
|
||||
* )
|
||||
*/
|
||||
public function notDuplicateAction($person1_id, $person2_id)
|
||||
{
|
||||
[$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id);
|
||||
@@ -184,12 +166,6 @@ class PersonDuplicateController extends AbstractController
|
||||
return $this->redirectToRoute('chill_person_duplicate_view', ['person_id' => $person1->getId()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_remove_duplicate_not_duplicate",
|
||||
* path="/{_locale}/person/{person1_id}/duplicate/{person2_id}/remove-not-duplicate"
|
||||
* )
|
||||
*/
|
||||
public function removeNotDuplicateAction($person1_id, $person2_id)
|
||||
{
|
||||
[$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id);
|
||||
@@ -208,12 +184,6 @@ class PersonDuplicateController extends AbstractController
|
||||
return $this->redirectToRoute('chill_person_duplicate_view', ['person_id' => $person1->getId()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_find_manually_duplicate",
|
||||
* path="/{_locale}/person/{person_id}/find-manually"
|
||||
* )
|
||||
*/
|
||||
public function findManuallyDuplicateAction($person_id, Request $request)
|
||||
{
|
||||
$person = $this->_getPerson($person_id);
|
@@ -26,35 +26,18 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Chill\MainBundle\Timeline\TimelineBuilder;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Timeline\TimelineBuilderInterface;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
/**
|
||||
* Class TimelinePersonController
|
||||
*
|
||||
* @package Chill\PersonBundle\Controller
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class TimelinePersonController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
protected EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var TimelineBuilderInterface
|
||||
*/
|
||||
protected $timelineBuilder;
|
||||
protected TimelineBuilder $timelineBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var PaginatorFactory
|
||||
*/
|
||||
protected $paginatorFactory;
|
||||
protected PaginatorFactory $paginatorFactory;
|
||||
|
||||
/**
|
||||
* TimelinePersonController constructor.
|
||||
@@ -63,28 +46,17 @@ class TimelinePersonController extends AbstractController
|
||||
*/
|
||||
public function __construct(
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
TimelineBuilderInterface $timelineBuilder,
|
||||
PaginatorFactory $paginatorFactory
|
||||
TimelineBuilder $timelineBuilder,
|
||||
PaginatorFactory $paginatorFactory,
|
||||
AuthorizationHelper $authorizationHelper
|
||||
) {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->timelineBuilder = $timelineBuilder;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* name="chill_person_timeline",
|
||||
* path="/{_locale}/person/{person_id}/timeline",
|
||||
* options={
|
||||
* menus={
|
||||
* person={
|
||||
* order="60",
|
||||
* label="Timeline"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
||||
public function personAction(Request $request, $person_id)
|
||||
{
|
||||
$person = $this->getDoctrine()
|
@@ -60,14 +60,20 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
$container->setParameter('chill_person.allow_multiple_simultaneous_accompanying_periods',
|
||||
$config['allow_multiple_simultaneous_accompanying_periods']);
|
||||
|
||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(dirname(__DIR__, 2).'/config'));
|
||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
|
||||
$loader->load('services.yaml');
|
||||
$loader->load('services/widgets.yaml');
|
||||
$loader->load('services/exports.yaml');
|
||||
$loader->load('services/fixtures.yaml');
|
||||
$loader->load('services/controller.yaml');
|
||||
$loader->load('services/search.yaml');
|
||||
$loader->load('services/menu.yaml');
|
||||
$loader->load('services/privacyEvent.yaml');
|
||||
$loader->load('services/command.yaml');
|
||||
$loader->load('services/actions.yaml');
|
||||
$loader->load('services/form.yaml');
|
||||
$loader->load('services/repository.yaml');
|
||||
$loader->load('services/templating.yaml');
|
||||
$loader->load('services/alt_names.yaml');
|
||||
$loader->load('services/serializer.yaml');
|
||||
|
||||
@@ -179,7 +185,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
$container->prependExtensionConfig('chill_main', array(
|
||||
'routing' => array(
|
||||
'resources' => array(
|
||||
dirname(__DIR__, 2) . '/config/routes.yaml'
|
||||
'@ChillPersonBundle/config/routes.yaml'
|
||||
)
|
||||
)
|
||||
));
|
@@ -37,7 +37,7 @@ use Chill\MainBundle\Entity\User;
|
||||
/**
|
||||
* AccompanyingPeriod Class
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriodRepository")
|
||||
* @ORM\Table(name="chill_person_accompanying_period")
|
||||
*/
|
||||
class AccompanyingPeriod
|
||||
@@ -302,13 +302,9 @@ class AccompanyingPeriod
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setRemark(string $remark): self
|
||||
public function setRemark(string $remark = null): self
|
||||
{
|
||||
if ($remark === null) {
|
||||
$remark = '';
|
||||
}
|
||||
|
||||
$this->remark = $remark;
|
||||
$this->remark = (string) $remark;
|
||||
|
||||
return $this;
|
||||
}
|
@@ -4,6 +4,7 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\Result;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
@@ -12,7 +13,7 @@ use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=AccompanyingPeriodWorkRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_work")
|
||||
*/
|
||||
class AccompanyingPeriodWork
|
@@ -4,12 +4,13 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\Goal;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Result;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkGoalRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=AccompanyingPeriodWorkGoalRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_work_goal")
|
||||
*/
|
||||
class AccompanyingPeriodWorkGoal
|
@@ -29,7 +29,8 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
/**
|
||||
* ClosingMotive give an explanation why we closed the Accompanying period
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(
|
||||
* repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository")
|
||||
* @ORM\Table(name="chill_person_accompanying_period_closingmotive")
|
||||
*/
|
||||
class ClosingMotive
|
@@ -22,12 +22,13 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\CommentRepository;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=CommentRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_comment")
|
||||
*/
|
||||
class Comment
|
@@ -22,10 +22,11 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\OriginRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=OriginRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_origin")
|
||||
*/
|
||||
class Origin
|
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
@@ -29,7 +30,7 @@ use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=ResourceRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_resource")
|
||||
*/
|
||||
class Resource
|
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity;
|
||||
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodParticipationRepository;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
@@ -30,7 +31,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
* AccompanyingPeriodParticipation Class
|
||||
*
|
||||
* @package Chill\PersonBundle\Entity
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=AccompanyingPeriodParticipationRepository::class)
|
||||
* @ORM\Table(name="chill_person_accompanying_period_participation")
|
||||
*/
|
||||
class AccompanyingPeriodParticipation
|
@@ -25,7 +25,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
/**
|
||||
* MaritalStatus
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity()
|
||||
* @ORM\Table(name="chill_person_marital_status")
|
||||
* @ORM\HasLifecycleCallbacks()
|
||||
*/
|
@@ -38,7 +38,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
/**
|
||||
* Person Class
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonRepository")
|
||||
* @ORM\Table(name="chill_person_person",
|
||||
* indexes={@ORM\Index(
|
||||
* name="person_names",
|
@@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
* PersonAltName
|
||||
*
|
||||
* @ORM\Table(name="chill_person_alt_name")
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonAltNameRepository")
|
||||
*/
|
||||
class PersonAltName
|
||||
{
|
@@ -9,7 +9,7 @@ use Chill\MainBundle\Entity\User;
|
||||
* PersonNotDuplicate
|
||||
*
|
||||
* @ORM\Table(name="chill_person_not_duplicate")
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonNotDuplicateRepository")
|
||||
*/
|
||||
class PersonNotDuplicate
|
||||
{
|
@@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
/**
|
||||
* Person Phones
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity()
|
||||
* @ORM\Table(name="chill_person_phone")
|
||||
*/
|
||||
class PersonPhone
|
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=EvaluationRepository::class)
|
||||
* @ORM\Table(name="chill_person_social_work_evaluation")
|
||||
*/
|
||||
class Evaluation
|
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=GoalRepository::class)
|
||||
* @ORM\Table(name="chill_person_social_work_goal")
|
||||
*/
|
||||
class Goal
|
@@ -4,12 +4,13 @@ namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
|
||||
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=ResultRepository::class)
|
||||
* @ORM\Table(name="chill_person_social_work_result")
|
||||
*/
|
||||
class Result
|
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=SocialActionRepository::class)
|
||||
* @ORM\Table(name="chill_person_social_action")
|
||||
*/
|
||||
class SocialAction
|
@@ -1,12 +1,14 @@
|
||||
<?php
|
||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass=SocialIssueRepository::class)
|
||||
* @ORM\Table(name="chill_person_social_issue")
|
||||
*/
|
||||
class SocialIssue
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user