Passed
Push — master ( 935c75...ae7ec4 )
by Angel Fernando Quiroz
10:05
created

IndexBlocksController::getExtraContent()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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