Proyectos de Subversion Moodle

Rev

Rev 1286 | Rev 1289 | 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
 */
54
class core_renderer extends \core_renderer
55
{
56
 
257 ariadna 57
    public function edit_button(moodle_url $url, string $method = 'post')
58
    {
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();
84
        global $USER;
85
 
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 {
1288 ariadna 129
            $candidate = $CFG->dirroot . theme_universe_child_themedir() . '/universe_child/layout/parts/' . $element;
257 ariadna 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)) {
251
            $userid = $USER->id;
252
        }
253
 
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') {
520 ariadna 633
            $html .= $this->render_from_template('theme_universe/header', $header);
257 ariadna 634
        }
635
 
636
        if ($this->page->pagelayout == 'admin') {
520 ariadna 637
            $html .= $this->render_from_template('theme_universe/header_admin', $header);
257 ariadna 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
 
520 ariadna 696
        $html .= $this->render_from_template('theme_universe/header', $header);
257 ariadna 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');
891 ariadna 823
        if ($this->cesa_navigation_course_completion() == '') {
824
            return $renderer->render($activitynav);
825
        }
826
        return '';
257 ariadna 827
    }
828
 
829
 
901 ariadna 830
 
257 ariadna 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'
1293
        );
1294
 
1295
        // Create a divider (well, a filler).
1296
        $divider = new action_menu_filler();
1297
        $divider->primary = false;
1298
 
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
 
1101 ariadna 1362
 
1363
 
257 ariadna 1364
        return html_writer::div(
1365
            $this->render($am),
1366
            $usermenuclasses
1367
        );
1368
    }
1369
 
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
 
1191 ariadna 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
257 ariadna 1768
        $context = context_course::instance($COURSE->id);
1191 ariadna 1769
        $roles = get_user_roles($context, $USER->id, true) ?: [];
257 ariadna 1770
 
1191 ariadna 1771
        // Agregar clases según los roles del usuario
1772
        if (!empty($roles)) {
257 ariadna 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
 
1191 ariadna 1780
        // Verificar configuración de edición
1781
        if (!empty($theme->settings->topbareditmode) && $theme->settings->topbareditmode == '1') {
257 ariadna 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
 
1191 ariadna 1791
 
257 ariadna 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
 
256 ariadna 1858
    public function render_statics_blocks($userid = null)
1859
    {
1860
        global $USER;
1861
 
1862
        if (!$userid) {
1863
            $userid = $USER->id;
1864
        }
1865
 
1866
        // Instanciamos StaticsBlocks para renderizar los bloques
379 ariadna 1867
        $statics_blocks = new \StaticsBlocks(
383 ariadna 1868
            'side-pre',
968 ariadna 1869
            ['messageteacher', 'comments', 'cesa_course_rating', 'cesa_notes']
379 ariadna 1870
        );
1871
 
256 ariadna 1872
        $blocks = $statics_blocks->renderBlocks();
1873
 
1874
        return $blocks;
1875
    }
257 ariadna 1876
 
1877
 
1878
    /**
1879
     * Color Customization
1880
     * @return string HTML fragment.
1881
     */
1882
    public function additional_head_html()
1883
    {
1884
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1885
 
1886
        $output = null;
1887
 
1888
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1889
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1890
                // Get custom field by name
1891
                $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1892
                // Get value
1893
                $mainthemecolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id));
1894
            } else {
1895
                $mainthemecolor = null;
1896
            }
1897
 
1898
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1899
                $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1900
                $mainthemecolor2 = $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id));
1901
            }
1902
 
1903
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1904
                // Get custom field by name
1905
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1906
                // Get value
1907
                $topbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1908
            }
1909
 
1910
            if ($DB->record_exists('customfield_field', array('shortname' => 'dmtopbarcolor'), 'id')) {
1911
                // Get custom field by name
1912
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1913
                // Get value
1914
                $dmtopbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1915
            } else {
1916
                $dmtopbarcolor = null;
1917
            }
1918
 
1919
 
1920
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1921
                // Get custom field by name
1922
                $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1923
                // Get value
1924
                $footercolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id));
1925
            } else {
1926
                $footercolor = null;
1927
            }
1928
 
1929
 
1930
            $css = '';
1931
 
1932
            $css .= ':root { ';
1933
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1934
                if ($mainthemecolor != null) {
1935
                    $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1936
                    $css .= '--primary-color-100: ' . $mainthemecolor->value . '30; ';
1937
                    $css .= '--primary-color-300: ' . $mainthemecolor->value . '70; ';
1938
                    $css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1939
                    $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1940
                    $css .= '--btn-primary-color-bg-hover: ' . $mainthemecolor->value . '95; ';
1941
 
1942
                    if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1943
                        if ($mainthemecolor2 != null) {
1944
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor2->value . '; ';
1945
                        } else {
1946
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor->value . '30; ';
1947
                        }
1948
                    }
1949
                }
1950
            }
1951
 
1952
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1953
                if ($topbarcolor != null) {
1954
                    $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1955
                    if ($dmtopbarcolor != null) {
1956
                        $css .= '--dm-topbar-color: ' . $dmtopbarcolor->value . '; ';
1957
                    } else {
1958
                        $css .= '--dm-topbar-color: ' . $topbarcolor->value . '; ';
1959
                    }
1960
                }
1961
            }
1962
 
1963
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1964
                if ($footercolor != null) {
1965
                    $css .= '--footer-color: ' . $footercolor->value . '; ';
1966
                }
1967
            }
1968
 
1969
            $css .= '}';
1970
 
1971
            if ($css) {
1972
                $output .= '<style>' . $css . '</style>';
1973
            }
1974
        }
1975
 
1976
        return $output;
1977
    }
1978
 
1979
    public function custom_course_logo()
1980
    {
1981
        global $DB, $CFG, $COURSE, $PAGE;
1982
 
1983
        $output = null;
1984
 
1985
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1986
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1987
                // Get custom field ID
1988
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1989
                $customfieldpicid = $customfieldpic->id;
1990
                // Get value
1991
                $customlogo = $DB->get_record(
1992
                    'customfield_data',
1993
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1994
                );
1995
 
1996
                $customlogoid = $customlogo->id;
1997
                $contextid = $customlogo->contextid;
1998
 
1999
                if ($customfieldpic != null) {
2000
                    $files = get_file_storage()->get_area_files(
2001
                        $contextid,
2002
                        'customfield_picture',
2003
                        'file',
2004
                        $customlogoid,
2005
                        '',
2006
                        false
2007
                    );
2008
 
2009
                    if (empty($files)) {
2010
                        return null;
2011
                    }
2012
 
2013
                    $file = reset($files);
2014
                    $fileurl = moodle_url::make_pluginfile_url(
2015
                        $file->get_contextid(),
2016
                        $file->get_component(),
2017
                        $file->get_filearea(),
2018
                        $file->get_itemid(),
2019
                        $file->get_filepath(),
2020
                        $file->get_filename()
2021
                    );
2022
 
2023
                    $output .= $fileurl;
2024
                }
2025
            }
2026
        }
2027
 
2028
        return $output;
2029
    }
2030
 
2031
    public function custom_course_dmlogo()
2032
    {
2033
        global $DB, $CFG, $COURSE, $PAGE;
2034
 
2035
        $output = null;
2036
 
2037
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2038
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
2039
                // Get custom field ID
2040
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
2041
                $customfieldpicid = $customfieldpic->id;
2042
                // Get value
2043
                $customlogo = $DB->get_record(
2044
                    'customfield_data',
2045
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2046
                );
2047
 
2048
                $customlogoid = $customlogo->id;
2049
                $contextid = $customlogo->contextid;
2050
 
2051
                if ($customfieldpic != null) {
2052
                    $files = get_file_storage()->get_area_files(
2053
                        $contextid,
2054
                        'customfield_picture',
2055
                        'file',
2056
                        $customlogoid,
2057
                        '',
2058
                        false
2059
                    );
2060
 
2061
                    if (empty($files)) {
2062
                        return null;
2063
                    }
2064
 
2065
                    $file = reset($files);
2066
                    $fileurl = moodle_url::make_pluginfile_url(
2067
                        $file->get_contextid(),
2068
                        $file->get_component(),
2069
                        $file->get_filearea(),
2070
                        $file->get_itemid(),
2071
                        $file->get_filepath(),
2072
                        $file->get_filename()
2073
                    );
2074
 
2075
                    $output .= $fileurl;
2076
                }
2077
            }
2078
        }
2079
 
2080
        return $output;
2081
    }
2082
 
2083
    public function custom_course_favicon()
2084
    {
2085
        global $DB, $CFG, $COURSE, $PAGE;
2086
 
2087
        $output = null;
2088
 
2089
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2090
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2091
                // Get custom field ID
2092
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2093
                $customfieldpicid = $customfieldpic->id;
2094
                // Get value
2095
                $customfavicon = $DB->get_record(
2096
                    'customfield_data',
2097
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2098
                );
2099
 
2100
                $customfaviconid = $customfavicon->id;
2101
                $contextid = $customfavicon->contextid;
2102
 
2103
                if ($customfieldpic != null) {
2104
                    $files = get_file_storage()->get_area_files(
2105
                        $contextid,
2106
                        'customfield_picture',
2107
                        'file',
2108
                        $customfaviconid,
2109
                        '',
2110
                        false
2111
                    );
2112
 
2113
                    if (empty($files)) {
2114
                        return null;
2115
                    }
2116
 
2117
                    $file = reset($files);
2118
                    $fileurl = moodle_url::make_pluginfile_url(
2119
                        $file->get_contextid(),
2120
                        $file->get_component(),
2121
                        $file->get_filearea(),
2122
                        $file->get_itemid(),
2123
                        $file->get_filepath(),
2124
                        $file->get_filename()
2125
                    );
2126
 
2127
                    $output .= $fileurl;
2128
                }
2129
            }
2130
        }
2131
 
2132
        return $output;
2133
    }
2134
 
2135
    public function custom_course_name()
2136
    {
2137
        global $DB, $CFG, $COURSE, $PAGE;
2138
 
2139
        $output = null;
2140
 
2141
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2142
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2143
                // Get custom field by name
2144
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2145
                // Get value
2146
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2147
                if (!empty($customcoursename)) {
2148
                    $output .= $customcoursename->value;
2149
                }
2150
            } else {
2151
                $customcoursename = null;
2152
            }
2153
        }
2154
 
2155
        return $output;
2156
    }
2157
 
2158
    /**
2159
     * Get the course pattern datauri to show on a course card.
2160
     *
2161
     * The datauri is an encoded svg that can be passed as a url.
2162
     * @param int $id Id to use when generating the pattern
2163
     * @return string datauri
2164
     */
2165
    public function get_generated_image_for_id($id)
2166
    {
2167
        global $CFG;
2168
 
2169
        $theme = \theme_config::load('universe');
2170
        // Add custom course cover.
2171
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2172
 
2173
        if (!empty(($customcover))) {
2174
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2175
            $customcover = str_replace($urlreplace, '', $customcover);
2176
            $txt = new moodle_url($customcover);
2177
            return strval($txt);
2178
        } else {
2179
            $color = $this->get_generated_color_for_id($id);
2180
            $pattern = new \core_geopattern();
2181
            $pattern->setColor($color);
2182
            $pattern->patternbyid($id);
2183
            return $pattern->datauri();
2184
        }
2185
    }
2186
 
2187
    public function moremenu_group_item()
2188
    {
2189
        global $CFG, $COURSE;
2190
 
2191
        $theme = \theme_config::load('universe');
2192
        $courseid = $COURSE->id;
2193
        $sitehomeurl = new moodle_url('/');
2194
 
2195
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2196
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2197
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2198
                return $html;
2199
            }
2200
        }
2201
    }
2202
 
369 ariadna 2203
 
2204
    public function cesa_navigation_course_completion()
2205
    {
2206
        global $COURSE, $PAGE, $USER, $CFG;
2207
 
2208
        if (empty($PAGE->cm->id) || empty($COURSE->enablecompletion)) {
2209
            return '';
2210
        }
2211
 
2212
        $course_context = context_course::instance($COURSE->id);
2213
        $roles = get_user_roles($course_context, $USER->id, true);
2214
 
2215
        $completion_visible = true;
2216
        foreach ($roles as $role) {
2217
            if ($role->shortname != 'student') {
2218
                $completion_visible  = false;
2219
            }
2220
        }
2221
 
2222
        if (!$completion_visible) {
891 ariadna 2223
            return '';
369 ariadna 2224
        }
2225
        $PAGE->requires->js(new \moodle_url($CFG->wwwroot . '/local/cesanavigation/javascript/terminacion.js'));
2226
 
2227
        $page_context = $PAGE->cm;
2228
 
2229
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2230
 
2231
        $mods = [];
2232
        foreach ($modules as $module) {
2233
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2234
                continue;
2235
            }
2236
            $mods[$module->id] = $module;
2237
        }
2238
 
2239
 
2240
 
2241
        $nummods = count($mods);
2242
 
2243
        // If there is only one mod then do nothing.
2244
        if ($nummods == 1) {
2245
            return '';
2246
        }
2247
 
2248
        $modids = array_keys($mods);
2249
        $position = array_search($page_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2250
 
2251
        $currentmod = $mods[$modids[$position]];
2252
 
2253
        /*if(!$currentmod->completion) {
2254
            return '';
2255
        }*/
2256
 
2257
        $completioninfo = new \completion_info($COURSE);
2258
        $completiondata = $completioninfo->get_data($currentmod, true);
2259
        if ($completiondata->completionstate != COMPLETION_COMPLETE && $completiondata->completionstate != COMPLETION_COMPLETE_PASS) {
2260
            $url = new \moodle_url($CFG->wwwroot . '/local/cesanavigation/terminacion.php', ['courseid' => $COURSE->id, 'modid' =>  $currentmod->id]);
2261
 
2262
 
2263
            return '<div class="containerr">
2264
                        <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">
2265
                    </div>';
2266
        }
2267
 
891 ariadna 2268
        return '';
369 ariadna 2269
    }
2270
 
257 ariadna 2271
    public function moremenu_custom_items()
2272
    {
2273
        global $CFG, $COURSE, $USER;
2274
 
2275
        $theme = \theme_config::load('universe');
2276
        $html = '';
2277
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2278
 
2279
        // Get current user role ID.
2280
        $context = context_course::instance($COURSE->id);
2281
        $roles = get_user_roles($context, $USER->id, true);
2282
        $role = 999;
2283
        $roleid = 999;
2284
        $role = key($roles);
2285
        if ($role != null) {
2286
            $roleid = $roles[$role]->roleid;
2287
        }
2288
 
2289
        // End.
2290
 
2291
        if ($this->page->theme->settings->secnavitems == 1) {
2292
 
2293
            $secnav = new stdClass();
2294
            for ($i = 1; $i <= $secnavcount; $i++) {
2295
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2296
 
2297
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2298
                $courseid = $COURSE->id;
2299
                $newurl = str_replace("{{courseID}}", $courseid, $url);
2300
 
2301
                // User role restriction.
2302
                $selectrole = theme_universe_get_setting("secnavuserroles" . $i);
2303
 
2304
                if ($roleid == $selectrole) {
2305
                    $secnav->url = $newurl;
2306
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2307
                }
2308
                if ($roleid != $selectrole) {
2309
                    $secnav->url = $newurl;
2310
                }
2311
                if ($selectrole == 0) {
2312
                    $secnav->url = $newurl;
2313
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2314
                }
2315
                // End.
2316
 
2317
            }
2318
        }
2319
        return $html;
2320
    }
655 ariadna 2321
 
2322
    public function get_navbar_image_courses()
2323
    {
2324
        global $CFG;
2325
 
2326
        if (!empty($this->page->theme->settings->navbar_icon_courses)) {
2327
            $url = $this->page->theme->setting_file_url('navbar_icon_courses', 'navbar_icon_courses');
2328
            // Get a URL suitable for moodle_url.
2329
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2330
            $url = str_replace($relativebaseurl, '', $url);
2331
            return new moodle_url($url);
2332
        }
2333
 
2334
 
686 ariadna 2335
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-catalog-white.png';
655 ariadna 2336
    }
2337
 
2338
    public function get_navbar_image_progress()
2339
    {
2340
        global $CFG;
2341
 
2342
        if (!empty($this->page->theme->settings->navbar_icon_progress)) {
2343
            $url = $this->page->theme->setting_file_url('navbar_icon_progress', 'navbar_icon_progress');
2344
            // Get a URL suitable for moodle_url.
2345
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2346
            $url = str_replace($relativebaseurl, '', $url);
2347
            return new moodle_url($url);
2348
        }
2349
 
2350
 
2351
 
686 ariadna 2352
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-progress-white.png';
655 ariadna 2353
    }
2354
 
2355
    public function get_navbar_image_forums()
2356
    {
2357
        global $CFG;
2358
 
2359
 
2360
        if (!empty($this->page->theme->settings->navbar_icon_forums)) {
2361
            $url = $this->page->theme->setting_file_url('navbar_icon_forums', 'navbar_icon_forums');
2362
            // Get a URL suitable for moodle_url.
2363
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2364
            $url = str_replace($relativebaseurl, '', $url);
2365
            return new moodle_url($url);
2366
        }
2367
 
686 ariadna 2368
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-forum-white.png';
655 ariadna 2369
    }
2370
 
2371
    public function get_navbar_image_calendar()
2372
    {
2373
        global $CFG;
2374
 
2375
 
2376
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2377
            $url = $this->page->theme->setting_file_url('navbar_icon_calendar', 'navbar_icon_calendar');
2378
            // Get a URL suitable for moodle_url.
2379
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2380
            $url = str_replace($relativebaseurl, '', $url);
2381
            return new moodle_url($url);
2382
        }
2383
 
687 ariadna 2384
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-calendar-white.png';
655 ariadna 2385
    }
669 ariadna 2386
 
682 ariadna 2387
    public function get_theme_image_login_bg()
669 ariadna 2388
    {
684 ariadna 2389
        global  $DB, $CFG;
681 ariadna 2390
 
682 ariadna 2391
        if (!empty($this->page->theme->settings->loginimagebackground)) {
2392
            $url = $this->page->theme->setting_file_url('loginimagebackground', 'loginimagebackground');
681 ariadna 2393
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2394
            $url = str_replace($relativebaseurl, '', $url);
2395
            return new moodle_url($url);
2396
        }
2397
 
684 ariadna 2398
        return '';
669 ariadna 2399
    }
693 ariadna 2400
 
2401
    public function get_navbar_image_personal_area()
2402
    {
2403
        global $CFG;
2404
 
2405
 
2406
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2407
            $url = $this->page->theme->setting_file_url('navbar_icon_personal_area', 'navbar_icon_personal_area');
2408
            // Get a URL suitable for moodle_url.
2409
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2410
            $url = str_replace($relativebaseurl, '', $url);
2411
            return new moodle_url($url);
2412
        }
2413
 
2414
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-personal-area-white.png';
2415
    }
694 ariadna 2416
 
2417
    public function get_navbar_image_messages()
2418
    {
2419
        global $CFG;
2420
 
2421
 
2422
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2423
            $url = $this->page->theme->setting_file_url('navbar_icon_messages', 'navbar_icon_messages');
2424
            // Get a URL suitable for moodle_url.
2425
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2426
            $url = str_replace($relativebaseurl, '', $url);
2427
            return new moodle_url($url);
2428
        }
2429
 
2430
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-messages-white.png';
2431
    }
901 ariadna 2432
 
2433
    private function extractDurationFromVideo($record, $filename)
2434
    {
2435
        global $DB;
2436
 
2437
        $duration = 0;
2438
 
2439
        if (empty($record->duration)) {
2440
            $fs = get_file_storage();
2441
            $file = $fs->get_file($record->contextid, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename);
2442
            if ($file) {
2443
 
2444
                $data = $file->get_content();
2445
 
2446
                $path_temp = __DIR__ . DIRECTORY_SEPARATOR . 'tmp';
2447
                if (!file_exists($path_temp)) {
2448
                    mkdir($path_temp, 0755);
2449
                }
2450
 
2451
                $full_filename = $path_temp . DIRECTORY_SEPARATOR . uniqid() . '_' . $filename;
2452
                file_put_contents($full_filename, $data);
2453
 
2454
                if (file_exists($full_filename)) {
2455
                    $cmd = "/usr/bin/ffprobe -i $full_filename -show_entries format=duration -v quiet -of csv=\"p=0\" ";
2456
                    $response = trim(shell_exec($cmd));
2457
                    @unlink($full_filename);
2458
 
2459
 
2460
                    $duration = $response;
2461
 
2462
 
2463
                    if ($response) {
2464
                        $response = floatval($response);
2465
 
2466
                        if ($response > 60) {
2467
 
2468
                            //echo 'response = ' . $response . '<br>';
2469
 
2470
                            $minutes = intval($response / 60);
2471
                            //echo 'minutes = ' . $minutes . '<br>';
2472
 
2473
                            $seconds = round(($response - ($minutes * 60)));
2474
                            //echo 'seconds = ' . $seconds . '<br>';
2475
 
2476
 
2477
                            if ($minutes < 10) {
2478
                                $duration = '0' . $minutes;
2479
                            } else {
2480
                                $duration = $minutes;
2481
                            }
2482
 
2483
                            if ($seconds) {
2484
                                if ($seconds < 10) {
2485
                                    $duration = $duration . ':0' . $seconds;
2486
                                } else {
2487
                                    $duration = $duration . ':' . $seconds;
2488
                                }
2489
                            } else {
2490
                                $duration = $duration . ':00';
2491
                            }
2492
                        } else {
2493
                            $duration = '00:' . intval($response);
2494
                        }
2495
 
2496
 
2497
 
2498
                        $dataobject = new \stdClass();
2499
                        $dataobject->id = $record->id;
2500
                        $dataobject->duration = $duration;
2501
 
2502
 
2503
 
2504
                        $DB->update_record('files', $dataobject);
2505
                    }
2506
                }
2507
            }
2508
        }
2509
        return $duration;
2510
    }
2511
 
2512
    private function substr_cesa_navigation_course_menu_name($s, $l = 50)
2513
    {
2514
        $s = trim($s);
2515
        if (strlen($s) > $l) {
2516
            $s = substr($s, 0, $l) . '...';
2517
        }
2518
        return $s;
2519
    }
2520
 
2521
    public function cesa_navigation_course_menu_lateral_output()
2522
    {
1169 ariadna 2523
 
2524
 
2525
 
901 ariadna 2526
        global $CFG, $COURSE, $PAGE, $DB, $OUTPUT;
2527
 
2528
 
2529
 
2530
 
2531
        if (!$COURSE->id) {
2532
            return '';
2533
        }
2534
 
2535
        $course_id = $COURSE->id;
2536
 
2537
        $parent = optional_param('parent', 0, PARAM_INT); // Course module id
2538
        if (!$parent) {
2539
            $parent = optional_param('amp;parent', 0, PARAM_INT); // Course module id
2540
        }
2541
 
1158 efrain 2542
        //$PAGE->requires->js('/theme/edumynew/javascript/menu-lateral.js');
901 ariadna 2543
 
2544
 
2545
        if ($parent) {
2546
            $sql  = ' SELECT * FROM {subcourse} WHERE course = ' . $parent;
2547
            $sql .= ' AND refcourse = ' . $course_id;
2548
 
2549
            $recordParentRefCourse  = $DB->get_record_sql($sql);
2550
            if ($recordParentRefCourse) {
2551
                $course_id = $recordParentRefCourse->course;
2552
            }
2553
        }
2554
 
2555
 
2556
 
2557
        $course = get_course($course_id);
2558
        $course_context = context_course::instance($course->id);
2559
        $completioninfo = new \completion_info($course);
2560
 
2561
        // $course_context = !empty($PAGE->cm->id)  ? $PAGE->cm : \context_course::instance($COURSE->id);
2562
        // First we should check if we want to add navigation.
2563
        // Get a list of all the activities in the course.
2564
 
2565
 
2566
 
2567
        $menu = [];
2568
 
2569
        $currentServerLink = strtolower(trim($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']));
2570
        $currentServerLink = html_entity_decode($currentServerLink);
2571
        $currentServerLink = htmlentities($currentServerLink);
2572
 
2573
        $parts = explode('&', $currentServerLink);
2574
        if (count($parts) > 1) {
2575
            $currentServerLink = $parts[0];
2576
        }
2577
 
2578
 
2579
 
2580
 
2581
        $modules = get_fast_modinfo($course->id)->get_cms();
2582
 
2583
        $prevmod = null;
2584
        $nextmod = null;
2585
        $currentmod = new stdClass();
2586
        $currentmod->name = "Sin Módulos";
2587
        $mods = [];
2588
        $menu = [];
2589
        $numberOfTemary = 1;
2590
        $prevlink = new \StdClass();
2591
        $nextlink = new \StdClass();
2592
        $prevlink->url = "#";
2593
        $nextlink->url = "#";
2594
 
2595
        $isACoursePage = $course->id !== "1" ? true : false;
2596
 
2597
 
2598
 
2599
 
2600
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2601
        /*
2602
            echo '<pre>';
2603
            print_r($modules);
2604
            echo '</pre>';
2605
            */
2606
 
2607
        if (!empty($modules)) {
2608
            // Put the modules into an array in order by the position they are shown in the course.
2609
            foreach ($modules as $module) {
2610
                if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2611
                    continue;
2612
                }
2613
                $mods[$module->id] = $module;
2614
            }
2615
 
2616
 
2617
            $nummods = count($mods);
2618
 
2619
 
2620
            // If there is only one mod then do nothing.
2621
            if ($nummods == 1) {
2622
            }
2623
 
2624
            // Get an array of just the course module ids used to get the cmid value based on their position in the course.
2625
            $modids = array_keys($mods);
2626
 
2627
            // Get the position in the array of the course module we are viewing.
2628
            $position = array_search($course_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2629
 
2630
            $currentmod = $mods[$modids[$position]];
2631
 
2632
 
2633
 
2634
            // Check if we have a previous mod to show.
2635
            if ($position > 0) {
2636
                $prevmod = $mods[$modids[$position - 1]];
2637
            }
2638
 
2639
            // Check if we have a next mod to show.
2640
            if ($position < ($nummods - 1)) {
2641
                $nextmod = $mods[$modids[$position + 1]];
2642
            }
2643
        }
2644
 
2645
 
2646
        //$sections = $DB->get_records('course_sections', ['course' => $COURSE->id], 'section ASC', 'id,name,section,sequence,visible');
2647
 
2648
 
2649
 
2650
 
2651
        $modinfo = get_fast_modinfo($course);
2652
        $records  =  $modinfo->get_section_info_all();
2653
        $sections = [];
2654
 
2655
        foreach ($records as $record) {
2656
            if (!$record->visible) {
2657
                continue;
2658
            }
2659
 
2660
            $section = new \stdClass();
2661
            $section->id = $record->id;
2662
            $section->section = $record->section;
2663
            $section->name = $record->name;
2664
            $section->parent = $record->parent;
2665
            $section->visible = 1;
2666
 
2667
 
2668
            array_push($sections, $section);
2669
        }
2670
 
2671
 
2672
 
2673
        $openParent = 0;
2674
        $maxSections = count($sections);
2675
        for ($i = 0; $i < $maxSections; $i++) {
2676
 
2677
 
2678
 
2679
            $j = $i + 1;
2680
            if ($j < $maxSections) {
2681
 
2682
                if ($sections[$j]->parent) {
2683
                    $openParent = true;
2684
                    $sections[$i]->close_section_parent = 0;
2685
                    $sections[$i]->close_section = 0;
2686
                } else {
2687
                    $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2688
 
2689
                    $sections[$i]->close_section = 1;
2690
                }
2691
            } else {
2692
                $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2693
                $sections[$i]->close_section = 1;
2694
            }
2695
 
2696
            // print_r($section);
2697
 
2698
 
2699
        }
2700
 
2701
        /*
2702
             echo '<pre>';
2703
           print_r($sections);
2704
           echo '</pre>';
2705
 
2706
      */
2707
 
2708
 
2709
 
2710
 
2711
        foreach ($sections as $key =>  $section) {
2712
 
2713
            if (!$section->visible) {
2714
                continue;
2715
            }
2716
 
2717
            $activities = [];
2718
            $section_active = false;
2719
 
2720
            foreach ($modules as $module) {
2721
 
2722
                if ($module->section  != $section->id) {
2723
                    continue;
2724
                }
2725
 
2726
                if (!$module->uservisible || $module->is_stealth()) {
2727
                    // if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2728
                    continue;
2729
                }
934 ariadna 2730
 
901 ariadna 2731
                $mods[$module->id] = $module;
2732
 
2733
                $duration = '';
2734
                $type = '';
2735
                $filepath = '';
2736
 
2737
                $sql = 'SELECT md.name, cm.instance  FROM {modules} md  ' .
2738
                    ' JOIN {course_modules} cm ON cm.module = md.id ' .
2739
                    ' WHERE cm.id = '  . $module->id . ' LIMIT 1 ';
2740
 
2741
                $record = $DB->get_record_sql($sql);
2742
                if ($record) {
2743
 
2744
                    /*
2745
                        echo '<pre>';
2746
                        print_r($record);
2747
                        echo '<pre>';
2748
                        */
2749
 
2750
                    $type = $record->name;
2751
 
2752
                    if ($type == 'hvp') {
2753
                        $instance   = $record->instance;
2754
 
2755
                        $sql = 'SELECT json_content FROM {hvp} WHERE id = ' . $instance . ' LIMIT 1';
2756
                        $record = $DB->get_record_sql($sql);
2757
 
2758
                        if ($record) {
2759
                            $json_content = json_decode($record->json_content);
2760
 
2761
                            if (!empty($json_content->interactiveVideo->video->files[0]->path)) {
2762
                                $filepath = trim($json_content->interactiveVideo->video->files[0]->path);
2763
                                $filepath = trim(str_replace('#tmp', '', $filepath));
2764
 
2765
 
2766
                                $arr = explode('/', $filepath);
2767
                                if (count($arr) > 1) {
2768
                                    $filename = $arr[count($arr) - 1];
2769
                                } else {
2770
                                    $filename = $arr[0];
2771
                                }
2772
 
2773
                                $record = $DB->get_record('files', ['filename' => $filename]);
2774
                                if ($record) {
2775
                                    $duration = $this->extractDurationFromVideo($record, $filename);
2776
                                }
2777
                            }
2778
                        }
2779
                    }
2780
                }
2781
 
934 ariadna 2782
                $modname = $module->get_formatted_name();
984 ariadna 2783
                $modcontent = $module->get_formatted_content();
901 ariadna 2784
 
2785
                if (empty($module->url)) {
2786
                    $linkurl = '';
2787
                    $currentLink = '';
2788
                } else {
2789
 
2790
                    $linkurl = new moodle_url($module->url, array('forceview' => 1));
2791
                    $linkurl = strtolower(trim($linkurl->__toString()));
2792
 
2793
                    $parts = explode('&', $linkurl);
2794
                    if (count($parts) > 1) {
2795
                        $currentLink = $parts[0];
2796
                    } else {
2797
                        $currentLink = $linkurl;
2798
                    }
2799
                }
2800
 
2801
                $completiondata = $completioninfo->get_data($module, true);
2802
 
2803
                if (strcasecmp($currentLink,  $currentServerLink) == 0) {
2804
                    $active = true;
2805
                    $section_active = true;
2806
                } else {
2807
                    $active = false;
2808
                }
2809
 
2810
                array_push($activities, [
2811
                    'active' => $active,
2812
                    'indexElement' => $key,
2813
                    'numberOfTemary' => $numberOfTemary,
2814
                    'activity' => true,
2815
                    'blank' => !empty($section->section),
2816
                    'name' => $this->substr_cesa_navigation_course_menu_name($modname),
984 ariadna 2817
                    'content' => $modcontent,
901 ariadna 2818
                    'duration' => $duration,
2819
                    'type' =>  $type,
2820
                    'completed' => $completiondata->completionstate == COMPLETION_COMPLETE || $completiondata->completionstate == COMPLETION_COMPLETE_PASS,
943 ariadna 2821
                    'failed' => $completiondata->completionstate == COMPLETION_COMPLETE_FAIL,
940 ariadna 2822
                    'url' => $linkurl
901 ariadna 2823
                ]);
2824
            }
2825
 
2826
 
2827
            if ($activities) {
2828
 
2829
                if ($section->section) {
2830
                    $sectionname = trim($section->name);
2831
                    $sectionname = $sectionname ? $sectionname : ' Tema ' . $section->section;
2832
                } else {
2833
                    $sectionname = 'Recursos';
2834
                }
2835
 
2836
                array_push($menu, [
2837
                    'active' => $section_active,
2838
                    'indexElement' => $key,
934 ariadna 2839
                    'id' => $section->id,
901 ariadna 2840
                    'numberOfTemary' => $numberOfTemary,
2841
                    'section' => true,
2842
                    'name' => $this->substr_cesa_navigation_course_menu_name($sectionname),
2843
                    'close_section_parent' => $section->close_section_parent,
2844
                    'close_section' => $section->close_section,
2845
                    'completed' => false,
2846
                    'url' => false,
2847
                    'activities' => $activities,
2848
 
2849
 
2850
                ]);
2851
            }
2852
 
2853
 
2854
            $numberOfTemary = ++$numberOfTemary;
2855
        }
2856
 
2857
        // Check if there is a previous module to display.
2858
        if ($prevmod) {
2859
            $linkurl = new \moodle_url($prevmod->url, array('forceview' => 1));
2860
            $attributes = [];
2861
            $prevlink = new \action_link($linkurl, $OUTPUT->larrow(), null, $attributes);
2862
        }
2863
 
2864
        // Check if there is a next module to display.
2865
        if ($nextmod) {
2866
            $linkurl = new \moodle_url($nextmod->url, array('forceview' => 1));
2867
            $attributes = [];
2868
            $nextlink = new \action_link($linkurl, $OUTPUT->rarrow(), null, $attributes);
2869
        }
2870
 
2871
 
2872
        //  echo '<pre>';
2873
        // print_r($activities);
2874
        // echo '</pre>';
2875
        // exit;
2876
 
2877
 
2878
        $progreso = number_format(progress::get_course_progress_percentage($course), 2); // Progreso por curso
2879
 
2880
        $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);
2881
        return $course_navigation->export_for_template($OUTPUT);
2882
    }
912 ariadna 2883
 
2884
    function universe_child_course_drawer(): string
2885
    {
2886
        global $PAGE;
2887
 
2888
        // If the course index is explicitly set and if it should be hidden.
2889
        if ($PAGE->get_show_course_index() === false) {
2890
            return '';
2891
        }
2892
 
2893
        // Only add course index on non-site course pages.
2894
        if (!$PAGE->course || $PAGE->course->id == SITEID) {
2895
            return '';
2896
        }
2897
 
2898
        // Show course index to users can access the course only.
2899
        if (!can_access_course($PAGE->course, null, '', true)) {
2900
            return '';
2901
        }
2902
 
2903
        $format = course_get_format($PAGE->course);
2904
        $renderer = $format->get_renderer($PAGE);
2905
        if (method_exists($renderer, 'course_index_drawer')) {
915 ariadna 2906
            return $this->render_from_template('theme_universe_child/courseindex/drawer', []);
912 ariadna 2907
        }
2908
 
2909
        return '';
2910
    }
256 ariadna 2911
}