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

IndexBlocksController::getItemsHealthCheck()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
cc 6
eloc 25
c 2
b 1
f 1
nc 4
nop 0
dl 0
loc 38
rs 8.8977
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