Proyectos de Subversion Moodle

Rev

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

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