Proyectos de Subversion Moodle

Rev

Rev 1294 | Rev 1296 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
256 ariadna 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
901 ariadna 17
namespace theme_universe_child\output;
256 ariadna 18
 
19
use html_writer;
20
use stdClass;
21
use moodle_url;
22
use context_course;
23
use context_system;
24
use core_course_list_element;
25
use custom_menu;
26
use action_menu_filler;
27
use action_menu_link_secondary;
28
use action_menu;
29
use action_link;
30
use core_text;
31
use coding_exception;
32
use navigation_node;
33
use context_header;
891 ariadna 34
use core\oauth2\rest;
256 ariadna 35
use pix_icon;
36
use renderer_base;
37
use theme_config;
38
use get_string;
39
use core_course_category;
40
use theme_universe\util\user;
41
use theme_universe\util\course;
901 ariadna 42
use core_completion\progress;
256 ariadna 43
 
44
require_once($CFG->dirroot . '/cesa/statics_blocks.php'); // Incluimos StaticsBlocks
45
 
46
 
47
/**
48
 * Renderers to align Moodle's HTML with that expected by Bootstrap
49
 *
50
 * @package    theme_universe
51
 * @copyright  2023 Marcin Czaja (https://rosea.io)
52
 * @license    Commercial https://themeforest.net/licenses
53
 */
1291 ariadna 54
class core_renderer extends \theme_universe\output\core_renderer
55
{
56
 
1295 ariadna 57
    public function edit_button(moodle_url $url, string $method = 'post')
1291 ariadna 58
    {
1295 ariadna 59
        if ($this->page->theme->haseditswitch) {
60
            return;
61
        }
62
        $url->param('sesskey', sesskey());
63
        if ($this->page->user_is_editing()) {
64
            $url->param('edit', 'off');
65
            $editstring = get_string('turneditingoff');
66
        } else {
67
            $url->param('edit', 'on');
68
            $editstring = get_string('turneditingon');
69
        }
70
        $button = new \single_button($url, $editstring, 'post', ['class' => 'btn btn-primary']);
71
        return $this->render_single_button($button);
72
    }
73
 
74
    /**
75
     * The standard tags (meta tags, links to stylesheets and JavaScript, etc.)
76
     * that should be included in the <head> tag. Designed to be called in theme
77
     * layout.php files.
78
     *
79
     * @return string HTML fragment.
80
     */
81
    public function standard_head_html()
82
    {
83
        $output = parent::standard_head_html();
1291 ariadna 84
        global $USER;
85
 
1295 ariadna 86
        $googleanalyticscode = "<script
87
                                    async
88
                                    src='https://www.googletagmanager.com/gtag/js?id=GOOGLE-ANALYTICS-CODE'>
89
                                </script>
90
                                <script>
91
                                    window.dataLayer = window.dataLayer || [];
92
                                    function gtag() {
93
                                        dataLayer.push(arguments);
94
                                    }
95
                                    gtag('js', new Date());
96
                                    gtag('config', 'GOOGLE-ANALYTICS-CODE');
97
                                </script>";
98
 
99
        $theme = theme_config::load('universe');
100
 
101
        if (!empty($theme->settings->googleanalytics) && isloggedin()) {
102
            $output .= str_replace(
103
                "GOOGLE-ANALYTICS-CODE",
104
                trim($theme->settings->googleanalytics),
105
                $googleanalyticscode
106
            );
107
        }
108
 
109
        return $output;
110
    }
111
 
112
    /**
113
     *
114
     * Method to load theme element form 'layout/parts' folder
115
     *
116
     */
117
    public function theme_part($name, $vars = array())
118
    {
119
 
120
        global $CFG;
121
 
122
        $element = $name . '.php';
123
        $candidate1 = $this->page->theme->dir . '/layout/parts/' . $element;
124
 
125
        // Require for child theme.
126
        if (file_exists($candidate1)) {
127
            $candidate = $candidate1;
128
        } else {
129
            $candidate = $CFG->dirroot . theme_universe_child_themedir() . '/universe_child/layout/parts/' . $element;
130
        }
131
 
132
        if (!is_readable($candidate)) {
133
            debugging("Could not include element $name.");
134
            return;
135
        }
136
 
137
        ob_start();
138
        include($candidate);
139
        $output = ob_get_clean();
140
        return $output;
141
    }
142
 
143
    /**
144
     * Renders the custom menu
145
     *
146
     * @param custom_menu $menu
147
     * @return mixed
148
     */
149
    protected function render_custom_menu(custom_menu $menu)
150
    {
151
        if (!$menu->has_children()) {
152
            return '';
153
        }
154
 
155
        $content = '';
156
        foreach ($menu->get_children() as $item) {
157
            $context = $item->export_for_template($this);
158
            $content .= $this->render_from_template('core/moremenu_children', $context);
159
        }
160
 
161
        return $content;
162
    }
163
 
164
    /**
165
     * Outputs the favicon urlbase.
166
     *
167
     * @return string an url
168
     */
169
    public function favicon()
170
    {
171
        global $CFG;
172
        $theme = theme_config::load('universe');
173
        $favicon = $theme->setting_file_url('favicon', 'favicon');
174
 
175
        if (!empty(($favicon))) {
176
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
177
            $favicon = str_replace($urlreplace, '', $favicon);
178
 
179
            return new moodle_url($favicon);
180
        }
181
 
182
        return parent::favicon();
183
    }
184
 
185
    public function render_lang_menu()
186
    {
187
        $langs = get_string_manager()->get_list_of_translations();
188
        $haslangmenu = $this->lang_menu() != '';
189
        $menu = new custom_menu;
190
 
191
        if ($haslangmenu) {
192
            $strlang = get_string('language');
193
            $currentlang = current_language();
194
            if (isset($langs[$currentlang])) {
195
                $currentlang = $langs[$currentlang];
196
            } else {
197
                $currentlang = $strlang;
198
            }
199
            $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
200
            foreach ($langs as $langtype => $langname) {
201
                $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
202
            }
203
            foreach ($menu->get_children() as $item) {
204
                $context = $item->export_for_template($this);
205
            }
206
 
207
            $context->currentlangname = array_search($currentlang, $langs);
208
 
209
            if (isset($context)) {
210
                return $this->render_from_template('theme_universe/lang_menu', $context);
211
            }
212
        }
213
    }
214
 
215
    public function render_lang_menu_login()
216
    {
217
        $langs = get_string_manager()->get_list_of_translations();
218
        $haslangmenu = $this->lang_menu() != '';
219
        $menu = new custom_menu;
220
 
221
        if ($haslangmenu) {
222
            $strlang = get_string('language');
223
            $currentlang = current_language();
224
            if (isset($langs[$currentlang])) {
225
                $currentlang = $langs[$currentlang];
226
            } else {
227
                $currentlang = $strlang;
228
            }
229
            $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
230
            foreach ($langs as $langtype => $langname) {
231
                $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
232
            }
233
            foreach ($menu->get_children() as $item) {
234
                $context = $item->export_for_template($this);
235
            }
236
 
237
            $context->currentlangname = array_search($currentlang, $langs);
238
 
239
            if (isset($context)) {
240
                return $this->render_from_template('theme_universe/lang_menu_login', $context);
241
            }
242
        }
243
    }
244
 
245
    public static function get_course_progress_count($course, $userid = 0)
246
    {
247
        global $USER;
248
 
249
        // Make sure we continue with a valid userid.
250
        if (empty($userid)) {
1291 ariadna 251
            $userid = $USER->id;
252
        }
253
 
1295 ariadna 254
        $completion = new \completion_info($course);
255
 
256
        // First, let's make sure completion is enabled.
257
        if (!$completion->is_enabled()) {
258
            return null;
259
        }
260
 
261
        if (!$completion->is_tracked_user($userid)) {
262
            return null;
263
        }
264
 
265
        // Before we check how many modules have been completed see if the course has.
266
        if ($completion->is_course_complete($userid)) {
267
            return 100;
268
        }
269
 
270
        // Get the number of modules that support completion.
271
        $modules = $completion->get_activities();
272
        $count = count($modules);
273
        if (!$count) {
274
            return null;
275
        }
276
 
277
        // Get the number of modules that have been completed.
278
        $completed = 0;
279
        foreach ($modules as $module) {
280
            $data = $completion->get_data($module, true, $userid);
281
            $completed += $data->completionstate == COMPLETION_INCOMPLETE ? 0 : 1;
282
        }
283
 
284
        return ($completed / $count) * 100;
285
    }
286
 
287
    /**
288
     *
289
     * Outputs the course progress if course completion is on.
290
     *
291
     * @return string Markup.
292
     */
293
    protected function courseprogress($course)
294
    {
295
        global $USER;
296
        $theme = \theme_config::load('universe');
297
 
298
        $output = '';
299
        $courseformat = course_get_format($course);
300
 
301
        if (get_class($courseformat) != 'format_tiles') {
302
            $completion = new \completion_info($course);
303
 
304
            // Start Course progress count.
305
            // Make sure we continue with a valid userid.
306
            if (empty($userid)) {
307
                $userid = $USER->id;
308
            }
309
            $completion = new \completion_info($course);
310
 
311
            // Get the number of modules that support completion.
312
            $modules = $completion->get_activities();
313
            $count = count($modules);
314
            if (!$count) {
315
                return null;
316
            }
317
 
318
            // Get the number of modules that have been completed.
319
            $completed = 0;
320
            foreach ($modules as $module) {
321
                $data = $completion->get_data($module, true, $userid);
322
                $completed += $data->completionstate == COMPLETION_INCOMPLETE ? 0 : 1;
323
            }
324
            $progresscountc = $completed;
325
            $progresscounttotal = $count;
326
            // End progress count.
327
 
328
            if ($completion->is_enabled()) {
329
                $templatedata = new \stdClass;
330
                $templatedata->progress = \core_completion\progress::get_course_progress_percentage($course);
331
                $templatedata->progresscountc = $progresscountc;
332
                $templatedata->progresscounttotal = $progresscounttotal;
333
 
334
                if (!is_null($templatedata->progress)) {
335
                    $templatedata->progress = floor($templatedata->progress);
336
                } else {
337
                    $templatedata->progress = 0;
338
                }
339
                if (get_config('theme_universe', 'courseprogressbar') == 1) {
340
                    $progressbar = '<div class="rui-course-progresschart">' .
341
                        $this->render_from_template('theme_universe/progress-chart', $templatedata) .
342
                        '</div>';
343
                    if (has_capability('report/progress:view',  \context_course::instance($course->id))) {
344
                        $courseprogress = new \moodle_url('/report/progress/index.php');
345
                        $courseprogress->param('course', $course->id);
346
                        $courseprogress->param('sesskey', sesskey());
347
                        $output .= html_writer::link($courseprogress, $progressbar, array('class' => 'rui-course-progressbar border rounded px-3 pt-2 mb-3'));
348
                    } else {
349
                        $output .= $progressbar;
350
                    }
351
                }
352
            }
353
        }
354
 
355
        return $output;
356
    }
357
 
358
 
359
    /**
360
     *
361
     * Returns HTML to display course contacts.
362
     *
363
     */
364
    public function course_teachers()
365
    {
366
        global $CFG, $COURSE, $DB;
367
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
368
        $course = new core_course_list_element($course);
369
        $instructors = $course->get_course_contacts();
370
 
371
        if (!empty($instructors)) {
372
            $content = html_writer::start_div('course-teachers-box');
373
 
374
            foreach ($instructors as $key => $instructor) {
375
                $name = $instructor['username'];
376
                $role = $instructor['rolename'];
377
                $roleshortname = $instructor['role']->shortname;
378
 
379
                if ($instructor['role']->id == '3') {
380
                    $url = $CFG->wwwroot . '/user/profile.php?id=' . $key;
381
                    $user = $instructor['user'];
382
                    $userutil = new user($user->id);
383
                    $picture = $userutil->get_user_picture();
384
 
385
                    $content .= "<div class='course-contact-title-item'>
386
                        <a href='{$url}' 'title='{$name}'
387
                            class='course-contact rui-user-{$roleshortname}'>";
388
                    $content .= "<img src='{$picture}'
389
                        class='course-teacher-avatar' alt='{$name}'
390
                        title='{$name} - {$role}' data-toggle='tooltip'/>";
391
                    $content .= "<div class='course-teacher-content'>
392
                        <span class='course-teacher-role'>{$role}</span>
393
                        <h4 class='course-teacher-name'>{$name}</h4></div>";
394
                    $content .= "</a></div>";
395
                }
396
            }
397
 
398
            $content .= html_writer::end_div(); // End .teachers-box.
399
            return $content;
400
        }
401
    }
402
 
403
    public function course_contacts()
404
    {
405
        global $CFG, $COURSE, $DB;
406
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
407
        $course = new core_course_list_element($course);
408
        $instructors = $course->get_course_contacts();
409
 
410
        if (!empty($instructors)) {
411
            $content = html_writer::start_div('course-teachers-box w-100');
412
 
413
            foreach ($instructors as $key => $instructor) {
414
                $name = $instructor['username'];
415
                $role = $instructor['rolename'];
416
                $roleshortname = $instructor['role']->shortname;
417
 
418
                $url = $CFG->wwwroot . '/user/profile.php?id=' . $key;
419
                $user = $instructor['user'];
420
                $userutil = new user($user->id);
421
                $picture = $userutil->get_user_picture(384);
422
 
423
                $user = $DB->get_record('user', array('id' => $key));
424
                $desc = $user->description;
425
 
426
                $content .= "<div class='rui-block-team-item text-center text-md-left
427
                    d-inline-flex flex-wrap align-items-start align-items-md-center'>";
428
                $content .= "<div class='rui-card-team--img-smpl'><img src='{$picture}'
429
                    class='rui-card-team--img-smpl mr-3 mr-md-5'
430
                    alt='{$name}, {$role}'/></div>";
431
                $content .= "<div class='rui-course-teacher--item col px-0 text-left'>
432
                    <a href='{$url}' 'title='{$name}'
433
                        class='course-contact rui-user-{$roleshortname}'>
434
                        <h4 class='mb-0'>{$name}</h4></a>
435
                        <span class='rui-block-text--3 rui-block-text--light mb-3'>{$role}</span>";
436
                $content .= "<div class='rui-block-text--2 mt-2'>{$desc}</div></div></div>";
437
            }
438
            $content .= html_writer::end_div(); // End .teachers-box.
439
            return $content;
440
        }
441
    }
442
 
443
    /**
444
     *
445
     * Returns HTML to display course details.
446
     *
447
     */
448
    protected function course_details()
449
    {
450
        global $CFG, $COURSE, $DB;
451
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
452
        $course = new core_course_list_element($course);
453
        $content = '';
454
        $tempcourse = $DB->get_record('course_categories', ['id' => $COURSE->id]);
455
 
456
        $content .= html_writer::start_div('rui-course-details mt-4');
457
        $content .= html_writer::start_div('rui-custom-field-box rui-course-startdate');
458
        $content .= html_writer::tag('span', get_string('startdate', 'moodle'), ['class' => 'rui-custom-field-name']);
459
        $content .= html_writer::tag('span', date("F j, Y", $COURSE->startdate), ['class' => 'rui-custom-field-value']);
460
        $content .= html_writer::end_div();
461
 
462
        // Course End date.
463
        $courseenddate = $COURSE->enddate;
464
        if ($courseenddate != '0') {
465
            $content .= html_writer::start_div('rui-custom-field-box rui-course-startdate');
466
            $content .= html_writer::tag('span', get_string('enddate', 'moodle'), ['class' => 'rui-course-enddate-label rui-custom-field-name']);
467
            $content .= html_writer::tag('span', date("F j, Y", $courseenddate), ['class' => 'rui-course-enddate rui-custom-field-value']);
468
            $content .= html_writer::end_div();
469
        }
470
        $content .= html_writer::end_div(); // .rui-course-details.
471
 
472
        return $content;
473
    }
474
 
475
    /**
476
     *
477
     * Returns HTML to display course summary.
478
     *
479
     */
480
    protected function course_summary($courseid = 0, $content = '')
481
    {
482
        global $COURSE, $CFG;
483
        $output = '';
484
 
485
        require_once($CFG->libdir . '/filelib.php');
486
 
487
        $iscourseid = $courseid ? $courseid : $COURSE->id;
488
        $iscontent = $content ? $content : $COURSE->summary;
489
        $context = context_course::instance($iscourseid);
490
        $desc = file_rewrite_pluginfile_urls($iscontent, 'pluginfile.php', $context->id, 'course', 'summary', null);
491
 
492
        $output .= html_writer::start_div('rui-course-desc');
493
        $output .= format_text($desc, FORMAT_HTML);
494
        $output .= html_writer::end_div();
495
 
496
        return $output;
497
    }
498
 
499
    /**
500
     * Outputs the pix url base
501
     *
502
     * @return string an URL.
503
     */
504
    public function get_pix_image_url_base()
505
    {
506
        global $CFG;
507
 
508
        return $CFG->wwwroot . "/theme/universe/pix";
509
    }
510
 
511
    /**
512
     *
513
     */
514
    public function course_hero_url()
515
    {
516
        global $CFG, $COURSE, $DB;
517
 
518
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
519
 
520
        $course = new core_course_list_element($course);
521
 
522
        $courseimage = '';
523
        $imageindex = 1;
524
        foreach ($course->get_course_overviewfiles() as $file) {
525
            $isimage = $file->is_valid_image();
526
 
527
            $url = new moodle_url("$CFG->wwwroot/pluginfile.php" . '/' .
528
                $file->get_contextid() . '/' . $file->get_component() . '/' .
529
                $file->get_filearea() .
530
                $file->get_filepath() .
531
                $file->get_filename(), ['forcedownload' => !$isimage]);
532
 
533
            if ($isimage) {
534
                $courseimage = $url;
535
            }
536
 
537
            if ($imageindex == 2) {
538
                break;
539
            }
540
 
541
            $imageindex++;
542
        }
543
 
544
        $html = '';
545
        // Create html for header.
546
        if (!empty($courseimage)) {
547
            $html .= $courseimage;
548
        }
549
        return $html;
550
    }
551
 
552
    /**
553
     * Returns HTML to display course hero.
554
     *
555
     */
556
    public function course_hero()
557
    {
558
        global $CFG, $COURSE, $DB;
559
 
560
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
561
 
562
        $course = new core_course_list_element($course);
563
 
564
        $courseimage = '';
565
 
566
        $courseutil = new course($course);
567
        $courseimage = $courseutil->get_summary_image(false); // Remove repeatable pattern on the course page.
568
 
569
        $html = '';
570
        // Create html for header.
571
        if (!empty($courseimage)) {
572
            $html .= $courseimage;
573
        }
574
        return $html;
575
    }
576
 
577
 
578
 
579
 
580
    /**
581
     * Breadcrumbs
582
     *
583
     */
584
    public function breadcrumbs()
585
    {
586
        global $USER, $COURSE, $CFG;
587
 
588
        $header = new stdClass();
589
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
590
        $header->navbar = $this->navbar();
591
        $header->courseheader = $this->course_header();
592
        $html = $this->render_from_template('theme_universe/breadcrumbs', $header);
593
 
594
        return $html;
595
    }
596
 
597
 
598
    /**
599
     * Wrapper for header elements.
600
     *
601
     * @return string HTML to display the main header.
602
     */
603
    public function simple_header()
604
    {
605
 
606
        global $USER, $COURSE, $CFG;
607
        $html = null;
608
 
609
        if (
610
            $this->page->include_region_main_settings_in_header_actions() &&
611
            !$this->page->blocks->is_block_present('settings')
612
        ) {
613
            // Only include the region main settings if the page has requested it and it doesn't already have
614
            // the settings block on it. The region main settings are included in the settings block and
615
            // duplicating the content causes behat failures.
616
            $this->page->add_header_action(html_writer::div(
617
                $this->region_main_settings_menu(),
618
                'd-print-none',
619
                ['id' => 'region-main-settings-menu']
620
            ));
621
        }
622
 
623
        $header = new stdClass();
624
        $header->settingsmenu = $this->context_header_settings_menu();
625
        $header->contextheader = $this->context_header();
626
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
627
        $header->navbar = $this->navbar();
628
        $header->pageheadingbutton = $this->page_heading_button();
629
        $header->courseheader = $this->course_header();
630
        $header->headeractions = $this->page->get_header_actions();
631
 
632
        if ($this->page->pagelayout != 'admin') {
633
            $html .= $this->render_from_template('theme_universe/header', $header);
634
        }
635
 
636
        if ($this->page->pagelayout == 'admin') {
637
            $html .= $this->render_from_template('theme_universe/header_admin', $header);
638
        }
639
 
640
        return $html;
641
    }
642
 
643
    public function display_course_progress()
644
    {
645
        $html = null;
646
        $html .= $this->courseprogress($this->page->course);
647
        return $html;
648
    }
649
 
650
    /**
651
     * Wrapper for header elements.
652
     *
653
     * @return string HTML to display the main header.
654
     */
655
    public function full_header()
656
    {
657
        global $USER, $COURSE, $CFG;
658
        $theme = \theme_config::load('universe');
659
        $html = null;
660
        $pagetype = $this->page->pagetype;
661
        $homepage = get_home_page();
662
        $homepagetype = null;
663
        // Add a special case since /my/courses is a part of the /my subsystem.
664
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
665
            $homepagetype = 'my-index';
666
        } else if ($homepage == HOMEPAGE_SITE) {
667
            $homepagetype = 'site-index';
668
        }
669
        if (
670
            $this->page->include_region_main_settings_in_header_actions() &&
671
            !$this->page->blocks->is_block_present('settings')
672
        ) {
673
            // Only include the region main settings if the page has requested it and it doesn't already have
674
            // the settings block on it. The region main settings are included in the settings block and
675
            // duplicating the content causes behat failures.
676
            $this->page->add_header_action(html_writer::div(
677
                $this->region_main_settings_menu(),
678
                'd-print-none',
679
                ['id' => 'region-main-settings-menu']
680
            ));
681
        }
682
 
683
        $header = new stdClass();
684
        $header->settingsmenu = $this->context_header_settings_menu();
685
        $header->contextheader = $this->context_header();
686
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
687
        $header->navbar = $this->navbar();
688
        $header->pageheadingbutton = $this->page_heading_button();
689
        $header->courseheader = $this->course_header();
690
        $header->headeractions = $this->page->get_header_actions();
691
 
692
        if ($this->page->theme->settings->ipcoursedetails == 1) {
693
            $html .= $this->course_details();
694
        }
695
 
696
        $html .= $this->render_from_template('theme_universe/header', $header);
697
        if ($this->page->theme->settings->ipcoursesummary == 1) {
698
            $html .= $this->course_summary();
699
        }
700
 
701
        $html .= html_writer::start_tag('div', array('class' => 'rui-course-header-color'));
702
        if ($this->page->theme->settings->cccteachers == 1) {
703
            $html .= $this->course_teachers();
704
        }
705
 
706
        $html .= html_writer::end_tag('div'); // End .rui-course-header.
707
 
708
        return $html;
709
    }
710
 
711
 
712
    /**
713
     * Wrapper for header elements.
714
     *
715
     * @return string HTML to display the main header.
716
     */
717
    public function clean_header()
718
    {
719
        global $USER, $COURSE, $CFG;
720
        $theme = \theme_config::load('universe');
721
        $html = null;
722
        $pagetype = $this->page->pagetype;
723
        $homepage = get_home_page();
724
        $homepagetype = null;
725
        // Add a special case since /my/courses is a part of the /my subsystem.
726
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
727
            $homepagetype = 'my-index';
728
        } else if ($homepage == HOMEPAGE_SITE) {
729
            $homepagetype = 'site-index';
730
        }
731
        if (
732
            $this->page->include_region_main_settings_in_header_actions() &&
733
            !$this->page->blocks->is_block_present('settings')
734
        ) {
735
            // Only include the region main settings if the page has requested it and it doesn't already have
736
            // the settings block on it. The region main settings are included in the settings block and
737
            // duplicating the content causes behat failures.
738
            $this->page->add_header_action(html_writer::div(
739
                $this->region_main_settings_menu(),
740
                'd-print-none',
741
                ['id' => 'region-main-settings-menu']
742
            ));
743
        }
744
 
745
        $header = new stdClass();
746
        $header->courseheader = $this->course_header();
747
        $header->headeractions = $this->page->get_header_actions();
748
 
749
        $html .= $this->render_from_template('theme_universe/header', $header);
750
 
751
        return $html;
752
    }
753
 
754
 
755
    /**
756
     * Returns standard navigation between activities in a course.
757
     *
758
     * @return string the navigation HTML.
759
     */
760
    public function activity_navigation()
761
    {
762
        // First we should check if we want to add navigation.
763
        $context = $this->page->context;
764
        if (($this->page->pagelayout !== 'incourse' && $this->page->pagelayout !== 'frametop')
765
            || $context->contextlevel != CONTEXT_MODULE
766
        ) {
767
            return '';
768
        }
769
        // If the activity is in stealth mode, show no links.
770
        if ($this->page->cm->is_stealth()) {
771
            return '';
772
        }
773
        $course = $this->page->cm->get_course();
774
        $courseformat = course_get_format($course);
775
 
776
        // Get a list of all the activities in the course.
777
        $modules = get_fast_modinfo($course->id)->get_cms();
778
        // Put the modules into an array in order by the position they are shown in the course.
779
        $mods = [];
780
        $activitylist = [];
781
        foreach ($modules as $module) {
782
            // Only add activities the user can access, aren't in stealth mode and have a url (eg. mod_label does not).
783
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
784
                continue;
785
            }
786
            $mods[$module->id] = $module;
787
            // No need to add the current module to the list for the activity dropdown menu.
788
            if ($module->id == $this->page->cm->id) {
789
                continue;
790
            }
791
            // Module name.
792
            $modname = $module->get_formatted_name();
793
            // Display the hidden text if necessary.
794
            if (!$module->visible) {
795
                $modname .= ' ' . get_string('hiddenwithbrackets');
796
            }
797
            // Module URL.
798
            $linkurl = new moodle_url($module->url, array('forceview' => 1));
799
            // Add module URL (as key) and name (as value) to the activity list array.
800
            $activitylist[$linkurl->out(false)] = $modname;
801
        }
802
        $nummods = count($mods);
803
        // If there is only one mod then do nothing.
804
        if ($nummods == 1) {
805
            return '';
806
        }
807
        // Get an array of just the course module ids used to get the cmid value based on their position in the course.
808
        $modids = array_keys($mods);
809
        // Get the position in the array of the course module we are viewing.
810
        $position = array_search($this->page->cm->id, $modids);
811
        $prevmod = null;
812
        $nextmod = null;
813
        // Check if we have a previous mod to show.
814
        if ($position > 0) {
815
            $prevmod = $mods[$modids[$position - 1]];
816
        }
817
        // Check if we have a next mod to show.
818
        if ($position < ($nummods - 1)) {
819
            $nextmod = $mods[$modids[$position + 1]];
820
        }
821
        $activitynav = new \core_course\output\activity_navigation($prevmod, $nextmod, $activitylist);
822
        $renderer = $this->page->get_renderer('core', 'course');
823
        if ($this->cesa_navigation_course_completion() == '') {
824
            return $renderer->render($activitynav);
825
        }
826
        return '';
827
    }
828
 
829
 
830
 
831
    /**
832
     * This is an optional menu that can be added to a layout by a theme. It contains the
833
     * menu for the course administration, only on the course main page.
834
     *
835
     * @return string
836
     */
837
    public function context_header_settings_menu()
838
    {
839
        $context = $this->page->context;
840
        $menu = new action_menu();
841
 
842
        $items = $this->page->navbar->get_items();
843
        $currentnode = end($items);
844
 
845
        $showcoursemenu = false;
846
        $showfrontpagemenu = false;
847
        $showusermenu = false;
848
 
849
        // We are on the course home page.
850
        if (($context->contextlevel == CONTEXT_COURSE) &&
851
            !empty($currentnode) &&
852
            ($currentnode->type == navigation_node::TYPE_COURSE || $currentnode->type == navigation_node::TYPE_SECTION)
853
        ) {
854
            $showcoursemenu = true;
855
        }
856
 
857
        $courseformat = course_get_format($this->page->course);
858
        // This is a single activity course format, always show the course menu on the activity main page.
859
        if (
860
            $context->contextlevel == CONTEXT_MODULE &&
861
            !$courseformat->has_view_page()
862
        ) {
863
 
864
            $this->page->navigation->initialise();
865
            $activenode = $this->page->navigation->find_active_node();
866
            // If the settings menu has been forced then show the menu.
867
            if ($this->page->is_settings_menu_forced()) {
868
                $showcoursemenu = true;
869
            } else if (!empty($activenode) && ($activenode->type == navigation_node::TYPE_ACTIVITY ||
870
                $activenode->type == navigation_node::TYPE_RESOURCE)) {
871
 
872
                // We only want to show the menu on the first page of the activity. This means
873
                // the breadcrumb has no additional nodes.
874
                if ($currentnode && ($currentnode->key == $activenode->key && $currentnode->type == $activenode->type)) {
875
                    $showcoursemenu = true;
876
                }
877
            }
878
        }
879
 
880
        // This is the site front page.
881
        if (
882
            $context->contextlevel == CONTEXT_COURSE &&
883
            !empty($currentnode) &&
884
            $currentnode->key === 'home'
885
        ) {
886
            $showfrontpagemenu = true;
887
        }
888
 
889
        // This is the user profile page.
890
        if (
891
            $context->contextlevel == CONTEXT_USER &&
892
            !empty($currentnode) &&
893
            ($currentnode->key === 'myprofile')
894
        ) {
895
            $showusermenu = true;
896
        }
897
 
898
        if ($showfrontpagemenu) {
899
            $settingsnode = $this->page->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
900
            if ($settingsnode) {
901
                // Build an action menu based on the visible nodes from this navigation tree.
902
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
903
 
904
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
905
                if ($skipped) {
906
                    $text = get_string('morenavigationlinks');
907
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
908
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
909
                    $menu->add_secondary_action($link);
910
                }
911
            }
912
        } else if ($showcoursemenu) {
913
            $settingsnode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE);
914
            if ($settingsnode) {
915
                // Build an action menu based on the visible nodes from this navigation tree.
916
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
917
 
918
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
919
                if ($skipped) {
920
                    $text = get_string('morenavigationlinks');
921
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
922
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
923
                    $menu->add_secondary_action($link);
924
                }
925
            }
926
        } else if ($showusermenu) {
927
            // Get the course admin node from the settings navigation.
928
            $settingsnode = $this->page->settingsnav->find('useraccount', navigation_node::TYPE_CONTAINER);
929
            if ($settingsnode) {
930
                // Build an action menu based on the visible nodes from this navigation tree.
931
                $this->build_action_menu_from_navigation($menu, $settingsnode);
932
            }
933
        }
934
 
935
        return $this->render($menu);
936
    }
937
 
938
    public function customeditblockbtn()
939
    {
940
        $header = new stdClass();
941
        $header->settingsmenu = $this->context_header_settings_menu();
942
        $header->pageheadingbutton = $this->page_heading_button();
943
 
944
        $html = $this->render_from_template('theme_universe/header_settings_menu', $header);
945
 
946
        return $html;
947
    }
948
 
949
    /**
950
     * Renders the context header for the page.
951
     *
952
     * @param array $headerinfo Heading information.
953
     * @param int $headinglevel What 'h' level to make the heading.
954
     * @return string A rendered context header.
955
     */
956
    public function context_header($headerinfo = null, $headinglevel = 1): string
957
    {
958
        global $DB, $USER, $CFG, $SITE;
959
        require_once($CFG->dirroot . '/user/lib.php');
960
        $context = $this->page->context;
961
        $heading = null;
962
        $imagedata = null;
963
        $subheader = null;
964
        $userbuttons = null;
965
 
966
        // Make sure to use the heading if it has been set.
967
        if (isset($headerinfo['heading'])) {
968
            $heading = $headerinfo['heading'];
969
        } else {
970
            $heading = $this->page->heading;
971
        }
972
 
973
        // The user context currently has images and buttons. Other contexts may follow.
974
        if ((isset($headerinfo['user']) || $context->contextlevel == CONTEXT_USER) && $this->page->pagetype !== 'my-index') {
975
            if (isset($headerinfo['user'])) {
976
                $user = $headerinfo['user'];
977
            } else {
978
                // Look up the user information if it is not supplied.
979
                $user = $DB->get_record('user', array('id' => $context->instanceid));
980
            }
981
 
982
            // If the user context is set, then use that for capability checks.
983
            if (isset($headerinfo['usercontext'])) {
984
                $context = $headerinfo['usercontext'];
985
            }
986
 
987
            // Only provide user information if the user is the current user, or a user which the current user can view.
988
            // When checking user_can_view_profile(), either:
989
            // If the page context is course, check the course context (from the page object) or;
990
            // If page context is NOT course, then check across all courses.
991
            $course = ($this->page->context->contextlevel == CONTEXT_COURSE) ? $this->page->course : null;
992
 
993
            if (user_can_view_profile($user, $course)) {
994
                // Use the user's full name if the heading isn't set.
995
                if (empty($heading)) {
996
                    $heading = fullname($user);
997
                }
998
 
999
                $imagedata = $this->user_picture($user, array('size' => 100));
1000
 
1001
                // Check to see if we should be displaying a message button.
1002
                if (!empty($CFG->messaging) && has_capability('moodle/site:sendmessage', $context)) {
1003
                    $userbuttons = array(
1004
                        'messages' => array(
1005
                            'buttontype' => 'message',
1006
                            'title' => get_string('message', 'message'),
1007
                            'url' => new moodle_url('/message/index.php', array('id' => $user->id)),
1008
                            'image' => 'message',
1009
                            'linkattributes' => \core_message\helper::messageuser_link_params($user->id),
1010
                            'page' => $this->page
1011
                        )
1012
                    );
1013
 
1014
                    if ($USER->id != $user->id) {
1015
                        $iscontact = \core_message\api::is_contact($USER->id, $user->id);
1016
                        $contacttitle = $iscontact ? 'removefromyourcontacts' : 'addtoyourcontacts';
1017
                        $contacturlaction = $iscontact ? 'removecontact' : 'addcontact';
1018
                        $contactimage = $iscontact ? 'removecontact' : 'addcontact';
1019
                        $userbuttons['togglecontact'] = array(
1020
                            'buttontype' => 'togglecontact',
1021
                            'title' => get_string($contacttitle, 'message'),
1022
                            'url' => new moodle_url(
1023
                                '/message/index.php',
1024
                                array(
1025
                                    'user1' => $USER->id,
1026
                                    'user2' => $user->id,
1027
                                    $contacturlaction => $user->id,
1028
                                    'sesskey' => sesskey()
1029
                                )
1030
                            ),
1031
                            'image' => $contactimage,
1032
                            'linkattributes' => \core_message\helper::togglecontact_link_params($user, $iscontact),
1033
                            'page' => $this->page
1034
                        );
1035
                    }
1036
 
1037
                    $this->page->requires->string_for_js('changesmadereallygoaway', 'moodle');
1038
                }
1039
            } else {
1040
                $heading = null;
1041
            }
1042
        }
1043
 
1044
        $prefix = null;
1045
        if ($context->contextlevel == CONTEXT_MODULE) {
1046
            if ($this->page->course->format === 'singleactivity') {
1047
                $heading = $this->page->course->fullname;
1048
            } else {
1049
                $heading = $this->page->cm->get_formatted_name();
1050
                $imagedata = $this->pix_icon('monologo', '', $this->page->activityname, ['class' => 'activityicon']);
1051
                $purposeclass = plugin_supports('mod', $this->page->activityname, FEATURE_MOD_PURPOSE);
1052
                $purposeclass .= ' activityiconcontainer';
1053
                $purposeclass .= ' modicon_' . $this->page->activityname;
1054
                $imagedata = html_writer::tag('div', $imagedata, ['class' => $purposeclass]);
1055
                $prefix = get_string('modulename', $this->page->activityname);
1056
            }
1057
        }
1058
 
1059
        $contextheader = new \context_header($heading, $headinglevel, $imagedata, $userbuttons, $prefix);
1060
        return $this->render_context_header($contextheader);
1061
    }
1062
 
1063
 
1064
    /**
1065
     * Construct a user menu, returning HTML that can be echoed out by a
1066
     * layout file.
1067
     *
1068
     * @param stdClass $user A user object, usually $USER.
1069
     * @param bool $withlinks true if a dropdown should be built.
1070
     * @return string HTML fragment.
1071
     */
1072
    public function user_menu($user = null, $withlinks = null)
1073
    {
1074
        global $USER, $CFG;
1075
        require_once($CFG->dirroot . '/user/lib.php');
1076
 
1077
        if (is_null($user)) {
1078
            $user = $USER;
1079
        }
1080
 
1081
        // Note: this behaviour is intended to match that of core_renderer::login_info,
1082
        // but should not be considered to be good practice; layout options are
1083
        // intended to be theme-specific. Please don't copy this snippet anywhere else.
1084
        if (is_null($withlinks)) {
1085
            $withlinks = empty($this->page->layout_options['nologinlinks']);
1086
        }
1087
 
1088
        // Add a class for when $withlinks is false.
1089
        $usermenuclasses = 'usermenu';
1090
        if (!$withlinks) {
1091
            $usermenuclasses .= ' withoutlinks';
1092
        }
1093
 
1094
        $returnstr = "";
1095
 
1096
        // If during initial install, return the empty return string.
1097
        if (during_initial_install()) {
1098
            return $returnstr;
1099
        }
1100
 
1101
        $loginpage = $this->is_login_page();
1102
        $loginurl = get_login_url();
1103
        // If not logged in, show the typical not-logged-in string.
1104
        if (!isloggedin()) {
1105
            if (!$loginpage) {
1106
                $returnstr .= "<a class=\"rui-topbar-btn rui-login-btn\" href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1107
                    get_string('login') .
1108
                    '</span>
1109
                <svg class="ml-2" width="20" height="20" fill="none" viewBox="0 0 24 24">
1110
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1111
                d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1112
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1113
                d="M9.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25 6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H9.75">
1114
                </path>
1115
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 12H4.75"></path>
1116
                </svg></a>';
1117
            }
1118
            return html_writer::div(
1119
                html_writer::span(
1120
                    $returnstr,
1121
                    'login'
1122
                ),
1123
                $usermenuclasses
1124
            );
1125
        }
1126
 
1127
        // If logged in as a guest user, show a string to that effect.
1128
        if (isguestuser()) {
1129
            $icon = '<svg class="mr-2"
1130
                width="24"
1131
                height="24"
1132
                viewBox="0 0 24 24"
1133
                fill="none"
1134
                xmlns="http://www.w3.org/2000/svg">
1135
            <path d="M10 12C10 12.5523 9.55228 13 9 13C8.44772 13 8 12.5523 8
1136
            12C8 11.4477 8.44772 11 9 11C9.55228 11 10 11.4477 10 12Z"
1137
                fill="currentColor"
1138
                />
1139
            <path d="M15 13C15.5523 13 16 12.5523 16 12C16 11.4477 15.5523 11
1140
            15 11C14.4477 11 14 11.4477 14 12C14 12.5523 14.4477 13 15 13Z"
1141
                fill="currentColor"
1142
                />
1143
            <path fill-rule="evenodd"
1144
                clip-rule="evenodd"
1145
                d="M12.0244 2.00003L12 2C6.47715 2 2 6.47715 2 12C2 17.5228
1146
                6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.74235
1147
            17.9425 2.43237 12.788 2.03059L12.7886 2.0282C12.5329 2.00891
1148
            12.278 1.99961 12.0244 2.00003ZM12 20C16.4183 20 20 16.4183 20
1149
            12C20 11.3014 19.9105 10.6237 19.7422
1150
            9.97775C16.1597 10.2313 12.7359 8.52461 10.7605 5.60246C9.31322
1151
            7.07886 7.2982 7.99666 5.06879 8.00253C4.38902 9.17866 4 10.5439 4
1152
            12C4 16.4183 7.58172 20
1153
            12 20ZM11.9785 4.00003L12.0236 4.00003L12 4L11.9785 4.00003Z"
1154
                fill="currentColor"
1155
                /></svg>';
1156
            $returnstr = '<div class="rui-badge-guest">' . $icon . get_string('loggedinasguest') . '</div>';
1157
            if (!$loginpage && $withlinks) {
1158
                $returnstr .= "<a class=\"rui-topbar-btn rui-login-btn\"
1159
                    href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1160
                    get_string('login') .
1161
                    '</span>
1162
                <svg class="ml-2"
1163
                    width="20"
1164
                    height="20"
1165
                    fill="none"
1166
                    viewBox="0 0 24 24">
1167
                <path stroke="currentColor"
1168
                    stroke-linecap="round"
1169
                    stroke-linejoin="round"
1170
                    stroke-width="2"
1171
                    d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1172
                <path stroke="currentColor"
1173
                    stroke-linecap="round"
1174
                    stroke-linejoin="round"
1175
                    stroke-width="2"
1176
                    d="M9.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25
1177
                    6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H9.75"></path>
1178
                    <path stroke="currentColor"
1179
                        stroke-linecap="round"
1180
                        stroke-linejoin="round"
1181
                        stroke-width="2"
1182
                        d="M13 12H4.75"></path></svg></a>';
1183
            }
1184
 
1185
            return html_writer::div(
1186
                html_writer::span(
1187
                    $returnstr,
1188
                    'login'
1189
                ),
1190
                $usermenuclasses
1191
            );
1192
        }
1193
 
1194
        // Get some navigation opts.
1195
        $opts = user_get_user_navigation_info($user, $this->page, array('avatarsize' => 56));
1196
 
1197
        $avatarclasses = "avatars";
1198
        $avatarcontents = html_writer::span($opts->metadata['useravatar'], 'avatar current');
1199
        $usertextcontents = '<span class="rui-fullname">' . $opts->metadata['userfullname'] . '</span>';
1200
        $usertextmail = $user->email;
1201
        $usernick = '<svg class="mr-1"
1202
            width="16"
1203
            height="16"
1204
            fill="none"
1205
            viewBox="0 0 24 24">
1206
        <path stroke="currentColor"
1207
            stroke-linecap="round"
1208
            stroke-linejoin="round"
1209
            stroke-width="2"
1210
            d="M12 13V15"></path>
1211
        <circle cx="12"
1212
            cy="9"
1213
            r="1"
1214
            fill="currentColor"></circle>
1215
        <circle cx="12"
1216
            cy="12"
1217
            r="7.25"
1218
            stroke="currentColor"
1219
            stroke-linecap="round"
1220
            stroke-linejoin="round"
1221
            stroke-width="1.5"></circle>
1222
        </svg>' . $user->username;
1223
 
1224
        // Other user.
1225
        $usermeta = '';
1226
        if (!empty($opts->metadata['asotheruser'])) {
1227
            $avatarcontents .= html_writer::span(
1228
                $opts->metadata['realuseravatar'],
1229
                'avatar realuser'
1230
            );
1231
            $usermeta .= $opts->metadata['realuserfullname'];
1232
            $usermeta .= html_writer::tag(
1233
                'span',
1234
                get_string(
1235
                    'loggedinas',
1236
                    'moodle',
1237
                    html_writer::span(
1238
                        $opts->metadata['userfullname'],
1239
                        'value'
1240
                    )
1241
                ),
1242
                array('class' => 'meta viewingas')
1243
            );
1244
        }
1245
 
1246
        // Role.
1247
        if (!empty($opts->metadata['asotherrole'])) {
1248
            $role = core_text::strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['rolename'])));
1249
            $usermeta .= html_writer::span(
1250
                $opts->metadata['rolename'],
1251
                'meta role role-' . $role
1252
            );
1253
        }
1254
 
1255
        // User login failures.
1256
        if (!empty($opts->metadata['userloginfail'])) {
1257
            $usermeta .= html_writer::div(
1258
                '<svg class="mr-1"
1259
                width="16"
1260
                height="16"
1261
                fill="none"
1262
                viewBox="0 0 24 24"><path stroke="currentColor"
1263
                stroke-linecap="round"
1264
                stroke-linejoin="round"
1265
                stroke-width="1.5"
1266
                d="M4.9522 16.3536L10.2152 5.85658C10.9531 4.38481 13.0539
1267
                4.3852 13.7913 5.85723L19.0495 16.3543C19.7156 17.6841 18.7487
1268
                19.25 17.2613 19.25H6.74007C5.25234
1269
                19.25 4.2854 17.6835 4.9522 16.3536Z">
1270
                </path><path stroke="currentColor"
1271
                stroke-linecap="round"
1272
                stroke-linejoin="round"
1273
                stroke-width="2"
1274
                d="M12 10V12"></path>
1275
                <circle cx="12" cy="16" r="1" fill="currentColor"></circle></svg>' .
1276
                    $opts->metadata['userloginfail'],
1277
                'meta loginfailures'
1278
            );
1279
        }
1280
 
1281
        // MNet.
1282
        if (!empty($opts->metadata['asmnetuser'])) {
1283
            $mnet = strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['mnetidprovidername'])));
1284
            $usermeta .= html_writer::span(
1285
                $opts->metadata['mnetidprovidername'],
1286
                'meta mnet mnet-' . $mnet
1287
            );
1288
        }
1289
 
1290
        $returnstr .= html_writer::span(
1291
            html_writer::span($avatarcontents, $avatarclasses),
1292
            'userbutton'
1291 ariadna 1293
        );
1294
 
1295 ariadna 1295
        // Create a divider (well, a filler).
1296
        $divider = new action_menu_filler();
1297
        $divider->primary = false;
1291 ariadna 1298
 
1295 ariadna 1299
        $am = new action_menu();
1300
        $am->set_menu_trigger(
1301
            $returnstr
1302
        );
1303
        $am->set_action_label(get_string('usermenu'));
1304
        $am->set_nowrap_on_items();
1305
 
1306
        if ($CFG->enabledashboard) {
1307
            $dashboardlink = '<div class="dropdown-item-wrapper"><a class="dropdown-item" href="' .
1308
                new moodle_url('/my/') .
1309
                '" data-identifier="dashboard,moodle" title="dashboard,moodle">' .
1310
                get_string('myhome', 'moodle') .
1311
                '</a></div>';
1312
        } else {
1313
            $dashboardlink = null;
1314
        }
1315
 
1316
        $am->add(
1317
            '<div class="dropdown-user-wrapper"><div class="dropdown-user">' . $usertextcontents  . '</div>'
1318
                . '<div class="dropdown-user-mail text-truncate" title="' . $usertextmail . '">' . $usertextmail . '</div>'
1319
                . '<span class="dropdown-user-nick w-100">' . $usernick . '</span>'
1320
                . '<div class="dropdown-user-meta"><span class="badge-xs badge-sq badge-warning flex-wrap">' .
1321
                $usermeta . '</span></div>'
1322
                . '</div><div class="dropdown-divider dropdown-divider-user"></div>' . $dashboardlink
1323
        );
1324
 
1325
        if ($withlinks) {
1326
            $navitemcount = count($opts->navitems);
1327
            $idx = 0;
1328
            foreach ($opts->navitems as $key => $value) {
1329
 
1330
                switch ($value->itemtype) {
1331
                    case 'divider':
1332
                        // If the nav item is a divider, add one and skip link processing.
1333
                        $am->add($divider);
1334
                        break;
1335
 
1336
                    case 'invalid':
1337
                        // Silently skip invalid entries (should we post a notification?).
1338
                        break;
1339
 
1340
                    case 'link':
1341
                        $al = '<a class="dropdown-item" href="' .
1342
                            $value->url .
1343
                            '" data-identifier="' .
1344
                            $value->titleidentifier .
1345
                            '" title="' .
1346
                            $value->titleidentifier .
1347
                            '">' .
1348
                            $value->title . '</a>';
1349
                        $am->add($al);
1350
                        break;
1351
                }
1352
 
1353
                $idx++;
1354
 
1355
                // Add dividers after the first item and before the last item.
1356
                if ($idx == 1 || $idx == $navitemcount - 1) {
1357
                    $am->add($divider);
1358
                }
1359
            }
1360
        }
1361
 
1362
 
1363
 
1364
        return html_writer::div(
1365
            $this->render($am),
1366
            $usermenuclasses
1367
        );
1291 ariadna 1368
    }
1294 ariadna 1369
 
1295 ariadna 1370
 
1371
    /**
1372
     * Returns standard main content placeholder.
1373
     * Designed to be called in theme layout.php files.
1374
     *
1375
     * @return string HTML fragment.
1376
     */
1377
    public function main_content()
1378
    {
1379
        // This is here because it is the only place we can inject the "main" role over the entire main content area
1380
        // without requiring all theme's to manually do it, and without creating yet another thing people need to
1381
        // remember in the theme.
1382
        // This is an unfortunate hack. DO NO EVER add anything more here.
1383
        // DO NOT add classes.
1384
        // DO NOT add an id.
1385
        return '<div class="main-content" role="main">' . $this->unique_main_content_token . '</div>';
1386
    }
1387
 
1388
    /**
1389
     * Outputs a heading
1390
     *
1391
     * @param string $text The text of the heading
1392
     * @param int $level The level of importance of the heading. Defaulting to 2
1393
     * @param string $classes A space-separated list of CSS classes. Defaulting to null
1394
     * @param string $id An optional ID
1395
     * @return string the HTML to output.
1396
     */
1397
    public function heading($text, $level = 2, $classes = null, $id = null)
1398
    {
1399
        $level = (int) $level;
1400
        if ($level < 1 || $level > 6) {
1401
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1402
        }
1403
        return html_writer::tag('div', html_writer::tag('h' .
1404
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1405
            ' rui-main-content-title rui-main-content-title--h' .
1406
            $level)), array('class' => 'rui-title-container'));
1407
    }
1408
 
1409
 
1410
    public function headingwithavatar($text, $level = 2, $classes = null, $id = null)
1411
    {
1412
        $level = (int) $level;
1413
        if ($level < 1 || $level > 6) {
1414
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1415
        }
1416
        return html_writer::tag('div', html_writer::tag('h' .
1417
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1418
            ' rui-main-content-title-with-avatar')), array('class' => 'rui-title-container-with-avatar'));
1419
    }
1420
 
1421
    /**
1422
     * Renders the login form.
1423
     *
1424
     * @param \core_auth\output\login $form The renderable.
1425
     * @return string
1426
     */
1427
    public function render_login(\core_auth\output\login $form)
1428
    {
1429
        global $CFG, $SITE;
1430
 
1431
        $context = $form->export_for_template($this);
1432
 
1433
        // Override because rendering is not supported in template yet.
1434
        if ($CFG->rememberusername == 0) {
1435
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
1436
        } else {
1437
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
1438
        }
1439
        $context->errorformatted = $this->error_text($context->error);
1440
        $url = $this->get_logo_url();
1441
        if ($url) {
1442
            $url = $url->out(false);
1443
        }
1444
        $context->logourl = $url;
1445
        $context->sitename = format_string(
1446
            $SITE->fullname,
1447
            true,
1448
            ['context' => context_course::instance(SITEID), "escape" => false]
1449
        );
1450
 
1451
        if ($this->page->theme->settings->setloginlayout == 1) {
1452
            $context->loginlayout1 = 1;
1453
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1454
            $context->loginlayout2 = 1;
1455
            if (isset($this->page->theme->settings->loginbg)) {
1456
                $context->loginlayoutimg = 1;
1457
            }
1458
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1459
            $context->loginlayout3 = 1;
1460
            if (isset($this->page->theme->settings->loginbg)) {
1461
                $context->loginlayoutimg = 1;
1462
            }
1463
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1464
            $context->loginlayout4 = 1;
1465
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1466
            $context->loginlayout5 = 1;
1467
        }
1468
 
1469
        if (isset($this->page->theme->settings->loginlogooutside)) {
1470
            $context->loginlogooutside = $this->page->theme->settings->loginlogooutside;
1471
        }
1472
 
1473
        if (isset($this->page->theme->settings->customsignupoutside)) {
1474
            $context->customsignupoutside = $this->page->theme->settings->customsignupoutside;
1475
        }
1476
 
1477
        if (isset($this->page->theme->settings->loginidprovtop)) {
1478
            $context->loginidprovtop = $this->page->theme->settings->loginidprovtop;
1479
        }
1480
 
1481
        if (isset($this->page->theme->settings->stringca)) {
1482
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1483
                FORMAT_HTML,
1484
                array('noclean' => true)
1485
            );
1486
        }
1487
 
1488
        if (isset($this->page->theme->settings->stringca)) {
1489
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1490
                FORMAT_HTML,
1491
                array('noclean' => true)
1492
            );
1493
        }
1494
 
1495
        if (isset($this->page->theme->settings->loginhtmlcontent1)) {
1496
            $context->loginhtmlcontent1 = format_text(($this->page->theme->settings->loginhtmlcontent1),
1497
                FORMAT_HTML,
1498
                array('noclean' => true)
1499
            );
1500
        }
1501
 
1502
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1503
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1504
                FORMAT_HTML,
1505
                array('noclean' => true)
1506
            );
1507
        }
1508
 
1509
        if (isset($this->page->theme->settings->loginhtmlcontent3)) {
1510
            $context->loginhtmlcontent3 = format_text(($this->page->theme->settings->loginhtmlcontent3),
1511
                FORMAT_HTML,
1512
                array('noclean' => true)
1513
            );
1514
        }
1515
 
1516
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1517
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1518
                FORMAT_HTML,
1519
                array('noclean' => true)
1520
            );
1521
        }
1522
 
1523
        if (isset($this->page->theme->settings->logincustomfooterhtml)) {
1524
            $context->logincustomfooterhtml = format_text(($this->page->theme->settings->logincustomfooterhtml),
1525
                FORMAT_HTML,
1526
                array('noclean' => true)
1527
            );
1528
        }
1529
 
1530
        if (isset($this->page->theme->settings->loginhtmlblockbottom)) {
1531
            $context->loginhtmlblockbottom = format_text(($this->page->theme->settings->loginhtmlblockbottom),
1532
                FORMAT_HTML,
1533
                array('noclean' => true)
1534
            );
1535
        }
1536
 
1537
        if (isset($this->page->theme->settings->loginfootercontent)) {
1538
            $context->loginfootercontent = format_text(($this->page->theme->settings->loginfootercontent),
1539
                FORMAT_HTML,
1540
                array('noclean' => true)
1541
            );
1542
        }
1543
 
1544
        if (isset($this->page->theme->settings->footercopy)) {
1545
            $context->footercopy = format_text(($this->page->theme->settings->footercopy),
1546
                FORMAT_HTML,
1547
                array('noclean' => true)
1548
            );
1549
        }
1550
 
1551
        if (isset($this->page->theme->settings->loginintrotext)) {
1552
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1553
                FORMAT_HTML,
1554
                array('noclean' => true)
1555
            );
1556
        }
1557
 
1558
        if (isset($this->page->theme->settings->loginintrotext)) {
1559
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1560
                FORMAT_HTML,
1561
                array('noclean' => true)
1562
            );
1563
        }
1564
 
1565
        if (isset($this->page->theme->settings->customloginlogo)) {
1566
            $context->customloginlogo = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1567
        }
1568
 
1569
        if (isset($this->page->theme->settings->loginbg)) {
1570
            $context->loginbg = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1571
        }
1572
 
1573
        if (isset($this->page->theme->settings->hideforgotpassword)) {
1574
            $context->hideforgotpassword = $this->page->theme->settings->hideforgotpassword == 1;
1575
        }
1576
 
1577
        if (isset($this->page->theme->settings->logininfobox)) {
1578
            $context->logininfobox = format_text(($this->page->theme->settings->logininfobox),
1579
                FORMAT_HTML,
1580
                array('noclean' => true)
1581
            );
1582
        }
1583
 
1584
        return $this->render_from_template('core/loginform', $context);
1585
    }
1586
 
1587
    /**
1588
     * Render the login signup form into a nice template for the theme.
1589
     *
1590
     * @param mform $form
1591
     * @return string
1592
     */
1593
    public function render_login_signup_form($form)
1594
    {
1595
        global $SITE;
1596
 
1597
        $context = $form->export_for_template($this);
1598
        $url = $this->get_logo_url();
1599
        if ($url) {
1600
            $url = $url->out(false);
1601
        }
1602
        $context['logourl'] = $url;
1603
        $context['sitename'] = format_string(
1604
            $SITE->fullname,
1605
            true,
1606
            ['context' => context_course::instance(SITEID), "escape" => false]
1607
        );
1608
 
1609
        if ($this->page->theme->settings->setloginlayout == 1) {
1610
            $context['loginlayout1'] = 1;
1611
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1612
            $context['loginlayout2'] = 1;
1613
            if (isset($this->page->theme->settings->loginbg)) {
1614
                $context['loginlayoutimg'] = 1;
1615
            }
1616
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1617
            $context['loginlayout3'] = 1;
1618
            if (isset($this->page->theme->settings->loginbg)) {
1619
                $context['loginlayoutimg'] = 1;
1620
            }
1621
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1622
            $context['loginlayout4'] = 1;
1623
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1624
            $context['loginlayout5'] = 1;
1625
        }
1626
 
1627
        if (isset($this->page->theme->settings->loginlogooutside)) {
1628
            $context['loginlogooutside'] = $this->page->theme->settings->loginlogooutside;
1629
        }
1630
 
1631
        if (isset($this->page->theme->settings->stringbacktologin)) {
1632
            $context['stringbacktologin'] = format_text(($this->page->theme->settings->stringbacktologin),
1633
                FORMAT_HTML,
1634
                array('noclean' => true)
1635
            );
1636
        }
1637
        if (isset($this->page->theme->settings->signupintrotext)) {
1638
            $context['signupintrotext'] = format_text(($this->page->theme->settings->signupintrotext),
1639
                FORMAT_HTML,
1640
                array('noclean' => true)
1641
            );
1642
        }
1643
        if (isset($this->page->theme->settings->signuptext)) {
1644
            $context['signuptext'] = format_text(($this->page->theme->settings->signuptext),
1645
                FORMAT_HTML,
1646
                array('noclean' => true)
1647
            );
1648
        }
1649
 
1650
        if (!empty($this->page->theme->settings->customloginlogo)) {
1651
            $url = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1652
            $context['customloginlogo'] = $url;
1653
        }
1654
 
1655
        if (!empty($this->page->theme->settings->loginbg)) {
1656
            $url = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1657
            $context['loginbg'] = $url;
1658
        }
1659
 
1660
        if (isset($this->page->theme->settings->loginfootercontent)) {
1661
            $context['loginfootercontent'] = format_text(($this->page->theme->settings->loginfootercontent),
1662
                FORMAT_HTML,
1663
                array('noclean' => true)
1664
            );
1665
        }
1666
 
1667
        return $this->render_from_template('core/signup_form_layout', $context);
1668
    }
1669
 
1670
 
1671
    /**
1672
     * Renders the header bar.
1673
     *
1674
     * @param context_header $contextheader Header bar object.
1675
     * @return string HTML for the header bar.
1676
     */
1677
    protected function render_context_header(\context_header $contextheader)
1678
    {
1679
        $heading = null;
1680
        $imagedata = null;
1681
        $html = null;
1682
 
1683
        // Generate the heading first and before everything else as we might have to do an early return.
1684
        if (!isset($contextheader->heading)) {
1685
            $heading = $this->heading($this->page->heading, $contextheader->headinglevel);
1686
        } else {
1687
            $heading = $this->heading($contextheader->heading, $contextheader->headinglevel);
1688
        }
1689
 
1690
        // All the html stuff goes here.
1691
        $html = html_writer::start_div('page-context-header d-flex align-items-center flex-wrap');
1692
 
1693
        // Image data.
1694
        if (isset($contextheader->imagedata)) {
1695
            // Header specific image.
1696
            $html .= html_writer::div($contextheader->imagedata, 'page-header-image');
1697
        }
1698
 
1699
        // Headings.
1700
        if (isset($contextheader->prefix)) {
1701
            $prefix = html_writer::div($contextheader->prefix, 'text-muted text-uppercase small line-height-3');
1702
            $heading = $prefix . $heading;
1703
        }
1704
 
1705
        if (!isset($contextheader->heading)) {
1706
            $html .= html_writer::tag('h3', $heading, array('class' => 'rui-page-title rui-page-title--page'));
1707
        } else if (isset($contextheader->imagedata)) {
1708
            $html .= html_writer::tag(
1709
                'div',
1710
                $this->heading($contextheader->heading, 4),
1711
                array('class' => 'rui-page-title rui-page-title--icon')
1712
            );
1713
        } else {
1714
            $html .= html_writer::tag('h2', $heading, array('class' => 'page-header-headings
1715
                rui-page-title rui-page-title--context'));
1716
        }
1717
 
1718
        // Buttons.
1719
        if (isset($contextheader->additionalbuttons)) {
1720
            $html .= html_writer::start_div('btn-group header-button-group my-2 my-lg-0 ml-lg-4');
1721
            foreach ($contextheader->additionalbuttons as $button) {
1722
                if (!isset($button->page)) {
1723
                    // Include js for messaging.
1724
                    if ($button['buttontype'] === 'togglecontact') {
1725
                        \core_message\helper::togglecontact_requirejs();
1726
                    }
1727
                    if ($button['buttontype'] === 'message') {
1728
                        \core_message\helper::messageuser_requirejs();
1729
                    }
1730
                    $image = $this->pix_icon($button['formattedimage'], $button['title'], 'moodle', array(
1731
                        'class' => 'iconsmall',
1732
                        'role' => 'presentation'
1733
                    ));
1734
                    $image .= html_writer::span($button['title'], 'header-button-title');
1735
                } else {
1736
                    $image = html_writer::empty_tag('img', array(
1737
                        'src' => $button['formattedimage'],
1738
                        'role' => 'presentation'
1739
                    ));
1740
                }
1741
                $html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
1742
            }
1743
            $html .= html_writer::end_div();
1744
        }
1745
        $html .= html_writer::end_div();
1746
 
1747
        return $html;
1748
    }
1749
 
1750
    public function header()
1751
    {
1752
        global $USER, $COURSE;
1753
        $theme = theme_config::load('universe');
1754
 
1755
        // Verificar si el curso está definido
1756
        if (!isset($COURSE) || empty($COURSE->id)) {
1757
            debugging('Error: No se pudo obtener el contexto del curso.', DEBUG_DEVELOPER);
1758
            return parent::header();
1759
        }
1760
 
1761
        // Verificar si el usuario está autenticado
1762
        if (!isset($USER->id)) {
1763
            debugging('Error: Usuario no autenticado.', DEBUG_DEVELOPER);
1764
            return parent::header();
1765
        }
1766
 
1767
        // Obtener contexto del curso
1768
        $context = context_course::instance($COURSE->id);
1769
        $roles = get_user_roles($context, $USER->id, true) ?: [];
1770
 
1771
        // Agregar clases según los roles del usuario
1772
        if (!empty($roles)) {
1773
            foreach ($roles as $role) {
1774
                $this->page->add_body_class('role-' . $role->shortname);
1775
            }
1776
        } else {
1777
            $this->page->add_body_class('role-none');
1778
        }
1779
 
1780
        // Verificar configuración de edición
1781
        if (!empty($theme->settings->topbareditmode) && $theme->settings->topbareditmode == '1') {
1782
            $this->page->add_body_class('rui-editmode--top');
1783
        } else {
1784
            $this->page->add_body_class('rui-editmode--footer');
1785
        }
1786
 
1787
        return parent::header();
1788
    }
1789
 
1790
 
1791
 
1792
    /**
1793
     * See if this is the first view of the current cm in the session if it has fake blocks.
1794
     *
1795
     * (We track up to 100 cms so as not to overflow the session.)
1796
     * This is done for drawer regions containing fake blocks so we can show blocks automatically.
1797
     *
1798
     * @return boolean true if the page has fakeblocks and this is the first visit.
1799
     */
1800
    public function firstview_fakeblocks(): bool
1801
    {
1802
        global $SESSION;
1803
 
1804
        $firstview = false;
1805
        if ($this->page->cm) {
1806
            if (!$this->page->blocks->region_has_fakeblocks('side-pre')) {
1807
                return false;
1808
            }
1809
            if (!property_exists($SESSION, 'firstview_fakeblocks')) {
1810
                $SESSION->firstview_fakeblocks = [];
1811
            }
1812
            if (array_key_exists($this->page->cm->id, $SESSION->firstview_fakeblocks)) {
1813
                $firstview = false;
1814
            } else {
1815
                $SESSION->firstview_fakeblocks[$this->page->cm->id] = true;
1816
                $firstview = true;
1817
                if (count($SESSION->firstview_fakeblocks) > 100) {
1818
                    array_shift($SESSION->firstview_fakeblocks);
1819
                }
1820
            }
1821
        }
1822
        return $firstview;
1823
    }
1824
 
1825
 
1826
    /**
1827
     * Build the guest access hint HTML code.
1828
     *
1829
     * @param int $courseid The course ID.
1830
     * @return string.
1831
     */
1832
    public function theme_universe_get_course_guest_access_hint($courseid)
1833
    {
1834
        global $CFG;
1835
        require_once($CFG->dirroot . '/enrol/self/lib.php');
1836
 
1837
        $html = '';
1838
        $instances = enrol_get_instances($courseid, true);
1839
        $plugins = enrol_get_plugins(true);
1840
        foreach ($instances as $instance) {
1841
            if (!isset($plugins[$instance->enrol])) {
1842
                continue;
1843
            }
1844
            $plugin = $plugins[$instance->enrol];
1845
            if ($plugin->show_enrolme_link($instance)) {
1846
                $html = html_writer::tag('div', get_string(
1847
                    'showhintcourseguestaccesssettinglink',
1848
                    'theme_universe',
1849
                    array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
1850
                ));
1851
                break;
1852
            }
1853
        }
1854
 
1855
        return $html;
1856
    }
1857
 
1858
 
1859
 
1860
 
1861
    /**
1862
     * Color Customization
1863
     * @return string HTML fragment.
1864
     */
1865
    public function additional_head_html()
1866
    {
1867
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1868
 
1869
        $output = null;
1870
 
1871
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1872
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1873
                // Get custom field by name
1874
                $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1875
                // Get value
1876
                $mainthemecolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id));
1877
            } else {
1878
                $mainthemecolor = null;
1879
            }
1880
 
1881
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1882
                $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1883
                $mainthemecolor2 = $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id));
1884
            }
1885
 
1886
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1887
                // Get custom field by name
1888
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1889
                // Get value
1890
                $topbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1891
            }
1892
 
1893
            if ($DB->record_exists('customfield_field', array('shortname' => 'dmtopbarcolor'), 'id')) {
1894
                // Get custom field by name
1895
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1896
                // Get value
1897
                $dmtopbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1898
            } else {
1899
                $dmtopbarcolor = null;
1900
            }
1901
 
1902
 
1903
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1904
                // Get custom field by name
1905
                $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1906
                // Get value
1907
                $footercolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id));
1908
            } else {
1909
                $footercolor = null;
1910
            }
1911
 
1912
 
1913
            $css = '';
1914
 
1915
            $css .= ':root { ';
1916
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1917
                if ($mainthemecolor != null) {
1918
                    $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1919
                    $css .= '--primary-color-100: ' . $mainthemecolor->value . '30; ';
1920
                    $css .= '--primary-color-300: ' . $mainthemecolor->value . '70; ';
1921
                    $css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1922
                    $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1923
                    $css .= '--btn-primary-color-bg-hover: ' . $mainthemecolor->value . '95; ';
1924
 
1925
                    if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1926
                        if ($mainthemecolor2 != null) {
1927
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor2->value . '; ';
1928
                        } else {
1929
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor->value . '30; ';
1930
                        }
1931
                    }
1932
                }
1933
            }
1934
 
1935
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1936
                if ($topbarcolor != null) {
1937
                    $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1938
                    if ($dmtopbarcolor != null) {
1939
                        $css .= '--dm-topbar-color: ' . $dmtopbarcolor->value . '; ';
1940
                    } else {
1941
                        $css .= '--dm-topbar-color: ' . $topbarcolor->value . '; ';
1942
                    }
1943
                }
1944
            }
1945
 
1946
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1947
                if ($footercolor != null) {
1948
                    $css .= '--footer-color: ' . $footercolor->value . '; ';
1949
                }
1950
            }
1951
 
1952
            $css .= '}';
1953
 
1954
            if ($css) {
1955
                $output .= '<style>' . $css . '</style>';
1956
            }
1957
        }
1958
 
1959
        return $output;
1960
    }
1961
 
1962
    public function custom_course_logo()
1963
    {
1964
        global $DB, $CFG, $COURSE, $PAGE;
1965
 
1966
        $output = null;
1967
 
1968
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1969
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1970
                // Get custom field ID
1971
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1972
                $customfieldpicid = $customfieldpic->id;
1973
                // Get value
1974
                $customlogo = $DB->get_record(
1975
                    'customfield_data',
1976
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1977
                );
1978
 
1979
                $customlogoid = $customlogo->id;
1980
                $contextid = $customlogo->contextid;
1981
 
1982
                if ($customfieldpic != null) {
1983
                    $files = get_file_storage()->get_area_files(
1984
                        $contextid,
1985
                        'customfield_picture',
1986
                        'file',
1987
                        $customlogoid,
1988
                        '',
1989
                        false
1990
                    );
1991
 
1992
                    if (empty($files)) {
1993
                        return null;
1994
                    }
1995
 
1996
                    $file = reset($files);
1997
                    $fileurl = moodle_url::make_pluginfile_url(
1998
                        $file->get_contextid(),
1999
                        $file->get_component(),
2000
                        $file->get_filearea(),
2001
                        $file->get_itemid(),
2002
                        $file->get_filepath(),
2003
                        $file->get_filename()
2004
                    );
2005
 
2006
                    $output .= $fileurl;
2007
                }
2008
            }
2009
        }
2010
 
2011
        return $output;
2012
    }
2013
 
2014
    public function custom_course_dmlogo()
2015
    {
2016
        global $DB, $CFG, $COURSE, $PAGE;
2017
 
2018
        $output = null;
2019
 
2020
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2021
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
2022
                // Get custom field ID
2023
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
2024
                $customfieldpicid = $customfieldpic->id;
2025
                // Get value
2026
                $customlogo = $DB->get_record(
2027
                    'customfield_data',
2028
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2029
                );
2030
 
2031
                $customlogoid = $customlogo->id;
2032
                $contextid = $customlogo->contextid;
2033
 
2034
                if ($customfieldpic != null) {
2035
                    $files = get_file_storage()->get_area_files(
2036
                        $contextid,
2037
                        'customfield_picture',
2038
                        'file',
2039
                        $customlogoid,
2040
                        '',
2041
                        false
2042
                    );
2043
 
2044
                    if (empty($files)) {
2045
                        return null;
2046
                    }
2047
 
2048
                    $file = reset($files);
2049
                    $fileurl = moodle_url::make_pluginfile_url(
2050
                        $file->get_contextid(),
2051
                        $file->get_component(),
2052
                        $file->get_filearea(),
2053
                        $file->get_itemid(),
2054
                        $file->get_filepath(),
2055
                        $file->get_filename()
2056
                    );
2057
 
2058
                    $output .= $fileurl;
2059
                }
2060
            }
2061
        }
2062
 
2063
        return $output;
2064
    }
2065
 
2066
    public function custom_course_favicon()
2067
    {
2068
        global $DB, $CFG, $COURSE, $PAGE;
2069
 
2070
        $output = null;
2071
 
2072
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2073
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2074
                // Get custom field ID
2075
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2076
                $customfieldpicid = $customfieldpic->id;
2077
                // Get value
2078
                $customfavicon = $DB->get_record(
2079
                    'customfield_data',
2080
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2081
                );
2082
 
2083
                $customfaviconid = $customfavicon->id;
2084
                $contextid = $customfavicon->contextid;
2085
 
2086
                if ($customfieldpic != null) {
2087
                    $files = get_file_storage()->get_area_files(
2088
                        $contextid,
2089
                        'customfield_picture',
2090
                        'file',
2091
                        $customfaviconid,
2092
                        '',
2093
                        false
2094
                    );
2095
 
2096
                    if (empty($files)) {
2097
                        return null;
2098
                    }
2099
 
2100
                    $file = reset($files);
2101
                    $fileurl = moodle_url::make_pluginfile_url(
2102
                        $file->get_contextid(),
2103
                        $file->get_component(),
2104
                        $file->get_filearea(),
2105
                        $file->get_itemid(),
2106
                        $file->get_filepath(),
2107
                        $file->get_filename()
2108
                    );
2109
 
2110
                    $output .= $fileurl;
2111
                }
2112
            }
2113
        }
2114
 
2115
        return $output;
2116
    }
2117
 
2118
    public function custom_course_name()
2119
    {
2120
        global $DB, $CFG, $COURSE, $PAGE;
2121
 
2122
        $output = null;
2123
 
2124
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2125
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2126
                // Get custom field by name
2127
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2128
                // Get value
2129
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2130
                if (!empty($customcoursename)) {
2131
                    $output .= $customcoursename->value;
2132
                }
2133
            } else {
2134
                $customcoursename = null;
2135
            }
2136
        }
2137
 
2138
        return $output;
2139
    }
2140
 
2141
    /**
2142
     * Get the course pattern datauri to show on a course card.
2143
     *
2144
     * The datauri is an encoded svg that can be passed as a url.
2145
     * @param int $id Id to use when generating the pattern
2146
     * @return string datauri
2147
     */
2148
    public function get_generated_image_for_id($id)
2149
    {
2150
        global $CFG;
2151
 
2152
        $theme = \theme_config::load('universe');
2153
        // Add custom course cover.
2154
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2155
 
2156
        if (!empty(($customcover))) {
2157
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2158
            $customcover = str_replace($urlreplace, '', $customcover);
2159
            $txt = new moodle_url($customcover);
2160
            return strval($txt);
2161
        } else {
2162
            $color = $this->get_generated_color_for_id($id);
2163
            $pattern = new \core_geopattern();
2164
            $pattern->setColor($color);
2165
            $pattern->patternbyid($id);
2166
            return $pattern->datauri();
2167
        }
2168
    }
2169
 
2170
    public function moremenu_group_item()
2171
    {
2172
        global $CFG, $COURSE;
2173
 
2174
        $theme = \theme_config::load('universe');
2175
        $courseid = $COURSE->id;
2176
        $sitehomeurl = new moodle_url('/');
2177
 
2178
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2179
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2180
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2181
                return $html;
2182
            }
2183
        }
2184
    }
2185
 
2186
 
2187
    public function cesa_navigation_course_completion()
2188
    {
2189
        global $COURSE, $PAGE, $USER, $CFG;
2190
 
2191
        if (empty($PAGE->cm->id) || empty($COURSE->enablecompletion)) {
2192
            return '';
2193
        }
2194
 
2195
        $course_context = context_course::instance($COURSE->id);
2196
        $roles = get_user_roles($course_context, $USER->id, true);
2197
 
2198
        $completion_visible = true;
2199
        foreach ($roles as $role) {
2200
            if ($role->shortname != 'student') {
2201
                $completion_visible  = false;
2202
            }
2203
        }
2204
 
2205
        if (!$completion_visible) {
2206
            return '';
2207
        }
2208
        $PAGE->requires->js(new \moodle_url($CFG->wwwroot . '/local/cesanavigation/javascript/terminacion.js'));
2209
 
2210
        $page_context = $PAGE->cm;
2211
 
2212
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2213
 
2214
        $mods = [];
2215
        foreach ($modules as $module) {
2216
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2217
                continue;
2218
            }
2219
            $mods[$module->id] = $module;
2220
        }
2221
 
2222
 
2223
 
2224
        $nummods = count($mods);
2225
 
2226
        // If there is only one mod then do nothing.
2227
        if ($nummods == 1) {
2228
            return '';
2229
        }
2230
 
2231
        $modids = array_keys($mods);
2232
        $position = array_search($page_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2233
 
2234
        $currentmod = $mods[$modids[$position]];
2235
 
2236
        /*if(!$currentmod->completion) {
2237
            return '';
2238
        }*/
2239
 
2240
        $completioninfo = new \completion_info($COURSE);
2241
        $completiondata = $completioninfo->get_data($currentmod, true);
2242
        if ($completiondata->completionstate != COMPLETION_COMPLETE && $completiondata->completionstate != COMPLETION_COMPLETE_PASS) {
2243
            $url = new \moodle_url($CFG->wwwroot . '/local/cesanavigation/terminacion.php', ['courseid' => $COURSE->id, 'modid' =>  $currentmod->id]);
2244
 
2245
 
2246
            return '<div class="containerr">
2247
                        <input type="button" class="btn btn-primary d-block mx-auto btn-cesa-course-completion button-cesa vertical-center center" data-url="' . $url . '" value="Completar y continuar">
2248
                    </div>';
2249
        }
2250
 
2251
        return '';
2252
    }
2253
 
2254
    public function moremenu_custom_items()
2255
    {
2256
        global $CFG, $COURSE, $USER;
2257
 
2258
        $theme = \theme_config::load('universe');
2259
        $html = '';
2260
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2261
 
2262
        // Get current user role ID.
2263
        $context = context_course::instance($COURSE->id);
2264
        $roles = get_user_roles($context, $USER->id, true);
2265
        $role = 999;
2266
        $roleid = 999;
2267
        $role = key($roles);
2268
        if ($role != null) {
2269
            $roleid = $roles[$role]->roleid;
2270
        }
2271
 
2272
        // End.
2273
 
2274
        if ($this->page->theme->settings->secnavitems == 1) {
2275
 
2276
            $secnav = new stdClass();
2277
            for ($i = 1; $i <= $secnavcount; $i++) {
2278
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2279
 
2280
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2281
                $courseid = $COURSE->id;
2282
                $newurl = str_replace("{{courseID}}", $courseid, $url);
2283
 
2284
                // User role restriction.
2285
                $selectrole = theme_universe_get_setting("secnavuserroles" . $i);
2286
 
2287
                if ($roleid == $selectrole) {
2288
                    $secnav->url = $newurl;
2289
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2290
                }
2291
                if ($roleid != $selectrole) {
2292
                    $secnav->url = $newurl;
2293
                }
2294
                if ($selectrole == 0) {
2295
                    $secnav->url = $newurl;
2296
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2297
                }
2298
                // End.
2299
 
2300
            }
2301
        }
2302
        return $html;
2303
    }
2304
 
2305
    public function get_navbar_image_courses()
2306
    {
2307
        global $CFG;
2308
 
2309
        if (!empty($this->page->theme->settings->navbar_icon_courses)) {
2310
            $url = $this->page->theme->setting_file_url('navbar_icon_courses', 'navbar_icon_courses');
2311
            // Get a URL suitable for moodle_url.
2312
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2313
            $url = str_replace($relativebaseurl, '', $url);
2314
            return new moodle_url($url);
2315
        }
2316
 
2317
 
2318
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-catalog-white.png';
2319
    }
2320
 
2321
    public function get_navbar_image_progress()
2322
    {
2323
        global $CFG;
2324
 
2325
        if (!empty($this->page->theme->settings->navbar_icon_progress)) {
2326
            $url = $this->page->theme->setting_file_url('navbar_icon_progress', 'navbar_icon_progress');
2327
            // Get a URL suitable for moodle_url.
2328
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2329
            $url = str_replace($relativebaseurl, '', $url);
2330
            return new moodle_url($url);
2331
        }
2332
 
2333
 
2334
 
2335
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-progress-white.png';
2336
    }
2337
 
2338
    public function get_navbar_image_forums()
2339
    {
2340
        global $CFG;
2341
 
2342
 
2343
        if (!empty($this->page->theme->settings->navbar_icon_forums)) {
2344
            $url = $this->page->theme->setting_file_url('navbar_icon_forums', 'navbar_icon_forums');
2345
            // Get a URL suitable for moodle_url.
2346
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2347
            $url = str_replace($relativebaseurl, '', $url);
2348
            return new moodle_url($url);
2349
        }
2350
 
2351
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-forum-white.png';
2352
    }
2353
 
2354
    public function get_navbar_image_calendar()
2355
    {
2356
        global $CFG;
2357
 
2358
 
2359
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2360
            $url = $this->page->theme->setting_file_url('navbar_icon_calendar', 'navbar_icon_calendar');
2361
            // Get a URL suitable for moodle_url.
2362
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2363
            $url = str_replace($relativebaseurl, '', $url);
2364
            return new moodle_url($url);
2365
        }
2366
 
2367
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-calendar-white.png';
2368
    }
2369
 
2370
    public function get_theme_image_login_bg()
2371
    {
2372
        global  $DB, $CFG;
2373
 
2374
        if (!empty($this->page->theme->settings->loginimagebackground)) {
2375
            $url = $this->page->theme->setting_file_url('loginimagebackground', 'loginimagebackground');
2376
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2377
            $url = str_replace($relativebaseurl, '', $url);
2378
            return new moodle_url($url);
2379
        }
2380
 
2381
        return '';
2382
    }
2383
 
2384
    public function get_navbar_image_personal_area()
2385
    {
2386
        global $CFG;
2387
 
2388
 
2389
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2390
            $url = $this->page->theme->setting_file_url('navbar_icon_personal_area', 'navbar_icon_personal_area');
2391
            // Get a URL suitable for moodle_url.
2392
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2393
            $url = str_replace($relativebaseurl, '', $url);
2394
            return new moodle_url($url);
2395
        }
2396
 
2397
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-personal-area-white.png';
2398
    }
2399
 
2400
    public function get_navbar_image_messages()
2401
    {
2402
        global $CFG;
2403
 
2404
 
2405
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2406
            $url = $this->page->theme->setting_file_url('navbar_icon_messages', 'navbar_icon_messages');
2407
            // Get a URL suitable for moodle_url.
2408
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2409
            $url = str_replace($relativebaseurl, '', $url);
2410
            return new moodle_url($url);
2411
        }
2412
 
2413
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-messages-white.png';
2414
    }
2415
 
2416
    private function extractDurationFromVideo($record, $filename)
2417
    {
2418
        global $DB;
2419
 
2420
        $duration = 0;
2421
 
2422
        if (empty($record->duration)) {
2423
            $fs = get_file_storage();
2424
            $file = $fs->get_file($record->contextid, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename);
2425
            if ($file) {
2426
 
2427
                $data = $file->get_content();
2428
 
2429
                $path_temp = __DIR__ . DIRECTORY_SEPARATOR . 'tmp';
2430
                if (!file_exists($path_temp)) {
2431
                    mkdir($path_temp, 0755);
2432
                }
2433
 
2434
                $full_filename = $path_temp . DIRECTORY_SEPARATOR . uniqid() . '_' . $filename;
2435
                file_put_contents($full_filename, $data);
2436
 
2437
                if (file_exists($full_filename)) {
2438
                    $cmd = "/usr/bin/ffprobe -i $full_filename -show_entries format=duration -v quiet -of csv=\"p=0\" ";
2439
                    $response = trim(shell_exec($cmd));
2440
                    @unlink($full_filename);
2441
 
2442
 
2443
                    $duration = $response;
2444
 
2445
 
2446
                    if ($response) {
2447
                        $response = floatval($response);
2448
 
2449
                        if ($response > 60) {
2450
 
2451
                            //echo 'response = ' . $response . '<br>';
2452
 
2453
                            $minutes = intval($response / 60);
2454
                            //echo 'minutes = ' . $minutes . '<br>';
2455
 
2456
                            $seconds = round(($response - ($minutes * 60)));
2457
                            //echo 'seconds = ' . $seconds . '<br>';
2458
 
2459
 
2460
                            if ($minutes < 10) {
2461
                                $duration = '0' . $minutes;
2462
                            } else {
2463
                                $duration = $minutes;
2464
                            }
2465
 
2466
                            if ($seconds) {
2467
                                if ($seconds < 10) {
2468
                                    $duration = $duration . ':0' . $seconds;
2469
                                } else {
2470
                                    $duration = $duration . ':' . $seconds;
2471
                                }
2472
                            } else {
2473
                                $duration = $duration . ':00';
2474
                            }
2475
                        } else {
2476
                            $duration = '00:' . intval($response);
2477
                        }
2478
 
2479
 
2480
 
2481
                        $dataobject = new \stdClass();
2482
                        $dataobject->id = $record->id;
2483
                        $dataobject->duration = $duration;
2484
 
2485
 
2486
 
2487
                        $DB->update_record('files', $dataobject);
2488
                    }
2489
                }
2490
            }
2491
        }
2492
        return $duration;
2493
    }
2494
 
2495
    private function substr_cesa_navigation_course_menu_name($s, $l = 50)
2496
    {
2497
        $s = trim($s);
2498
        if (strlen($s) > $l) {
2499
            $s = substr($s, 0, $l) . '...';
2500
        }
2501
        return $s;
2502
    }
2503
 
2504
    public function cesa_navigation_course_menu_lateral_output()
2505
    {
2506
 
2507
 
2508
 
2509
        global $CFG, $COURSE, $PAGE, $DB, $OUTPUT;
2510
 
2511
 
2512
 
2513
 
2514
        if (!$COURSE->id) {
2515
            return '';
2516
        }
2517
 
2518
        $course_id = $COURSE->id;
2519
 
2520
        $parent = optional_param('parent', 0, PARAM_INT); // Course module id
2521
        if (!$parent) {
2522
            $parent = optional_param('amp;parent', 0, PARAM_INT); // Course module id
2523
        }
2524
 
2525
        //$PAGE->requires->js('/theme/edumynew/javascript/menu-lateral.js');
2526
 
2527
 
2528
        if ($parent) {
2529
            $sql  = ' SELECT * FROM {subcourse} WHERE course = ' . $parent;
2530
            $sql .= ' AND refcourse = ' . $course_id;
2531
 
2532
            $recordParentRefCourse  = $DB->get_record_sql($sql);
2533
            if ($recordParentRefCourse) {
2534
                $course_id = $recordParentRefCourse->course;
2535
            }
2536
        }
2537
 
2538
 
2539
 
2540
        $course = get_course($course_id);
2541
        $course_context = context_course::instance($course->id);
2542
        $completioninfo = new \completion_info($course);
2543
 
2544
        // $course_context = !empty($PAGE->cm->id)  ? $PAGE->cm : \context_course::instance($COURSE->id);
2545
        // First we should check if we want to add navigation.
2546
        // Get a list of all the activities in the course.
2547
 
2548
 
2549
 
2550
        $menu = [];
2551
 
2552
        $currentServerLink = strtolower(trim($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']));
2553
        $currentServerLink = html_entity_decode($currentServerLink);
2554
        $currentServerLink = htmlentities($currentServerLink);
2555
 
2556
        $parts = explode('&', $currentServerLink);
2557
        if (count($parts) > 1) {
2558
            $currentServerLink = $parts[0];
2559
        }
2560
 
2561
 
2562
 
2563
 
2564
        $modules = get_fast_modinfo($course->id)->get_cms();
2565
 
2566
        $prevmod = null;
2567
        $nextmod = null;
2568
        $currentmod = new stdClass();
2569
        $currentmod->name = "Sin Módulos";
2570
        $mods = [];
2571
        $menu = [];
2572
        $numberOfTemary = 1;
2573
        $prevlink = new \StdClass();
2574
        $nextlink = new \StdClass();
2575
        $prevlink->url = "#";
2576
        $nextlink->url = "#";
2577
 
2578
        $isACoursePage = $course->id !== "1" ? true : false;
2579
 
2580
 
2581
 
2582
 
2583
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2584
        /*
2585
            echo '<pre>';
2586
            print_r($modules);
2587
            echo '</pre>';
2588
            */
2589
 
2590
        if (!empty($modules)) {
2591
            // Put the modules into an array in order by the position they are shown in the course.
2592
            foreach ($modules as $module) {
2593
                if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2594
                    continue;
2595
                }
2596
                $mods[$module->id] = $module;
2597
            }
2598
 
2599
 
2600
            $nummods = count($mods);
2601
 
2602
 
2603
            // If there is only one mod then do nothing.
2604
            if ($nummods == 1) {
2605
            }
2606
 
2607
            // Get an array of just the course module ids used to get the cmid value based on their position in the course.
2608
            $modids = array_keys($mods);
2609
 
2610
            // Get the position in the array of the course module we are viewing.
2611
            $position = array_search($course_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2612
 
2613
            $currentmod = $mods[$modids[$position]];
2614
 
2615
 
2616
 
2617
            // Check if we have a previous mod to show.
2618
            if ($position > 0) {
2619
                $prevmod = $mods[$modids[$position - 1]];
2620
            }
2621
 
2622
            // Check if we have a next mod to show.
2623
            if ($position < ($nummods - 1)) {
2624
                $nextmod = $mods[$modids[$position + 1]];
2625
            }
2626
        }
2627
 
2628
 
2629
        //$sections = $DB->get_records('course_sections', ['course' => $COURSE->id], 'section ASC', 'id,name,section,sequence,visible');
2630
 
2631
 
2632
 
2633
 
2634
        $modinfo = get_fast_modinfo($course);
2635
        $records  =  $modinfo->get_section_info_all();
2636
        $sections = [];
2637
 
2638
        foreach ($records as $record) {
2639
            if (!$record->visible) {
2640
                continue;
2641
            }
2642
 
2643
            $section = new \stdClass();
2644
            $section->id = $record->id;
2645
            $section->section = $record->section;
2646
            $section->name = $record->name;
2647
            $section->parent = $record->parent;
2648
            $section->visible = 1;
2649
 
2650
 
2651
            array_push($sections, $section);
2652
        }
2653
 
2654
 
2655
 
2656
        $openParent = 0;
2657
        $maxSections = count($sections);
2658
        for ($i = 0; $i < $maxSections; $i++) {
2659
 
2660
 
2661
 
2662
            $j = $i + 1;
2663
            if ($j < $maxSections) {
2664
 
2665
                if ($sections[$j]->parent) {
2666
                    $openParent = true;
2667
                    $sections[$i]->close_section_parent = 0;
2668
                    $sections[$i]->close_section = 0;
2669
                } else {
2670
                    $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2671
 
2672
                    $sections[$i]->close_section = 1;
2673
                }
2674
            } else {
2675
                $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2676
                $sections[$i]->close_section = 1;
2677
            }
2678
 
2679
            // print_r($section);
2680
 
2681
 
2682
        }
2683
 
2684
        /*
2685
             echo '<pre>';
2686
           print_r($sections);
2687
           echo '</pre>';
2688
 
2689
      */
2690
 
2691
 
2692
 
2693
 
2694
        foreach ($sections as $key =>  $section) {
2695
 
2696
            if (!$section->visible) {
2697
                continue;
2698
            }
2699
 
2700
            $activities = [];
2701
            $section_active = false;
2702
 
2703
            foreach ($modules as $module) {
2704
 
2705
                if ($module->section  != $section->id) {
2706
                    continue;
2707
                }
2708
 
2709
                if (!$module->uservisible || $module->is_stealth()) {
2710
                    // if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2711
                    continue;
2712
                }
2713
 
2714
                $mods[$module->id] = $module;
2715
 
2716
                $duration = '';
2717
                $type = '';
2718
                $filepath = '';
2719
 
2720
                $sql = 'SELECT md.name, cm.instance  FROM {modules} md  ' .
2721
                    ' JOIN {course_modules} cm ON cm.module = md.id ' .
2722
                    ' WHERE cm.id = '  . $module->id . ' LIMIT 1 ';
2723
 
2724
                $record = $DB->get_record_sql($sql);
2725
                if ($record) {
2726
 
2727
                    /*
2728
                        echo '<pre>';
2729
                        print_r($record);
2730
                        echo '<pre>';
2731
                        */
2732
 
2733
                    $type = $record->name;
2734
 
2735
                    if ($type == 'hvp') {
2736
                        $instance   = $record->instance;
2737
 
2738
                        $sql = 'SELECT json_content FROM {hvp} WHERE id = ' . $instance . ' LIMIT 1';
2739
                        $record = $DB->get_record_sql($sql);
2740
 
2741
                        if ($record) {
2742
                            $json_content = json_decode($record->json_content);
2743
 
2744
                            if (!empty($json_content->interactiveVideo->video->files[0]->path)) {
2745
                                $filepath = trim($json_content->interactiveVideo->video->files[0]->path);
2746
                                $filepath = trim(str_replace('#tmp', '', $filepath));
2747
 
2748
 
2749
                                $arr = explode('/', $filepath);
2750
                                if (count($arr) > 1) {
2751
                                    $filename = $arr[count($arr) - 1];
2752
                                } else {
2753
                                    $filename = $arr[0];
2754
                                }
2755
 
2756
                                $record = $DB->get_record('files', ['filename' => $filename]);
2757
                                if ($record) {
2758
                                    $duration = $this->extractDurationFromVideo($record, $filename);
2759
                                }
2760
                            }
2761
                        }
2762
                    }
2763
                }
2764
 
2765
                $modname = $module->get_formatted_name();
2766
                $modcontent = $module->get_formatted_content();
2767
 
2768
                if (empty($module->url)) {
2769
                    $linkurl = '';
2770
                    $currentLink = '';
2771
                } else {
2772
 
2773
                    $linkurl = new moodle_url($module->url, array('forceview' => 1));
2774
                    $linkurl = strtolower(trim($linkurl->__toString()));
2775
 
2776
                    $parts = explode('&', $linkurl);
2777
                    if (count($parts) > 1) {
2778
                        $currentLink = $parts[0];
2779
                    } else {
2780
                        $currentLink = $linkurl;
2781
                    }
2782
                }
2783
 
2784
                $completiondata = $completioninfo->get_data($module, true);
2785
 
2786
                if (strcasecmp($currentLink,  $currentServerLink) == 0) {
2787
                    $active = true;
2788
                    $section_active = true;
2789
                } else {
2790
                    $active = false;
2791
                }
2792
 
2793
                array_push($activities, [
2794
                    'active' => $active,
2795
                    'indexElement' => $key,
2796
                    'numberOfTemary' => $numberOfTemary,
2797
                    'activity' => true,
2798
                    'blank' => !empty($section->section),
2799
                    'name' => $this->substr_cesa_navigation_course_menu_name($modname),
2800
                    'content' => $modcontent,
2801
                    'duration' => $duration,
2802
                    'type' =>  $type,
2803
                    'completed' => $completiondata->completionstate == COMPLETION_COMPLETE || $completiondata->completionstate == COMPLETION_COMPLETE_PASS,
2804
                    'failed' => $completiondata->completionstate == COMPLETION_COMPLETE_FAIL,
2805
                    'url' => $linkurl
2806
                ]);
2807
            }
2808
 
2809
 
2810
            if ($activities) {
2811
 
2812
                if ($section->section) {
2813
                    $sectionname = trim($section->name);
2814
                    $sectionname = $sectionname ? $sectionname : ' Tema ' . $section->section;
2815
                } else {
2816
                    $sectionname = 'Recursos';
2817
                }
2818
 
2819
                array_push($menu, [
2820
                    'active' => $section_active,
2821
                    'indexElement' => $key,
2822
                    'id' => $section->id,
2823
                    'numberOfTemary' => $numberOfTemary,
2824
                    'section' => true,
2825
                    'name' => $this->substr_cesa_navigation_course_menu_name($sectionname),
2826
                    'close_section_parent' => $section->close_section_parent,
2827
                    'close_section' => $section->close_section,
2828
                    'completed' => false,
2829
                    'url' => false,
2830
                    'activities' => $activities,
2831
 
2832
 
2833
                ]);
2834
            }
2835
 
2836
 
2837
            $numberOfTemary = ++$numberOfTemary;
2838
        }
2839
 
2840
        // Check if there is a previous module to display.
2841
        if ($prevmod) {
2842
            $linkurl = new \moodle_url($prevmod->url, array('forceview' => 1));
2843
            $attributes = [];
2844
            $prevlink = new \action_link($linkurl, $OUTPUT->larrow(), null, $attributes);
2845
        }
2846
 
2847
        // Check if there is a next module to display.
2848
        if ($nextmod) {
2849
            $linkurl = new \moodle_url($nextmod->url, array('forceview' => 1));
2850
            $attributes = [];
2851
            $nextlink = new \action_link($linkurl, $OUTPUT->rarrow(), null, $attributes);
2852
        }
2853
 
2854
 
2855
        //  echo '<pre>';
2856
        // print_r($activities);
2857
        // echo '</pre>';
2858
        // exit;
2859
 
2860
 
2861
        $progreso = number_format(progress::get_course_progress_percentage($course), 2); // Progreso por curso
2862
 
2863
        $course_navigation = new \theme_universe_child\output\custom_drawer($prevlink->url, $nextlink->url, $menu, $this->substr_cesa_navigation_course_menu_name($currentmod->name, 10), false, $isACoursePage,  $COURSE->summary, $progreso);
2864
        return $course_navigation->export_for_template($OUTPUT);
2865
    }
2866
 
1294 ariadna 2867
    function universe_child_course_drawer(): string
2868
    {
2869
        global $PAGE;
2870
 
2871
        // If the course index is explicitly set and if it should be hidden.
2872
        if ($PAGE->get_show_course_index() === false) {
2873
            return '';
2874
        }
2875
 
2876
        // Only add course index on non-site course pages.
2877
        if (!$PAGE->course || $PAGE->course->id == SITEID) {
2878
            return '';
2879
        }
2880
 
2881
        // Show course index to users can access the course only.
2882
        if (!can_access_course($PAGE->course, null, '', true)) {
2883
            return '';
2884
        }
2885
 
2886
        $format = course_get_format($PAGE->course);
2887
        $renderer = $format->get_renderer($PAGE);
2888
        if (method_exists($renderer, 'course_index_drawer')) {
2889
            return $this->render_from_template('theme_universe_child/courseindex/drawer', []);
2890
        }
2891
 
2892
        return '';
2893
    }
1291 ariadna 2894
}