mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-11-24 12:48:30 +00:00
187 lines
11 KiB
Markdown
187 lines
11 KiB
Markdown
# Stats about event on entity in php world
|
|
|
|
It is necessary to be able to gather information about events for some entities:
|
|
|
|
- when the event has been done;
|
|
- who did it;
|
|
- ...
|
|
|
|
Those "infos" are not linked with right management, like describe in [timelines`.
|
|
|
|
### “infos” for some stats and info about an entity
|
|
|
|
Building an info means:
|
|
|
|
- create an Entity, and map this entity to a SQL view (not a regular table);
|
|
- use the framework to build this entity dynamically.
|
|
|
|
A framework api is built to be able to build multiple “infos” entities
|
|
through “union” views:
|
|
|
|
- use a command ``bin/console chill:db:sync-views`` to synchronize view (create view if it does not exist, or update
|
|
views when new SQL parts are added in the UNION query. Internally, this command call a new ``ViewEntityInfoManager``,
|
|
which iterate over available views to build the SQL;
|
|
- one can create new “view entity info” by implementing a
|
|
``ViewEntityInfoProviderInterface``
|
|
- this implementation of the interface is free to create another
|
|
interface for building each part of the UNION query. This interface
|
|
is created for AccompanyingPeriodInfo:
|
|
``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface``
|
|
|
|
So, converting new “events” into rows for ``AccompanyingPeriodInfo`` is
|
|
just implementing this interface!
|
|
|
|
### Implementation for AccompanyingPeriod (``AccompanyingPeriod/AccompanyingPeriodInfo``)
|
|
|
|
A class is created for computing some statistical info for an
|
|
AccompanyingPeriod: ``AccompanyingPeriod/AccompanyingPeriodInfo``. This
|
|
contains information about “something happens”, who did it and when.
|
|
|
|
Having that info in the table answers some questions like:
|
|
|
|
- when is the last and the first action (AccompanyingPeriodWork,
|
|
Activity, AccompanyingPeriodWorkEvaluation, …) on the period;
|
|
- who is “acting” on the period, and when is the last “action” for each
|
|
user.
|
|
|
|
The AccompanyingPeriod info is mapped to a SQL view, not a table. The
|
|
SQL view is built dynamically (see below), and gathers info from
|
|
ActivityBundle, PersonBundle, CalendarBundle, … It is possible to create
|
|
a custom bundle and add info on this view.
|
|
|
|
```php
|
|
/**
|
|
*
|
|
* @ORM\Entity()
|
|
* @ORM\Table(name="view_chill_person_accompanying_period_info") ](==== THIS IS A VIEW, NOT A TABLE
|
|
*/
|
|
class AccompanyingPeriodInfo
|
|
{
|
|
// ...
|
|
}
|
|
```
|
|
|
|
#### Why do we need this?
|
|
|
|
For multiple jobs in a PHP world:
|
|
|
|
- moving the accompanying period to another step when inactive,
|
|
automatically;
|
|
- listing all the users which are intervening on the action on a new
|
|
“Liste des intervenants” page;
|
|
- filtering on exports
|
|
|
|
Later we will launch automatic anonymize for an accompanying period and
|
|
all related entities through this information.
|
|
|
|
#### How are the SQL views built that are mapped to “info” entities?
|
|
|
|
The AccompanyingPeriodInfo entity is mapped by a SQL view (not a regular
|
|
table).
|
|
|
|
The SQL view is built dynamically; it is a SQL view like this, for now (April 2023):
|
|
|
|
```sql
|
|
create view view_chill_person_accompanying_period_info
|
|
(accompanyingperiod_id, relatedentity, relatedentityid, user_id, infodate, discriminator, metadata) as
|
|
SELECT w.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity,
|
|
w.id AS relatedentityid,
|
|
cpapwr.user_id,
|
|
w.enddate AS infodate,
|
|
'accompanying_period_work_end'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work w
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id
|
|
WHERE w.enddate IS NOT NULL
|
|
UNION
|
|
SELECT cpapw.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity,
|
|
e.id AS relatedentityid,
|
|
e.updatedby_id AS user_id,
|
|
e.updatedat AS infodate,
|
|
'accompanying_period_work_evaluation_updated_at'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work_evaluation e
|
|
JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id
|
|
WHERE e.updatedat IS NOT NULL
|
|
UNION
|
|
SELECT cpapw.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity,
|
|
e.id AS relatedentityid,
|
|
cpapwr.user_id,
|
|
e.maxdate AS infodate,
|
|
'accompanying_period_work_evaluation_start'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work_evaluation e
|
|
JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id
|
|
WHERE e.maxdate IS NOT NULL
|
|
UNION
|
|
SELECT cpapw.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity,
|
|
e.id AS relatedentityid,
|
|
cpapwr.user_id,
|
|
e.startdate AS infodate,
|
|
'accompanying_period_work_evaluation_start'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work_evaluation e
|
|
JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id
|
|
UNION
|
|
SELECT cpapw.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument'::text AS relatedentity,
|
|
doc.id AS relatedentityid,
|
|
doc.updatedby_id AS user_id,
|
|
doc.updatedat AS infodate,
|
|
'accompanying_period_work_evaluation_document_updated_at'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work_evaluation_document doc
|
|
JOIN chill_person_accompanying_period_work_evaluation e ON doc.accompanyingperiodworkevaluation_id = e.id
|
|
JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id
|
|
WHERE doc.updatedat IS NOT NULL
|
|
UNION
|
|
SELECT cpapw.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation'::text AS relatedentity,
|
|
e.id AS relatedentityid,
|
|
cpapwr.user_id,
|
|
e.maxdate AS infodate,
|
|
'accompanying_period_work_evaluation_max'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work_evaluation e
|
|
JOIN chill_person_accompanying_period_work cpapw ON cpapw.id = e.accompanyingperiodwork_id
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON cpapw.id = cpapwr.accompanyingperiodwork_id
|
|
WHERE e.maxdate IS NOT NULL
|
|
UNION
|
|
SELECT w.accompanyingperiod_id,
|
|
'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'::text AS relatedentity,
|
|
w.id AS relatedentityid,
|
|
cpapwr.user_id,
|
|
w.startdate AS infodate,
|
|
'accompanying_period_work_start'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM chill_person_accompanying_period_work w
|
|
LEFT JOIN chill_person_accompanying_period_work_referrer cpapwr ON w.id = cpapwr.accompanyingperiodwork_id
|
|
UNION
|
|
SELECT activity.accompanyingperiod_id,
|
|
'Chill\ActivityBundle\Entity\Activity'::text AS relatedentity,
|
|
activity.id AS relatedentityid,
|
|
au.user_id,
|
|
activity.date AS infodate,
|
|
'activity_date'::text AS discriminator,
|
|
'{}'::jsonb AS metadata
|
|
FROM activity
|
|
LEFT JOIN activity_user au ON activity.id = au.activity_id
|
|
WHERE activity.accompanyingperiod_id IS NOT NULL;
|
|
```
|
|
|
|
As you can see, the view gathers multiple SELECT queries and binds them
|
|
with UNION.
|
|
|
|
Each SELECT query is built dynamically, through a class implementing an
|
|
interface: ``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface``, `like
|
|
here <https://gitlab.com/Chill-Projet/chill-bundles/-/blob/master/src/Bundle/ChillPersonBundle/Service/EntityInfo/AccompanyingPeriodInfoQueryPart/AccompanyingPeriodWorkEndQueryPartForAccompanyingPeriodInfo.php.md)__
|
|
|
|
To add new `SELECT` query in different `UNION` parts in the SQL view, create a
|
|
service and implements this interface: ``Chill\PersonBundle\Service\EntityInfo\AccompanyingPeriodInfoUnionQueryPartInterface``.
|