Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 229 |
|
0.00% |
0 / 16 |
CRAP | |
0.00% |
0 / 1 |
CollectivityGenerator | |
0.00% |
0 / 229 |
|
0.00% |
0 / 16 |
3306 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
2 | |||
initializeExtract | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
12 | |||
collectivityHeaders | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
2 | |||
initializeCollectivity | |
0.00% |
0 / 56 |
|
0.00% |
0 / 1 |
552 | |||
registryHeaders | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
initializeRegistry | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
20 | |||
surveyHeaders | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
initializeSurvey | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
userHeaders | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
initializeUser | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
proofHeaders | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
initializeProof | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
conformiteOrganisationHeaders | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
initializeConformiteOrganisation | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
30 | |||
collectivityServiceHeaders | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
initializeService | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * This file is part of the MADIS - RGPD Management application. |
5 | * |
6 | * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes |
7 | * |
8 | * This program is free software: you can redistribute it and/or modify |
9 | * it under the terms of the GNU Affero General Public License as published by |
10 | * the Free Software Foundation, either version 3 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU Affero General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU Affero General Public License |
19 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
20 | */ |
21 | |
22 | declare(strict_types=1); |
23 | |
24 | namespace App\Domain\Reporting\Generator\Csv; |
25 | |
26 | use App\Domain\Registry\Dictionary\ProofTypeDictionary; |
27 | use App\Domain\Registry\Repository\ConformiteOrganisation\Processus; |
28 | use App\Domain\Registry\Repository\Contractor; |
29 | use App\Domain\Registry\Repository\Mesurement; |
30 | use App\Domain\Registry\Repository\Proof; |
31 | use App\Domain\Registry\Repository\Request; |
32 | use App\Domain\Registry\Repository\Violation; |
33 | use App\Domain\Registry\Service\ConformiteOrganisationService; |
34 | use App\Domain\User\Dictionary\CollectivityTypeDictionary; |
35 | use App\Domain\User\Dictionary\ContactCivilityDictionary; |
36 | use App\Domain\User\Repository\Collectivity; |
37 | use App\Infrastructure\ORM\Maturity\Repository\Survey; |
38 | use App\Infrastructure\ORM\Registry\Repository\ConformiteOrganisation\Evaluation; |
39 | use App\Infrastructure\ORM\Registry\Repository\Treatment; |
40 | use App\Infrastructure\ORM\User\Repository\User; |
41 | use Symfony\Component\Security\Core\Security; |
42 | use Symfony\Contracts\Translation\TranslatorInterface; |
43 | |
44 | class CollectivityGenerator extends AbstractGenerator |
45 | { |
46 | /** |
47 | * @var TranslatorInterface |
48 | */ |
49 | private $translator; |
50 | |
51 | /** |
52 | * @var Collectivity |
53 | */ |
54 | private $collectivityRepository; |
55 | |
56 | /** |
57 | * @var Mesurement |
58 | */ |
59 | private $mesurementRepository; |
60 | |
61 | /** |
62 | * @var Survey |
63 | */ |
64 | private $surveyRepository; |
65 | |
66 | /** |
67 | * @var User |
68 | */ |
69 | private $userRepository; |
70 | |
71 | /** |
72 | * @var Proof |
73 | */ |
74 | private $proofRepository; |
75 | |
76 | /** |
77 | * @var Treatment |
78 | */ |
79 | private $treatmentRepository; |
80 | |
81 | /** |
82 | * @var Contractor |
83 | */ |
84 | private $contractorRepository; |
85 | |
86 | /** |
87 | * @var Violation |
88 | */ |
89 | private $violationRepository; |
90 | |
91 | /** |
92 | * @var Request |
93 | */ |
94 | private $requestRepository; |
95 | |
96 | /** |
97 | * @var Processus |
98 | */ |
99 | private $processsusRepository; |
100 | |
101 | /** |
102 | * @var Evaluation |
103 | */ |
104 | private $evaluationRepository; |
105 | |
106 | /** |
107 | * @var Security |
108 | */ |
109 | private $security; |
110 | |
111 | /** |
112 | * @var string |
113 | */ |
114 | private $defaultDpoCivility; |
115 | /** |
116 | * @var string |
117 | */ |
118 | private $defaultDpoFirstName; |
119 | /** |
120 | * @var string |
121 | */ |
122 | private $defaultDpoLastName; |
123 | /** |
124 | * @var string |
125 | */ |
126 | private $defaultDpoCompany; |
127 | /** |
128 | * @var string |
129 | */ |
130 | private $defaultDpoJob; |
131 | /** |
132 | * @var string |
133 | */ |
134 | private $defaultDpoMail; |
135 | /** |
136 | * @var string |
137 | */ |
138 | private $defaultDpoPhoneNumber; |
139 | |
140 | public function __construct( |
141 | TranslatorInterface $translatorInterface, |
142 | Collectivity $collectivityRepository, |
143 | Mesurement $mesurementRepository, |
144 | Survey $surveyRepository, |
145 | User $userRepository, |
146 | Proof $proofRepository, |
147 | Treatment $treatmentRepository, |
148 | Contractor $contractorRepository, |
149 | Violation $violationRepository, |
150 | Request $requestRepository, |
151 | Processus $processusRepository, |
152 | Evaluation $evaluationRepository, |
153 | Security $security, |
154 | string $defaultDpoCivility, |
155 | string $defaultDpoFirstName, |
156 | string $defaultDpoLastName, |
157 | string $defaultDpoCompany, |
158 | string $defaultDpoJob, |
159 | string $defaultDpoMail, |
160 | string $defaultDpoPhoneNumber, |
161 | ) { |
162 | $this->translator = $translatorInterface; |
163 | $this->collectivityRepository = $collectivityRepository; |
164 | $this->mesurementRepository = $mesurementRepository; |
165 | $this->surveyRepository = $surveyRepository; |
166 | $this->userRepository = $userRepository; |
167 | $this->proofRepository = $proofRepository; |
168 | $this->treatmentRepository = $treatmentRepository; |
169 | $this->contractorRepository = $contractorRepository; |
170 | $this->violationRepository = $violationRepository; |
171 | $this->requestRepository = $requestRepository; |
172 | $this->processsusRepository = $processusRepository; |
173 | $this->evaluationRepository = $evaluationRepository; |
174 | $this->security = $security; |
175 | $this->defaultDpoCivility = $defaultDpoCivility; |
176 | $this->defaultDpoFirstName = $defaultDpoFirstName; |
177 | $this->defaultDpoLastName = $defaultDpoLastName; |
178 | $this->defaultDpoCompany = $defaultDpoCompany; |
179 | $this->defaultDpoJob = $defaultDpoJob; |
180 | $this->defaultDpoMail = $defaultDpoMail; |
181 | $this->defaultDpoPhoneNumber = $defaultDpoPhoneNumber; |
182 | } |
183 | |
184 | public function initializeExtract(): array |
185 | { |
186 | $headers = array_merge( |
187 | $this->collectivityHeaders(), |
188 | $this->registryHeaders(), |
189 | $this->surveyHeaders(), |
190 | $this->userHeaders(), |
191 | $this->proofHeaders(), |
192 | $this->conformiteOrganisationHeaders(), |
193 | ); |
194 | $data = [$headers]; |
195 | if ($this->security->isGranted('ROLE_ADMIN')) { |
196 | $collectivities = $this->collectivityRepository->findAll(); |
197 | } else { |
198 | $collectivities = $this->collectivityRepository->findByUserReferent($this->security->getUser(), true); |
199 | } |
200 | |
201 | foreach ($collectivities as $collectivity) { |
202 | $extract = array_merge( |
203 | $this->initializeCollectivity($collectivity), |
204 | $this->initializeRegistry($collectivity), |
205 | $this->initializeSurvey($collectivity), |
206 | $this->initializeUser($collectivity), |
207 | $this->initializeProof($collectivity), |
208 | $this->initializeConformiteOrganisation($collectivity) |
209 | ); |
210 | array_push($data, $extract); |
211 | } |
212 | |
213 | return $data; |
214 | } |
215 | |
216 | private function collectivityHeaders(): array |
217 | { |
218 | $legalManager = $this->translator->trans('user.organization.tab.legal_manager'); |
219 | $itManager = $this->translator->trans('user.organization.tab.it_manager'); |
220 | $referent = $this->translator->trans('user.organization.tab.referent'); |
221 | $dpo = $this->translator->trans('user.organization.tab.dpo'); |
222 | |
223 | return [ |
224 | 'Id', |
225 | $this->translator->trans('user.organization.label.name'), |
226 | $this->translator->trans('user.organization.label.short_name'), |
227 | $this->translator->trans('user.organization.label.type'), |
228 | $this->translator->trans('user.organization.label.siren'), |
229 | $this->translator->trans('user.organization.label.active'), |
230 | $this->translator->trans('user.organization.label.website'), |
231 | $this->translator->trans('user.organization.label.has_module_conformite_traitement'), |
232 | $this->translator->trans('user.organization.label.has_module_conformite_organisation'), |
233 | $this->translator->trans('global.label.address.line_one'), |
234 | $this->translator->trans('global.label.address.line_two'), |
235 | $this->translator->trans('global.label.address.zip_code'), |
236 | $this->translator->trans('global.label.address.city'), |
237 | $this->translator->trans('global.label.address.insee'), |
238 | $this->translator->trans('user.organization.label.export_service_csv'), |
239 | $this->translator->trans('user.organization.label.other_information'), |
240 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.civility'), |
241 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.first_name'), |
242 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.last_name'), |
243 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.job'), |
244 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.email'), |
245 | $legalManager . ' - ' . $this->translator->trans('global.label.contact.phone_number'), |
246 | $itManager . ' - ' . $this->translator->trans('user.organization.label.different_it_manager'), |
247 | $itManager . ' - ' . $this->translator->trans('global.label.contact.civility'), |
248 | $itManager . ' - ' . $this->translator->trans('global.label.contact.first_name'), |
249 | $itManager . ' - ' . $this->translator->trans('global.label.contact.last_name'), |
250 | $itManager . ' - ' . $this->translator->trans('global.label.contact.job'), |
251 | $itManager . ' - ' . $this->translator->trans('global.label.contact.email'), |
252 | $itManager . ' - ' . $this->translator->trans('global.label.contact.phone_number'), |
253 | $referent . ' - ' . $this->translator->trans('global.label.contact.civility'), |
254 | $referent . ' - ' . $this->translator->trans('global.label.contact.first_name'), |
255 | $referent . ' - ' . $this->translator->trans('global.label.contact.last_name'), |
256 | $referent . ' - ' . $this->translator->trans('global.label.contact.job'), |
257 | $referent . ' - ' . $this->translator->trans('global.label.contact.email'), |
258 | $referent . ' - ' . $this->translator->trans('global.label.contact.phone_number'), |
259 | $dpo . ' - ' . $this->translator->trans('user.organization.label.different_dpo'), |
260 | $dpo . ' - ' . $this->translator->trans('global.label.contact.civility'), |
261 | $dpo . ' - ' . $this->translator->trans('global.label.contact.first_name'), |
262 | $dpo . ' - ' . $this->translator->trans('global.label.contact.last_name'), |
263 | $dpo . ' - ' . $this->translator->trans('global.label.contact.job'), |
264 | $dpo . ' - ' . $this->translator->trans('global.label.contact.email'), |
265 | $dpo . ' - ' . $this->translator->trans('global.label.contact.phone_number'), |
266 | $this->translator->trans('user.organization.label.management_commitment'), |
267 | $this->translator->trans('user.organization.label.continuous_improvement'), |
268 | $this->translator->trans('user.organization.label.comite_il_short'), |
269 | $this->translator->trans('global.label.created_at'), |
270 | $this->translator->trans('global.label.updated_at'), |
271 | ]; |
272 | } |
273 | |
274 | private function initializeCollectivity(\App\Domain\User\Model\Collectivity $collectivity) |
275 | { |
276 | $yes = $this->translator->trans('global.label.yes'); |
277 | $no = $this->translator->trans('global.label.no'); |
278 | |
279 | $legalManager = $collectivity->getLegalManager(); |
280 | $itManager = $collectivity->getItManager(); |
281 | $services = $collectivity->getServices(); |
282 | $referent = $collectivity->getReferent(); |
283 | $dpo = $collectivity->getDpo(); |
284 | |
285 | return [ |
286 | $collectivity->getId()->toString(), |
287 | $collectivity->getName(), |
288 | $collectivity->getShortName(), |
289 | !\is_null($collectivity->getType()) ? CollectivityTypeDictionary::getTypes()[$collectivity->getType()] : '', |
290 | $collectivity->getSiren(), |
291 | $collectivity->isActive() ? $this->translator->trans('global.label.active') : $this->translator->trans('global.label.inactive'), |
292 | $collectivity->getWebsite(), |
293 | $collectivity->isHasModuleConformiteTraitement() ? $yes : $no, |
294 | $collectivity->isHasModuleConformiteOrganisation() ? $yes : $no, |
295 | $collectivity->getAddress()->getLineOne(), |
296 | $collectivity->getAddress()->getLineTwo(), |
297 | $collectivity->getAddress()->getZipCode(), |
298 | $collectivity->getAddress()->getCity(), |
299 | $collectivity->getAddress()->getInsee(), |
300 | implode(' - ', \iterable_to_array($collectivity->getServices())), |
301 | $collectivity->getInformationsComplementaires(), |
302 | !\is_null($legalManager->getCivility() && in_array($legalManager->getCivility(), ContactCivilityDictionary::getCivilitiesKeys())) ? ContactCivilityDictionary::getCivilities()[$legalManager->getCivility()] : '', |
303 | $legalManager->getFirstName(), |
304 | $legalManager->getLastName(), |
305 | $legalManager->getJob(), |
306 | $legalManager->getMail(), |
307 | $legalManager->getPhoneNumber(), |
308 | $collectivity->isDifferentItManager() ? $yes : $no, |
309 | !\is_null($itManager->getCivility() && in_array($itManager->getCivility(), ContactCivilityDictionary::getCivilitiesKeys())) ? ContactCivilityDictionary::getCivilities()[$itManager->getCivility()] : $itManager->getCivility(), |
310 | $itManager->getFirstName(), |
311 | $itManager->getLastName(), |
312 | $itManager->getJob(), |
313 | $itManager->getMail(), |
314 | $itManager->getPhoneNumber(), |
315 | !\is_null($referent->getCivility() && in_array($referent->getCivility(), ContactCivilityDictionary::getCivilitiesKeys())) ? ContactCivilityDictionary::getCivilities()[$referent->getCivility()] : '', |
316 | $referent->getFirstName(), |
317 | $referent->getLastName(), |
318 | $referent->getJob(), |
319 | $referent->getMail(), |
320 | $referent->getPhoneNumber(), |
321 | $collectivity->isDifferentDpo() ? $yes : $no, |
322 | !\is_null($dpo->getCivility() && in_array($dpo->getCivility(), ContactCivilityDictionary::getCivilitiesKeys())) ? ContactCivilityDictionary::getCivilities()[$dpo->getCivility()] : ContactCivilityDictionary::getCivilities()[$this->defaultDpoCivility], |
323 | !\is_null($dpo->getFirstName()) ? $dpo->getFirstName() : $this->defaultDpoFirstName, |
324 | !\is_null($dpo->getLastName()) ? $dpo->getLastName() : $this->defaultDpoLastName, |
325 | !\is_null($dpo->getJob()) ? $dpo->getJob() : $this->defaultDpoJob, |
326 | !\is_null($dpo->getMail()) ? $dpo->getMail() : $this->defaultDpoMail, |
327 | !\is_null($dpo->getPhoneNumber()) ? $dpo->getPhoneNumber() : $this->defaultDpoPhoneNumber, |
328 | !\is_null($collectivity->getReportingBlockManagementCommitment()) ? \strip_tags($collectivity->getReportingBlockManagementCommitment()) : '', |
329 | !\is_null($collectivity->getReportingBlockContinuousImprovement()) ? \strip_tags(html_entity_decode($collectivity->getReportingBlockContinuousImprovement(), ENT_QUOTES | ENT_HTML401)) : '', |
330 | !$collectivity->getComiteIlContacts()->isEmpty() ? json_encode($collectivity->getComiteIlContacts()->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : '', |
331 | $this->getDate($collectivity->getCreatedAt()), |
332 | $this->getDate($collectivity->getUpdatedAt()), |
333 | ]; |
334 | } |
335 | |
336 | private function registryHeaders() |
337 | { |
338 | return [ |
339 | 'Actions de protection réalisées', |
340 | 'Actions de protection planifiées', |
341 | 'Nombre de preuves déposées', |
342 | 'Nombre de traitements', |
343 | 'Nombre de sous-traitants', |
344 | 'Nombre de violation de données', |
345 | 'Nombre de demandes de personnes concernées', |
346 | 'Date du dernier traitement modifié', |
347 | 'Date de la dernière violation', |
348 | 'Date de la dernière demande', |
349 | ]; |
350 | } |
351 | |
352 | private function initializeRegistry(\App\Domain\User\Model\Collectivity $collectivity): array |
353 | { |
354 | $lastUpdatedTreatment = $this->treatmentRepository->findOneOrNullLastUpdateByCollectivity($collectivity); |
355 | $lastUpdatedViolation = $this->violationRepository->findOneOrNullLastUpdateByCollectivity($collectivity); |
356 | $lastUpdatedRequest = $this->requestRepository->findOneOrNullLastUpdateByCollectivity($collectivity); |
357 | |
358 | return [ |
359 | $this->mesurementRepository->countAppliedByCollectivity($collectivity), |
360 | $this->mesurementRepository->countPlanifiedByCollectivity($collectivity), |
361 | $this->proofRepository->countAllByCollectivity($collectivity), |
362 | $this->treatmentRepository->countAllByCollectivity($collectivity), |
363 | $this->contractorRepository->countAllByCollectivity($collectivity), |
364 | $this->violationRepository->countAllByCollectivity($collectivity), |
365 | $this->requestRepository->countAllByCollectivity($collectivity), |
366 | !\is_null($lastUpdatedTreatment) ? $this->getDate($lastUpdatedTreatment->getUpdatedAt()) : null, |
367 | !\is_null($lastUpdatedViolation) ? $this->getDate($lastUpdatedViolation->getUpdatedAt()) : null, |
368 | !\is_null($lastUpdatedRequest) ? $this->getDate($lastUpdatedRequest->getUpdatedAt()) : null, |
369 | ]; |
370 | } |
371 | |
372 | private function surveyHeaders() |
373 | { |
374 | return [ |
375 | 'Dernier indice de maturité - date', |
376 | 'Dernier indice de maturité - score', |
377 | ]; |
378 | } |
379 | |
380 | private function initializeSurvey(\App\Domain\User\Model\Collectivity $collectivity): array |
381 | { |
382 | $surveys = $this->surveyRepository->findAllByCollectivity($collectivity, ['createdAt' => 'desc'], 1); |
383 | |
384 | /** @var \App\Domain\Maturity\Model\Survey|null $survey */ |
385 | $survey = isset($surveys[0]) ? $surveys[0] : null; |
386 | |
387 | return [ |
388 | !\is_null($survey) ? $this->getDate($survey->getCreatedAt()) : null, |
389 | !\is_null($survey) ? $survey->getScore() : null, |
390 | ]; |
391 | } |
392 | |
393 | private function userHeaders() |
394 | { |
395 | return [ |
396 | 'Dernier utilisateur connecté - Date dernière connextion', |
397 | 'Dernier utilisateur connecté - Nom', |
398 | 'Dernier utilisateur connecté - Email', |
399 | ]; |
400 | } |
401 | |
402 | private function initializeUser(\App\Domain\User\Model\Collectivity $collectivity): array |
403 | { |
404 | $user = $this->userRepository->findOneOrNullLastLoginUserByCollectivity($collectivity); |
405 | |
406 | return [ |
407 | !\is_null($user) ? $this->getDate($user->getLastLogin()) : null, |
408 | !\is_null($user) ? $user->getFullName() : null, |
409 | !\is_null($user) ? $user->getEmail() : null, |
410 | ]; |
411 | } |
412 | |
413 | private function proofHeaders() |
414 | { |
415 | $headers = []; |
416 | |
417 | foreach (ProofTypeDictionary::getTypes() as $type) { |
418 | $headers[] = 'Dernier dépot de preuve - ' . $type; |
419 | } |
420 | |
421 | return $headers; |
422 | } |
423 | |
424 | private function initializeProof(\App\Domain\User\Model\Collectivity $collectivity) |
425 | { |
426 | $data = []; |
427 | |
428 | foreach (ProofTypeDictionary::getTypesKeys() as $type) { |
429 | $proof = $this->proofRepository->findOneOrNullByTypeAndCollectivity($type, $collectivity); |
430 | |
431 | $data[] = !\is_null($proof) ? $this->getDate($proof->getCreatedAt()) : null; |
432 | } |
433 | |
434 | return $data; |
435 | } |
436 | |
437 | private function conformiteOrganisationHeaders() |
438 | { |
439 | $headers = ['Brouillon']; |
440 | |
441 | foreach ($this->processsusRepository->findAll(['position' => 'asc']) as $processus) { |
442 | $headers[] = 'Conformité processus - ' . $processus->getNom(); |
443 | $headers[] = 'Conformité processus - ' . $processus->getNom() . ' - Pilote'; |
444 | } |
445 | |
446 | return $headers; |
447 | } |
448 | |
449 | private function initializeConformiteOrganisation(\App\Domain\User\Model\Collectivity $collectivity) |
450 | { |
451 | $data = []; |
452 | |
453 | $conformiteOrganisationEvaluation = $this->evaluationRepository->findLastByOrganisation($collectivity); |
454 | |
455 | if ($collectivity->isHasModuleConformiteOrganisation() && null !== $conformiteOrganisationEvaluation) { |
456 | $conformites = ConformiteOrganisationService::getOrderedConformites($conformiteOrganisationEvaluation); |
457 | |
458 | $data[] = $conformiteOrganisationEvaluation->isDraft() ? 'Oui' : 'Non'; |
459 | foreach ($conformites as $conformite) { |
460 | $data[] = $conformite->getConformite(); |
461 | $data[] = $conformite->getPilote(); |
462 | } |
463 | } |
464 | |
465 | return $data; |
466 | } |
467 | |
468 | private function collectivityServiceHeaders() |
469 | { |
470 | return [ |
471 | $this->translator->trans('user.organization.label.export_service_csv'), |
472 | ]; |
473 | } |
474 | |
475 | private function initializeService(\App\Domain\User\Model\Collectivity $collectivity): array |
476 | { |
477 | return [ |
478 | implode(' - ', \iterable_to_array($collectivity->getServices())), |
479 | ]; |
480 | } |
481 | } |