Proyectos de Subversion Moodle

Rev

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