Proyectos de Subversion Moodle

Rev

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