Proyectos de Subversion Moodle

Rev

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