Passed
Push — master ( 658469...7ef440 )
by
unknown
11:44
created

IndexBlocksController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
nc 1
nop 10
dl 0
loc 13
rs 10
c 1
b 0
f 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Controller\Admin;
8
9
use AppPlugin;
10
use Chamilo\CoreBundle\Controller\BaseController;
11
use Chamilo\CoreBundle\Entity\Page;
12
use Chamilo\CoreBundle\Entity\PageCategory;
13
use Chamilo\CoreBundle\Entity\SequenceResource;
14
use Chamilo\CoreBundle\Event\AbstractEvent;
15
use Chamilo\CoreBundle\Event\AdminBlockDisplayedEvent;
16
use Chamilo\CoreBundle\Event\Events;
17
use Chamilo\CoreBundle\Helpers\AccessUrlHelper;
18
use Chamilo\CoreBundle\Helpers\AuthenticationConfigHelper;
19
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository;
20
use Chamilo\CoreBundle\Repository\PageCategoryRepository;
21
use Chamilo\CoreBundle\Repository\PageRepository;
22
use Chamilo\CoreBundle\Repository\PluginRepository;
23
use Chamilo\CoreBundle\Settings\SettingsManager;
24
use Plugin;
25
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
26
use Symfony\Component\ExpressionLanguage\Expression;
27
use Symfony\Component\HttpFoundation\JsonResponse;
28
use Symfony\Component\Routing\Attribute\Route;
29
use Symfony\Component\Security\Http\Attribute\IsGranted;
30
use Symfony\Component\Serializer\SerializerInterface;
31
use Symfony\Contracts\Translation\TranslatorInterface;
32
use Throwable;
33
34
#[IsGranted(new Expression('is_granted("ROLE_ADMIN") or is_granted("ROLE_SESSION_MANAGER")'))]
35
#[Route('/admin/index', name: 'admin_index_blocks')]
36
class IndexBlocksController extends BaseController
37
{
38
    private bool $isAdmin = false;
39
    private bool $isSessionAdmin = false;
40
    private bool $isLdapActive;
41
42
    public function __construct(
43
        private readonly TranslatorInterface $translator,
44
        private readonly SettingsManager $settingsManager,
45
        private readonly PageRepository $pageRepository,
46
        private readonly PageCategoryRepository $pageCategoryRepository,
47
        private readonly SerializerInterface $serializer,
48
        private readonly EventDispatcherInterface $eventDispatcher,
49
        private readonly PluginRepository $pluginRepository,
50
        private readonly AccessUrlHelper $accessUrlHelper,
51
        private readonly AccessUrlRepository $accessUrlRepository,
52
        AuthenticationConfigHelper $authConfigHelper,
53
    ) {
54
        $this->isLdapActive = $authConfigHelper->getLdapConfig()['enabled'];
55
    }
56
57
    public function __invoke(): JsonResponse
58
    {
59
        $this->isAdmin = $this->isGranted('ROLE_ADMIN');
60
        $this->isSessionAdmin = $this->isGranted('ROLE_SESSION_MANAGER');
61
62
        $json = [];
63
64
        $adminBlockEvent = new AdminBlockDisplayedEvent($json, AbstractEvent::TYPE_PRE);
65
66
        $this->eventDispatcher->dispatch($adminBlockEvent, Events::ADMIN_BLOCK_DISPLAYED);
67
68
        $json = $adminBlockEvent->getData();
69
70
        $json['users'] = [
71
            'id' => 'block-admin-users',
72
            'searchUrl' => '/main/admin/user_list.php',
73
            'editable' => $this->isAdmin,
74
            'items' => $this->getItemsUsers(),
75
            'extraContent' => $this->getExtraContent('block-admin-users'),
76
        ];
77
78
        if ($this->isAdmin) {
79
            $json['courses'] = [
80
                'id' => 'block-admin-courses',
81
                'searchUrl' => '/main/admin/course_list.php',
82
                'editable' => true,
83
                'items' => $this->getItemsCourses(),
84
                'extraContent' => $this->getExtraContent('block-admin-courses'),
85
            ];
86
87
            $json['platform'] = [
88
                'id' => 'block-admin-platform',
89
                'searchUrl' => $this->generateUrl('chamilo_platform_settings_search'),
90
                'editable' => true,
91
                'items' => $this->getItemsPlatform(),
92
                'extraContent' => $this->getExtraContent('block-admin-platform'),
93
            ];
94
95
            /* Settings */
96
            $json['settings'] = [
97
                'id' => 'block-admin-settings',
98
                'editable' => false,
99
                'items' => $this->getItemsSettings(),
100
                'extraContent' => $this->getExtraContent('block-admin-settings'),
101
            ];
102
103
            // Skills
104
            if ('true' === $this->settingsManager->getSetting('skill.allow_skills_tool')) {
105
                $json['skills'] = [
106
                    'id' => 'block-admin-skills',
107
                    'editable' => false,
108
                    'items' => $this->getItemsSkills(),
109
                    'extraContent' => $this->getExtraContent('block-admin-skills'),
110
                ];
111
            }
112
113
            if ('true' === $this->settingsManager->getSetting('gradebook.gradebook_dependency')) {
114
                $json['gradebook'] = [
115
                    'id' => 'block-admin-gradebook',
116
                    'editable' => false,
117
                    'items' => $this->getItemsGradebook(),
118
                    'extraContent' => $this->getExtraContent('block-admin-gradebook'),
119
                ];
120
            }
121
122
            // Data protection
123
            if ('true' !== $this->settingsManager->getSetting('privacy.disable_gdpr')) {
124
                $json['data_privacy'] = [
125
                    'id' => 'block-admin-privacy',
126
                    'editable' => false,
127
                    'items' => $this->getItemsPrivacy(),
128
                    'extraContent' => $this->getExtraContent('block-admin-privacy'),
129
                ];
130
            }
131
132
            $json['security'] = [
133
                'id' => 'block-admin-security',
134
                'editable' => false,
135
                'items' => $this->getItemsSecurity(),
136
                'extraContent' => $this->getExtraContent('block-admin-security'),
137
            ];
138
139
            /* Chamilo.org */
140
            $json['chamilo'] = [
141
                'id' => 'block-admin-chamilo',
142
                'editable' => false,
143
                'items' => $this->getItemsChamilo(),
144
                'extraContent' => $this->getExtraContent('block-admin-chamilo'),
145
            ];
146
147
            $json['plugins'] = [
148
                'id' => 'block-admin-plugins',
149
                'editable' => false,
150
                'items' => $this->getItemsPlugins(),
151
            ];
152
153
            /* Health check */
154
            $json['health_check'] = [
155
                'id' => 'block-admin-health-check',
156
                'editable' => false,
157
                'items' => $this->getItemsHealthCheck(),
158
            ];
159
        }
160
161
        /* Sessions */
162
        $json['sessions'] = [
163
            'id' => 'block-admin-sessions',
164
            'searchUrl' => '/main/session/session_list.php',
165
            'editable' => $this->isAdmin,
166
            'items' => $this->getItemsSessions(),
167
            'extraContent' => $this->getExtraContent('block-admin-sessions'),
168
        ];
169
170
        $adminBlockEvent = new AdminBlockDisplayedEvent($json, AbstractEvent::TYPE_POST);
171
172
        $this->eventDispatcher->dispatch($adminBlockEvent, Events::ADMIN_BLOCK_DISPLAYED);
173
174
        $json = $adminBlockEvent->getData();
175
176
        return $this->json($json);
177
    }
178
179
    private function getItemsSecurity(): array
180
    {
181
        return [
182
            [
183
                'class' => 'item-security-login-attempts',
184
                'url' => $this->generateUrl('admin_security_login_attempts'),
185
                'label' => $this->translator->trans('Login attempts'),
186
            ],
187
        ];
188
    }
189
190
    private function getItemsUsers(): array
191
    {
192
        $items = [];
193
        $items[] = [
194
            'class' => 'item-user-list',
195
            'url' => '/main/admin/user_list.php',
196
            'label' => $this->translator->trans('User list'),
197
        ];
198
        $items[] = [
199
            'class' => 'item-user-add',
200
            'url' => '/main/admin/user_add.php',
201
            'label' => $this->translator->trans('Add a user'),
202
        ];
203
204
        if ($this->isAdmin) {
205
            $items[] = [
206
                'class' => 'item-user-export',
207
                'url' => '/main/admin/user_export.php',
208
                'label' => $this->translator->trans('Export users list'),
209
            ];
210
            $items[] = [
211
                'class' => 'item-user-import',
212
                'url' => '/main/admin/user_import.php',
213
                'label' => $this->translator->trans('Import users list'),
214
            ];
215
            $items[] = [
216
                'class' => 'item-user-import-update',
217
                'url' => '/main/admin/user_update_import.php',
218
                'label' => $this->translator->trans('Edit users list'),
219
            ];
220
            $items[] = [
221
                'class' => 'item-user-import-anonymize',
222
                'url' => '/main/admin/user_anonymize_import.php',
223
                'label' => $this->translator->trans('Anonymise users list'),
224
            ];
225
226
            if ($this->isLdapActive) {
227
                $items[] = [
228
                    'class' => 'item-user-ldap-list',
229
                    'url' => '/main/admin/ldap_users_list.php',
230
                    'label' => $this->translator->trans('Import LDAP users into the platform'),
231
                ];
232
            }
233
234
            $items[] = [
235
                'class' => 'item-user-field',
236
                'url' => '/main/admin/extra_fields.php?'.http_build_query(['type' => 'user']),
237
                'label' => $this->translator->trans('Profiling'),
238
            ];
239
            $items[] = [
240
                'class' => 'item-user-groups',
241
                'url' => '/main/admin/usergroups.php',
242
                'label' => $this->translator->trans('Classes'),
243
            ];
244
245
            if ('true' === $this->settingsManager->getSetting('admin.show_link_request_hrm_user')) {
246
                $items[] = [
247
                    'class' => 'item-user-linking-requests',
248
                    'url' => '/main/admin/user_linking_requests.php',
249
                    'label' => $this->translator->trans('Student linking requests'),
250
                ];
251
            }
252
        } else {
253
            $items[] = [
254
                'class' => 'item-user-import',
255
                'url' => '/main/admin/user_import.php',
256
                'label' => $this->translator->trans('Import users list'),
257
            ];
258
            $items[] = [
259
                'class' => 'item-user-groups',
260
                'url' => '/main/admin/usergroups.php',
261
                'label' => $this->translator->trans('Classes'),
262
            ];
263
264
            if ('true' === $this->settingsManager->getSetting('session.limit_session_admin_role')) {
265
                $items = array_filter($items, function (array $item) {
266
                    $urls = [
267
                        '/main/admin/user_list.php',
268
                        '/main/admin/user_add.php',
269
                    ];
270
271
                    return \in_array($item['url'], $urls, true);
272
                });
273
            }
274
275
            if ('true' === $this->settingsManager->getSetting('session.limit_session_admin_list_users')) {
276
                $items = array_filter($items, function (array $item): bool {
277
                    $urls = [
278
                        '/main/admin/user_list.php',
279
                    ];
280
281
                    return !\in_array($item['url'], $urls, true);
282
                });
283
            }
284
285
            if ('true' === $this->settingsManager->getSetting('session.allow_session_admin_extra_access')) {
286
                $items[] = [
287
                    'class' => 'item-user-import-update',
288
                    'url' => '/main/admin/user_update_import.php',
289
                    'label' => $this->translator->trans('Edit users list'),
290
                ];
291
                $items[] = [
292
                    'class' => 'item-user-export',
293
                    'url' => '/main/admin/user_export.php',
294
                    'label' => $this->translator->trans('Export users list'),
295
                ];
296
            }
297
        }
298
299
        return array_values($items);
300
    }
301
302
    private function getExtraContent(string $title): ?array
303
    {
304
        /** @var Page|null $page */
305
        $page = $this->pageRepository->findOneBy(['title' => $title]);
306
307
        $pageJsonld = $this->serializer->serialize($page, 'jsonld', ['groups' => ['adminblock:read']]);
308
        $pageArray = json_decode($pageJsonld, true);
309
310
        if ($page) {
311
            return $pageArray;
312
        }
313
314
        /** @var PageCategory $category */
315
        $category = $this->pageCategoryRepository->findOneBy(['title' => $title]);
316
        $categoryJsonld = $this->serializer->serialize($category, 'jsonld', ['groups' => ['page:read']]);
317
        $categoryArray = json_decode($categoryJsonld, true);
318
319
        if (empty($categoryArray)) {
320
            return [];
321
        }
322
323
        return [
324
            'category' => $categoryArray['@id'],
325
        ];
326
    }
327
328
    private function getItemsCourses(): array
329
    {
330
        $items = [];
331
        $items[] = [
332
            'class' => 'item-course-list',
333
            'url' => '/main/admin/course_list.php',
334
            'label' => $this->translator->trans('Course list'),
335
        ];
336
        $items[] = [
337
            'class' => 'item-course-add',
338
            'url' => '/main/admin/course_add.php',
339
            'label' => $this->translator->trans('Add course'),
340
        ];
341
342
        if ('true' === $this->settingsManager->getSetting('course.course_validation')) {
343
            $items[] = [
344
                'class' => 'item-course-request',
345
                'url' => '/main/admin/course_request_review.php',
346
                'label' => $this->translator->trans('Review incoming course requests'),
347
            ];
348
            $items[] = [
349
                'class' => 'item-course-request-accepted',
350
                'url' => '/main/admin/course_request_accepted.php',
351
                'label' => $this->translator->trans('Accepted course requests'),
352
            ];
353
            $items[] = [
354
                'class' => 'item-course-request-rejected',
355
                'url' => '/main/admin/course_request_rejected.php',
356
                'label' => $this->translator->trans('Rejected course requests'),
357
            ];
358
        }
359
360
        $items[] = [
361
            'class' => 'item-course-export',
362
            'url' => '/main/admin/course_export.php',
363
            'label' => $this->translator->trans('Export courses'),
364
        ];
365
        $items[] = [
366
            'class' => 'item-course-import',
367
            'url' => '/main/admin/course_import.php',
368
            'label' => $this->translator->trans('Import courses list'),
369
        ];
370
        $items[] = [
371
            'class' => 'item-course-category',
372
            'url' => '/main/admin/course_category.php',
373
            'label' => $this->translator->trans('Course categories'),
374
        ];
375
        $items[] = [
376
            'class' => 'item-course-subscription',
377
            'url' => '/main/admin/subscribe_user2course.php',
378
            'label' => $this->translator->trans('Add a user to a course'),
379
        ];
380
        $items[] = [
381
            'class' => 'item-course-subscription-import',
382
            'url' => '/main/admin/course_user_import.php',
383
            'label' => $this->translator->trans('Import users list'),
384
        ];
385
        // $items[] = [
386
        //    'url'=>'course_intro_pdf_import.php',
387
        //    'label' => $this->translator->$this->trans('Import PDF introductions into courses'),
388
        // ];
389
390
        if ('true' === $this->settingsManager->getSetting('gradebook.gradebook_enable_grade_model')) {
391
            $items[] = [
392
                'class' => 'item-grade-model',
393
                'url' => '/main/admin/grade_models.php',
394
                'label' => $this->translator->trans('Grading model'),
395
            ];
396
        }
397
398
        if ($this->isLdapActive) {
399
            $items[] = [
400
                'class' => 'item-course-subscription-ldap',
401
                'url' => '/main/admin/ldap_import_students.php',
402
                'label' => $this->translator->trans('Import LDAP users into a course'),
403
            ];
404
        }
405
406
        $items[] = [
407
            'class' => 'item-course-field',
408
            'url' => '/main/admin/extra_fields.php?'.http_build_query(['type' => 'course']),
409
            'label' => $this->translator->trans('Manage extra fields for courses'),
410
        ];
411
        $items[] = [
412
            'class' => 'item-question-bank',
413
            'url' => '/main/admin/questions.php',
414
            'label' => $this->translator->trans('Questions'),
415
        ];
416
        $items[] = [
417
            'class' => 'item-resource-sequence',
418
            'url' => '/main/admin/resource_sequence.php?'.http_build_query(['type' => SequenceResource::COURSE_TYPE]),
419
            'label' => $this->translator->trans('Resources sequencing'),
420
        ];
421
422
        return $items;
423
    }
424
425
    private function getItemsPlatform(): array
426
    {
427
        $items = [];
428
        $items[] = [
429
            'class' => 'item-setting-list',
430
            'url' => $this->generateUrl('admin_settings'),
431
            'label' => $this->translator->trans('Configuration settings'),
432
        ];
433
        $items[] = [
434
            'class' => 'item-language-list',
435
            'url' => '/main/admin/languages.php',
436
            'label' => $this->translator->trans('Languages'),
437
        ];
438
        $items[] = [
439
            'class' => 'item-plugin-list',
440
            'url' => '/main/admin/settings.php?'.http_build_query(['category' => 'Plugins']),
441
            'label' => $this->translator->trans('Plugins'),
442
        ];
443
        $items[] = [
444
            'class' => 'item-region-list',
445
            'url' => '/main/admin/settings.php?'.http_build_query(['category' => 'Regions']),
446
            'label' => $this->translator->trans('Regions'),
447
        ];
448
        $items[] = [
449
            'class' => 'item-global-announcement',
450
            'url' => '/main/admin/system_announcements.php',
451
            'label' => $this->translator->trans('Portal news'),
452
        ];
453
        $items[] = [
454
            'class' => 'item-global-agenda',
455
            'route' => ['name' => 'CCalendarEventList', 'query' => ['type' => 'global']],
456
            'label' => $this->translator->trans('Global agenda'),
457
        ];
458
        $items[] = [
459
            'class' => 'item-agenda-reminders',
460
            'url' => '/main/admin/import_course_agenda_reminders.php',
461
            'label' => $this->translator->trans('Import course events'),
462
        ];
463
        $items[] = [
464
            'class' => 'item-pages-list',
465
            'route' => ['name' => 'PageList'],
466
            'label' => $this->translator->trans('Pages'),
467
        ];
468
        /*
469
         * Disabled until differentiated with Pages, and reviewed - see GH#6404
470
        $items[] = [
471
            'class' => 'item-page-layouts',
472
            'route' => ['name' => 'PageLayoutList'],
473
            'label' => $this->translator->trans('Page layouts'),
474
        ];
475
        */
476
        $items[] = [
477
            'class' => 'item-registration-page',
478
            'url' => '/main/auth/registration.php?'.http_build_query(['create_intro_page' => 1]),
479
            'label' => $this->translator->trans('Setting the registration page'),
480
        ];
481
        $items[] = [
482
            'class' => 'item-stats',
483
            'url' => '/main/admin/statistics/index.php',
484
            'label' => $this->translator->trans('Statistics'),
485
        ];
486
        $items[] = [
487
            'class' => 'item-stats-report',
488
            'url' => '/main/my_space/company_reports.php',
489
            'label' => $this->translator->trans('Reports'),
490
        ];
491
        $items[] = [
492
            'class' => 'item-teacher-time-report',
493
            'url' => '/main/admin/teacher_time_report.php',
494
            'label' => $this->translator->trans('Teachers time report'),
495
        ];
496
497
        if (api_get_configuration_value('chamilo_cms')) {
498
            $items[] = [
499
                'class' => 'item-cms',
500
                'url' => api_get_path(WEB_PATH).'web/app_dev.php/administration/dashboard',
501
                'label' => $this->translator->trans('CMS'),
502
            ];
503
        }
504
505
        /* Event settings */
506
507
        $items[] = [
508
            'class' => 'item-field',
509
            'url' => '/main/admin/extra_field_list.php',
510
            'label' => $this->translator->trans('Extra fields'),
511
        ];
512
513
        if (api_is_global_platform_admin()) {
514
            $items[] = [
515
                'class' => 'item-access-url',
516
                'url' => '/main/admin/access_urls.php',
517
                'label' => $this->translator->trans('Configure multiple access URL'),
518
            ];
519
        }
520
521
        if ('true' === api_get_plugin_setting('dictionary', 'enable_plugin_dictionary')) {
522
            $items[] = [
523
                'class' => 'item-dictionary',
524
                'url' => api_get_path(WEB_PLUGIN_PATH).'Dictionary/terms.php',
525
                'label' => $this->translator->trans('Dictionary'),
526
            ];
527
        }
528
529
        if ('true' === $this->settingsManager->getSetting('registration.allow_terms_conditions', true)) {
530
            $items[] = [
531
                'class' => 'item-terms-and-conditions',
532
                'route' => ['name' => 'TermsConditionsList'],
533
                'label' => $this->translator->trans('Terms and Conditions'),
534
            ];
535
        }
536
537
        $items[] = [
538
            'class' => 'item-mail-template',
539
            'url' => '/main/mail_template/list.php',
540
            'label' => $this->translator->trans('Mail templates'),
541
        ];
542
543
        if ('true' === api_get_setting('platform.notification_event')) {
544
            $items[] = [
545
                'class' => 'item-notification-list',
546
                'url' => '/main/notification_event/list.php',
547
                'label' => $this->translator->trans('Notifications'),
548
            ];
549
        }
550
551
        $allowJustification = 'true' === api_get_plugin_setting('justification', 'tool_enable');
552
553
        if ($allowJustification) {
554
            $items[] = [
555
                'class' => 'item-justification-list',
556
                'url' => api_get_path(WEB_PLUGIN_PATH).'Justification/list.php',
557
                'label' => $this->translator->trans('Justification'),
558
            ];
559
        }
560
561
        $items[] = [
562
            'class' => 'item-lti-admin',
563
            'url' => $this->generateUrl('chamilo_lti_admin'),
564
            'label' => $this->translator->trans('External tools (LTI)'),
565
        ];
566
567
        $items[] = [
568
            'class' => 'item-contact-category-admin',
569
            'url' => $this->generateUrl('chamilo_contact_category_index'),
570
            'label' => $this->translator->trans('Contact form categories'),
571
        ];
572
573
        $items[] = [
574
            'class' => 'item-system-template-admin',
575
            'url' => '/main/admin/settings.php?'.http_build_query(['category' => 'Templates']),
576
            'label' => $this->translator->trans('System templates'),
577
        ];
578
579
        return $items;
580
    }
581
582
    private function getItemsSettings(): array
583
    {
584
        $items = [];
585
        $items[] = [
586
            'class' => 'item-cleanup-temp-uploads',
587
            'url' => '/admin/cleanup-temp-uploads',
588
            'label' => $this->translator->trans('Clean temporary files'),
589
        ];
590
591
        $items[] = [
592
            'class' => 'item-special-export',
593
            'url' => '/main/admin/special_exports.php',
594
            'label' => $this->translator->trans('Special exports'),
595
        ];
596
        /*$items[] = [
597
            'url' => '/main/admin/periodic_export.php',
598
            'label' => $this->translator->$this->trans('Periodic export'),
599
        ];*/
600
        $items[] = [
601
            'class' => 'item-system-status',
602
            'url' => '/main/admin/system_status.php',
603
            'label' => $this->translator->trans('System status'),
604
        ];
605
        if (is_dir(api_get_path(SYS_TEST_PATH).'datafiller/')) {
606
            $items[] = [
607
                'class' => 'item-data-filler',
608
                'url' => '/main/admin/filler.php',
609
                'label' => $this->translator->trans('Data filler'),
610
            ];
611
        }
612
613
        if (is_dir(api_get_path(SYS_TEST_PATH))) {
614
            $items[] = [
615
                'class' => 'item-email-tester',
616
                'url' => '/main/admin/email_tester.php',
617
                'label' => $this->translator->trans('E-mail tester'),
618
            ];
619
        }
620
621
        $items[] = [
622
            'class' => 'item-ticket-system',
623
            'url' => '/main/ticket/tickets.php',
624
            'label' => $this->translator->trans('Tickets'),
625
        ];
626
627
        $items[] = [
628
            'url' => '/main/session/cron_status.php',
629
            'label' => $this->translator->trans('Update session status'),
630
        ];
631
632
        $items[] = [
633
            'class' => 'item-colors',
634
            'route' => ['name' => 'AdminConfigurationColors'],
635
            'label' => $this->translator->trans('Colors'),
636
        ];
637
638
        $items[] = [
639
            'class' => 'item-file-info',
640
            'url' => '/admin/files_info',
641
            'label' => $this->translator->trans('File info'),
642
        ];
643
644
        $items[] = [
645
            'class' => 'item-resources-info',
646
            'url' => '/admin/resources_info',
647
            'label' => $this->translator->trans('Resources by type'),
648
        ];
649
650
        return $items;
651
    }
652
653
    private function getItemsSkills(): array
654
    {
655
        $items = [];
656
        $items[] = [
657
            'class' => 'item-skill-wheel',
658
            'route' => ['name' => 'SkillWheel'],
659
            'label' => $this->translator->trans('Skills wheel'),
660
        ];
661
        $items[] = [
662
            'class' => 'item-skill-import',
663
            'url' => '/main/skills/skills_import.php',
664
            'label' => $this->translator->trans('Skills import'),
665
        ];
666
        $items[] = [
667
            'class' => 'item-skill-list',
668
            'url' => '/main/skills/skill_list.php',
669
            'label' => $this->translator->trans('Manage skills'),
670
        ];
671
        $items[] = [
672
            'class' => 'item-skill-level',
673
            'url' => '/main/skills/skill.php',
674
            'label' => $this->translator->trans('Manage skills levels'),
675
        ];
676
677
        $items[] = [
678
            'class' => 'item-skill-ranking',
679
            'url' => '/main/social/skills_ranking.php',
680
            'label' => $this->translator->trans('Skills ranking'),
681
        ];
682
        $items[] = [
683
            'class' => 'item-skill-gradebook',
684
            'url' => '/main/skills/skills_gradebook.php',
685
            'label' => $this->translator->trans('Skills and assessments'),
686
        ];
687
688
        /*$items[] = [
689
            'url' => '/main/admin/skill_badge.php',
690
            'label' => $this->translator->trans('Badges'),
691
        ];*/
692
693
        return $items;
694
    }
695
696
    private function getItemsGradebook(): array
697
    {
698
        $items = [];
699
        $items[] = [
700
            'class' => 'item-gradebook-list',
701
            'url' => '/main/admin/gradebook_list.php',
702
            'label' => $this->translator->trans('List'),
703
        ];
704
705
        return $items;
706
    }
707
708
    private function getItemsPrivacy(): array
709
    {
710
        $items = [];
711
        $items[] = [
712
            'class' => 'item-privacy-consent',
713
            'url' => '/main/admin/user_list_consent.php',
714
            'label' => $this->translator->trans('User list'),
715
        ];
716
        $items[] = [
717
            'class' => 'item-gdpr-parties',
718
            'route' => ['name' => 'ThirdPartyManager'],
719
            'label' => $this->translator->trans('Third parties (GDPR)'),
720
        ];
721
722
        return $items;
723
    }
724
725
    private function getItemsChamilo(): array
726
    {
727
        $languageInterface = api_get_language_isocode();
728
729
        $items = [];
730
        $items[] = [
731
            'class' => 'item-software-homepage',
732
            'url' => 'https://chamilo.org/',
733
            'label' => $this->translator->trans('Chamilo homepage'),
734
        ];
735
736
        // Custom linking to user guides in the existing languages
737
        /*$guideLinks = [
738
            'french' => 'v/1.11.x-fr/',
739
            'spanish' => 'v/1.11.x-es/',
740
            'dutch' => 'v/1.11.x-nl/',
741
            'galician' => 'v/1.11.x-ga/',
742
        ];*/
743
744
        $guideLink = 'https://docs.chamilo.org/';
745
746
        /*if (!empty($guideLinks[$languageInterface])) {
747
            $guideLink .= $guideLinks[$languageInterface];
748
        }*/
749
750
        $items[] = [
751
            'class' => 'item-user-guides',
752
            'url' => $guideLink,
753
            'label' => $this->translator->trans('User guides'),
754
        ];
755
        $items[] = [
756
            'class' => 'item-forum',
757
            'url' => 'https://github.com/chamilo/chamilo-lms/discussions/',
758
            'label' => $this->translator->trans('Chamilo forum'),
759
        ];
760
        $items[] = [
761
            'class' => 'item-installation-guide',
762
            'url' => '/documentation/installation_guide.html',
763
            'label' => $this->translator->trans('Installation guide'),
764
        ];
765
        $items[] = [
766
            'class' => 'item-changelog',
767
            'url' => '/documentation/changelog.html',
768
            'label' => $this->translator->trans('Changes in last version'),
769
        ];
770
        $items[] = [
771
            'class' => 'item-credits',
772
            'url' => '/documentation/credits.html',
773
            'label' => $this->translator->trans('Contributors list'),
774
        ];
775
        $items[] = [
776
            'class' => 'item-security',
777
            'url' => '/documentation/security.html',
778
            'label' => $this->translator->trans('Security guide'),
779
        ];
780
        $items[] = [
781
            'class' => 'item-optimization',
782
            'url' => '/documentation/optimization.html',
783
            'label' => $this->translator->trans('Optimization guide'),
784
        ];
785
        $items[] = [
786
            'class' => 'item-extensions',
787
            'url' => 'https://chamilo.org/extensions',
788
            'label' => $this->translator->trans('Chamilo extensions'),
789
        ];
790
        $items[] = [
791
            'class' => 'item-providers',
792
            'url' => 'https://chamilo.org/providers',
793
            'label' => $this->translator->trans('Chamilo official services providers'),
794
        ];
795
796
        return $items;
797
    }
798
799
    private function getItemsSessions(): array
800
    {
801
        $items = [];
802
        $items[] = [
803
            'class' => 'item-session-list',
804
            'url' => '/main/session/session_list.php',
805
            'label' => $this->translator->trans('Training sessions list'),
806
        ];
807
        $items[] = [
808
            'class' => 'item-session-add',
809
            'url' => '/main/session/session_add.php',
810
            'label' => $this->translator->trans('Add a training session'),
811
        ];
812
        $items[] = [
813
            'class' => 'item-session-category',
814
            'url' => '/main/session/session_category_list.php',
815
            'label' => $this->translator->trans('Sessions categories list'),
816
        ];
817
        $items[] = [
818
            'class' => 'item-session-import',
819
            'url' => '/main/session/session_import.php',
820
            'label' => $this->translator->trans('Import sessions list'),
821
        ];
822
        $items[] = [
823
            'class' => 'item-session-import-hr',
824
            'url' => '/main/session/session_import_drh.php',
825
            'label' => $this->translator->trans('Import list of HR directors into sessions'),
826
        ];
827
828
        if ($this->isLdapActive) {
829
            $items[] = [
830
                'class' => 'item-session-subscription-ldap-import',
831
                'url' => '/main/admin/ldap_import_students_to_session.php',
832
                'label' => $this->translator->trans('Import LDAP users into a session'),
833
            ];
834
        }
835
836
        $items[] = [
837
            'class' => 'item-session-export',
838
            'url' => '/main/session/session_export.php',
839
            'label' => $this->translator->trans('Export sessions list'),
840
        ];
841
842
        $items[] = [
843
            'class' => 'item-session-course-copy',
844
            'url' => '/main/coursecopy/copy_course_session.php',
845
            'label' => $this->translator->trans('Copy from course in session to another session'),
846
        ];
847
848
        $allowCareer = $this->settingsManager->getSetting('session.allow_session_admin_read_careers');
849
850
        if ($this->isAdmin || ('true' === $allowCareer && $this->isSessionAdmin)) {
851
            // Disabled until it is reemplemented to work with Chamilo 2
852
            /*                $items[] = [
853
                                'class' => 'item-session-user-move-stats',
854
                                'url' => '/main/admin/user_move_stats.php',
855
                                'label' => $this->translator->trans('Move users results from/to a session'),
856
                            ];
857
             */
858
            $items[] = [
859
                'class' => 'item-session-user-move',
860
                'url' => '/main/coursecopy/move_users_from_course_to_session.php',
861
                'label' => $this->translator->trans('Move users results from base course to a session'),
862
            ];
863
864
            $items[] = [
865
                'class' => 'item-career-dashboard',
866
                'url' => '/main/admin/career_dashboard.php',
867
                'label' => $this->translator->trans('Careers and promotions'),
868
            ];
869
            $items[] = [
870
                'class' => 'item-session-field',
871
                'url' => '/main/admin/extra_fields.php?'.http_build_query(['type' => 'session']),
872
                'label' => $this->translator->trans('Manage session fields'),
873
            ];
874
            $items[] = [
875
                'class' => 'item-resource-sequence',
876
                'url' => '/main/admin/resource_sequence.php?'.http_build_query(['type' => SequenceResource::SESSION_TYPE]),
877
                'label' => $this->translator->trans('Resources sequencing'),
878
            ];
879
            $items[] = [
880
                'class' => 'item-export-exercise-results',
881
                'url' => '/main/admin/export_exercise_results.php',
882
                'label' => $this->translator->trans('Export all results from an exercise'),
883
            ];
884
        }
885
886
        return $items;
887
    }
888
889
    private function getItemsPlugins(): array
890
    {
891
        $items = [];
892
893
        $accessUrl = $this->accessUrlHelper->getCurrent();
894
        $appPlugin = new AppPlugin();
895
        $plugins = $this->pluginRepository->getInstalledPlugins();
896
897
        foreach ($plugins as $plugin) {
898
            // getPluginInfo() might fail to build the plugin object; never assume 'obj' exists
899
            $pluginInfo = $appPlugin->getPluginInfo($plugin->getTitle());
900
901
            // Normalize/fallbacks
902
            if (!\is_array($pluginInfo)) {
903
                // Defensive: unexpected structure → skip
904
                error_log(\sprintf('[admin:index] Plugin "%s" has no pluginInfo array, skipping.', $plugin->getTitle()));
905
906
                continue;
907
            }
908
909
            /** @var Plugin|null $objPlugin */
910
            $objPlugin = $pluginInfo['obj'] ?? null;
911
912
            if (!$objPlugin instanceof Plugin) {
913
                // Defensive: plugin could not be instantiated (e.g. throws in constructor)
914
                error_log(\sprintf('[admin:index] Plugin "%s" has no valid "obj" (instance of Plugin), skipping.', $plugin->getTitle()));
915
916
                continue;
917
            }
918
919
            // Per-URL configuration
920
            $pluginInUrl = $plugin->getOrCreatePluginConfiguration($accessUrl);
921
            $configuration = $pluginInUrl->getConfiguration() ?: [];
922
923
            if (!$configuration || !isset($configuration['regions'])) {
924
                continue;
925
            }
926
927
            // Only show plugins that declare the admin menu region
928
            if (!\in_array('menu_administrator', $configuration['regions'], true)) {
929
                continue;
930
            }
931
932
            // Build admin URL defensively (some plugins may throw when building URLs)
933
            try {
934
                $adminUrl = $objPlugin->getAdminUrl();
935
            } catch (Throwable $e) {
936
                error_log(\sprintf('[admin:index] Plugin "%s" getAdminUrl() failed: %s', $plugin->getTitle(), $e->getMessage()));
937
938
                continue;
939
            }
940
941
            // Label fallback to DB title if pluginInfo misses 'title'
942
            $label = (string) ($pluginInfo['title'] ?? $plugin->getTitle());
943
944
            $items[] = [
945
                'class' => 'item-plugin-'.strtolower($plugin->getTitle()),
946
                'url' => $adminUrl,
947
                'label' => $label,
948
            ];
949
        }
950
951
        return $items;
952
    }
953
954
    private function getItemsHealthCheck(): array
955
    {
956
        $items = [];
957
958
        // Check if dsn or email is defined :
959
        $mailDsn = $this->settingsManager->getSetting('mail.mailer_dsn', true);
960
        $mailSender = $this->settingsManager->getSetting('mail.mailer_from_email', true);
961
        $nameSender = $this->settingsManager->getSetting('mail.mailer_from_name', true);
962
        if ((empty($mailDsn) || 'null://null' == $mailDsn) || empty($mailSender) || empty($nameSender)) {
963
            $items[] = [
964
                'className' => 'item-health-check-mail-settings text-error',
965
                'url' => '/admin/settings/mail',
966
                'label' => $this->translator->trans('E-mail settings need to be configured'),
967
            ];
968
        } else {
969
            $items[] = [
970
                'className' => 'item-health-check-mail-settings text-success',
971
                'url' => '/admin/settings/mail',
972
                'label' => $this->translator->trans('E-mail settings are OK'),
973
            ];
974
        }
975
976
        // Check if the admin user has access to all URLs
977
        if (api_is_admin_in_all_active_urls()) {
978
            $items[] = [
979
                'className' => 'item-health-check-admin-urls text-success',
980
                'url' => '/main/admin/access_urls.php',
981
                'label' => $this->translator->trans('All URLs have at least one admin assigned'),
982
            ];
983
        } else {
984
            $items[] = [
985
                'className' => 'item-health-check-admin-urls text-error',
986
                'url' => '/main/admin/access_url_edit_users_to_url.php',
987
                'label' => $this->translator->trans('At least one URL has no admin assigned'),
988
            ];
989
        }
990
991
        return $items;
992
    }
993
}
994