Proyectos de Subversion Moodle

Rev

Rev 194 | Rev 199 | 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);
198 ariadna 672
        $statics_blocks->renderBlocks();
673
        $context = [
674
            'blocks' => $statics_blocks,
675
        ];
676
 
677
        $html = $this->render_from_template('theme_universe/static-blocks', $header);
678
 
679
        return
168 ariadna 680
    }
194 ariadna 681
 
161 ariadna 682
    public function display_course_progress()
683
    {
1 efrain 684
        $html = null;
685
        $html .= $this->courseprogress($this->page->course);
686
        return $html;
687
    }
688
 
689
    /**
690
     * Wrapper for header elements.
691
     *
692
     * @return string HTML to display the main header.
693
     */
161 ariadna 694
    public function full_header()
695
    {
1 efrain 696
        global $USER, $COURSE, $CFG;
697
        $theme = \theme_config::load('universe');
698
        $html = null;
699
        $pagetype = $this->page->pagetype;
700
        $homepage = get_home_page();
701
        $homepagetype = null;
702
        // Add a special case since /my/courses is a part of the /my subsystem.
703
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
704
            $homepagetype = 'my-index';
705
        } else if ($homepage == HOMEPAGE_SITE) {
706
            $homepagetype = 'site-index';
707
        }
708
        if (
709
            $this->page->include_region_main_settings_in_header_actions() &&
710
            !$this->page->blocks->is_block_present('settings')
711
        ) {
712
            // Only include the region main settings if the page has requested it and it doesn't already have
713
            // the settings block on it. The region main settings are included in the settings block and
714
            // duplicating the content causes behat failures.
715
            $this->page->add_header_action(html_writer::div(
716
                $this->region_main_settings_menu(),
717
                'd-print-none',
718
                ['id' => 'region-main-settings-menu']
719
            ));
720
        }
721
 
722
        $header = new stdClass();
723
        $header->settingsmenu = $this->context_header_settings_menu();
724
        $header->contextheader = $this->context_header();
725
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
726
        $header->navbar = $this->navbar();
727
        $header->pageheadingbutton = $this->page_heading_button();
728
        $header->courseheader = $this->course_header();
729
        $header->headeractions = $this->page->get_header_actions();
730
 
731
        if ($this->page->theme->settings->ipcoursedetails == 1) {
732
            $html .= $this->course_details();
733
        }
734
 
735
        $html .= $this->render_from_template('theme_universe/header', $header);
736
        if ($this->page->theme->settings->ipcoursesummary == 1) {
737
            $html .= $this->course_summary();
738
        }
739
 
740
        $html .= html_writer::start_tag('div', array('class' => 'rui-course-header-color'));
741
        if ($this->page->theme->settings->cccteachers == 1) {
742
            $html .= $this->course_teachers();
743
        }
744
 
745
        $html .= html_writer::end_tag('div'); // End .rui-course-header.
746
 
747
        return $html;
748
    }
749
 
750
 
751
    /**
752
     * Wrapper for header elements.
753
     *
754
     * @return string HTML to display the main header.
755
     */
161 ariadna 756
    public function clean_header()
757
    {
1 efrain 758
        global $USER, $COURSE, $CFG;
759
        $theme = \theme_config::load('universe');
760
        $html = null;
761
        $pagetype = $this->page->pagetype;
762
        $homepage = get_home_page();
763
        $homepagetype = null;
764
        // Add a special case since /my/courses is a part of the /my subsystem.
765
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
766
            $homepagetype = 'my-index';
767
        } else if ($homepage == HOMEPAGE_SITE) {
768
            $homepagetype = 'site-index';
769
        }
770
        if (
771
            $this->page->include_region_main_settings_in_header_actions() &&
772
            !$this->page->blocks->is_block_present('settings')
773
        ) {
774
            // Only include the region main settings if the page has requested it and it doesn't already have
775
            // the settings block on it. The region main settings are included in the settings block and
776
            // duplicating the content causes behat failures.
777
            $this->page->add_header_action(html_writer::div(
778
                $this->region_main_settings_menu(),
779
                'd-print-none',
780
                ['id' => 'region-main-settings-menu']
781
            ));
782
        }
783
 
784
        $header = new stdClass();
785
        $header->courseheader = $this->course_header();
786
        $header->headeractions = $this->page->get_header_actions();
787
 
788
        $html .= $this->render_from_template('theme_universe/header', $header);
789
 
790
        return $html;
791
    }
792
 
793
 
794
    /**
795
     * Returns standard navigation between activities in a course.
796
     *
797
     * @return string the navigation HTML.
798
     */
161 ariadna 799
    public function activity_navigation()
800
    {
1 efrain 801
        // First we should check if we want to add navigation.
802
        $context = $this->page->context;
803
        if (($this->page->pagelayout !== 'incourse' && $this->page->pagelayout !== 'frametop')
804
            || $context->contextlevel != CONTEXT_MODULE
805
        ) {
806
            return '';
807
        }
808
        // If the activity is in stealth mode, show no links.
809
        if ($this->page->cm->is_stealth()) {
810
            return '';
811
        }
812
        $course = $this->page->cm->get_course();
813
        $courseformat = course_get_format($course);
814
 
815
        // Get a list of all the activities in the course.
816
        $modules = get_fast_modinfo($course->id)->get_cms();
817
        // Put the modules into an array in order by the position they are shown in the course.
818
        $mods = [];
819
        $activitylist = [];
820
        foreach ($modules as $module) {
821
            // Only add activities the user can access, aren't in stealth mode and have a url (eg. mod_label does not).
822
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
823
                continue;
824
            }
825
            $mods[$module->id] = $module;
826
            // No need to add the current module to the list for the activity dropdown menu.
827
            if ($module->id == $this->page->cm->id) {
828
                continue;
829
            }
830
            // Module name.
831
            $modname = $module->get_formatted_name();
832
            // Display the hidden text if necessary.
833
            if (!$module->visible) {
834
                $modname .= ' ' . get_string('hiddenwithbrackets');
835
            }
836
            // Module URL.
837
            $linkurl = new moodle_url($module->url, array('forceview' => 1));
838
            // Add module URL (as key) and name (as value) to the activity list array.
839
            $activitylist[$linkurl->out(false)] = $modname;
840
        }
841
        $nummods = count($mods);
842
        // If there is only one mod then do nothing.
843
        if ($nummods == 1) {
844
            return '';
845
        }
846
        // Get an array of just the course module ids used to get the cmid value based on their position in the course.
847
        $modids = array_keys($mods);
848
        // Get the position in the array of the course module we are viewing.
849
        $position = array_search($this->page->cm->id, $modids);
850
        $prevmod = null;
851
        $nextmod = null;
852
        // Check if we have a previous mod to show.
853
        if ($position > 0) {
854
            $prevmod = $mods[$modids[$position - 1]];
855
        }
856
        // Check if we have a next mod to show.
857
        if ($position < ($nummods - 1)) {
858
            $nextmod = $mods[$modids[$position + 1]];
859
        }
860
        $activitynav = new \core_course\output\activity_navigation($prevmod, $nextmod, $activitylist);
861
        $renderer = $this->page->get_renderer('core', 'course');
862
        return $renderer->render($activitynav);
863
    }
864
 
865
 
866
    /**
867
     * This is an optional menu that can be added to a layout by a theme. It contains the
868
     * menu for the course administration, only on the course main page.
869
     *
870
     * @return string
871
     */
161 ariadna 872
    public function context_header_settings_menu()
873
    {
1 efrain 874
        $context = $this->page->context;
875
        $menu = new action_menu();
876
 
877
        $items = $this->page->navbar->get_items();
878
        $currentnode = end($items);
879
 
880
        $showcoursemenu = false;
881
        $showfrontpagemenu = false;
882
        $showusermenu = false;
883
 
884
        // We are on the course home page.
885
        if (($context->contextlevel == CONTEXT_COURSE) &&
886
            !empty($currentnode) &&
887
            ($currentnode->type == navigation_node::TYPE_COURSE || $currentnode->type == navigation_node::TYPE_SECTION)
888
        ) {
889
            $showcoursemenu = true;
890
        }
891
 
892
        $courseformat = course_get_format($this->page->course);
893
        // This is a single activity course format, always show the course menu on the activity main page.
894
        if (
895
            $context->contextlevel == CONTEXT_MODULE &&
896
            !$courseformat->has_view_page()
897
        ) {
898
 
899
            $this->page->navigation->initialise();
900
            $activenode = $this->page->navigation->find_active_node();
901
            // If the settings menu has been forced then show the menu.
902
            if ($this->page->is_settings_menu_forced()) {
903
                $showcoursemenu = true;
904
            } else if (!empty($activenode) && ($activenode->type == navigation_node::TYPE_ACTIVITY ||
905
                $activenode->type == navigation_node::TYPE_RESOURCE)) {
906
 
907
                // We only want to show the menu on the first page of the activity. This means
908
                // the breadcrumb has no additional nodes.
909
                if ($currentnode && ($currentnode->key == $activenode->key && $currentnode->type == $activenode->type)) {
910
                    $showcoursemenu = true;
911
                }
912
            }
913
        }
914
 
915
        // This is the site front page.
916
        if (
917
            $context->contextlevel == CONTEXT_COURSE &&
918
            !empty($currentnode) &&
919
            $currentnode->key === 'home'
920
        ) {
921
            $showfrontpagemenu = true;
922
        }
923
 
924
        // This is the user profile page.
925
        if (
926
            $context->contextlevel == CONTEXT_USER &&
927
            !empty($currentnode) &&
928
            ($currentnode->key === 'myprofile')
929
        ) {
930
            $showusermenu = true;
931
        }
932
 
933
        if ($showfrontpagemenu) {
934
            $settingsnode = $this->page->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
935
            if ($settingsnode) {
936
                // Build an action menu based on the visible nodes from this navigation tree.
937
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
938
 
939
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
940
                if ($skipped) {
941
                    $text = get_string('morenavigationlinks');
942
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
943
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
944
                    $menu->add_secondary_action($link);
945
                }
946
            }
947
        } else if ($showcoursemenu) {
948
            $settingsnode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE);
949
            if ($settingsnode) {
950
                // Build an action menu based on the visible nodes from this navigation tree.
951
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
952
 
953
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
954
                if ($skipped) {
955
                    $text = get_string('morenavigationlinks');
956
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
957
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
958
                    $menu->add_secondary_action($link);
959
                }
960
            }
961
        } else if ($showusermenu) {
962
            // Get the course admin node from the settings navigation.
963
            $settingsnode = $this->page->settingsnav->find('useraccount', navigation_node::TYPE_CONTAINER);
964
            if ($settingsnode) {
965
                // Build an action menu based on the visible nodes from this navigation tree.
966
                $this->build_action_menu_from_navigation($menu, $settingsnode);
967
            }
968
        }
969
 
970
        return $this->render($menu);
971
    }
972
 
161 ariadna 973
    public function customeditblockbtn()
974
    {
1 efrain 975
        $header = new stdClass();
976
        $header->settingsmenu = $this->context_header_settings_menu();
977
        $header->pageheadingbutton = $this->page_heading_button();
978
 
979
        $html = $this->render_from_template('theme_universe/header_settings_menu', $header);
980
 
981
        return $html;
982
    }
983
 
984
    /**
985
     * Renders the context header for the page.
986
     *
987
     * @param array $headerinfo Heading information.
988
     * @param int $headinglevel What 'h' level to make the heading.
989
     * @return string A rendered context header.
990
     */
161 ariadna 991
    public function context_header($headerinfo = null, $headinglevel = 1): string
992
    {
1 efrain 993
        global $DB, $USER, $CFG, $SITE;
994
        require_once($CFG->dirroot . '/user/lib.php');
995
        $context = $this->page->context;
996
        $heading = null;
997
        $imagedata = null;
998
        $subheader = null;
999
        $userbuttons = null;
1000
 
1001
        // Make sure to use the heading if it has been set.
1002
        if (isset($headerinfo['heading'])) {
1003
            $heading = $headerinfo['heading'];
1004
        } else {
1005
            $heading = $this->page->heading;
1006
        }
1007
 
1008
        // The user context currently has images and buttons. Other contexts may follow.
1009
        if ((isset($headerinfo['user']) || $context->contextlevel == CONTEXT_USER) && $this->page->pagetype !== 'my-index') {
1010
            if (isset($headerinfo['user'])) {
1011
                $user = $headerinfo['user'];
1012
            } else {
1013
                // Look up the user information if it is not supplied.
1014
                $user = $DB->get_record('user', array('id' => $context->instanceid));
1015
            }
1016
 
1017
            // If the user context is set, then use that for capability checks.
1018
            if (isset($headerinfo['usercontext'])) {
1019
                $context = $headerinfo['usercontext'];
1020
            }
1021
 
1022
            // Only provide user information if the user is the current user, or a user which the current user can view.
1023
            // When checking user_can_view_profile(), either:
1024
            // If the page context is course, check the course context (from the page object) or;
1025
            // If page context is NOT course, then check across all courses.
1026
            $course = ($this->page->context->contextlevel == CONTEXT_COURSE) ? $this->page->course : null;
1027
 
1028
            if (user_can_view_profile($user, $course)) {
1029
                // Use the user's full name if the heading isn't set.
1030
                if (empty($heading)) {
1031
                    $heading = fullname($user);
1032
                }
1033
 
1034
                $imagedata = $this->user_picture($user, array('size' => 100));
1035
 
1036
                // Check to see if we should be displaying a message button.
1037
                if (!empty($CFG->messaging) && has_capability('moodle/site:sendmessage', $context)) {
1038
                    $userbuttons = array(
1039
                        'messages' => array(
1040
                            'buttontype' => 'message',
1041
                            'title' => get_string('message', 'message'),
1042
                            'url' => new moodle_url('/message/index.php', array('id' => $user->id)),
1043
                            'image' => 'message',
1044
                            'linkattributes' => \core_message\helper::messageuser_link_params($user->id),
1045
                            'page' => $this->page
1046
                        )
1047
                    );
1048
 
1049
                    if ($USER->id != $user->id) {
1050
                        $iscontact = \core_message\api::is_contact($USER->id, $user->id);
1051
                        $contacttitle = $iscontact ? 'removefromyourcontacts' : 'addtoyourcontacts';
1052
                        $contacturlaction = $iscontact ? 'removecontact' : 'addcontact';
1053
                        $contactimage = $iscontact ? 'removecontact' : 'addcontact';
1054
                        $userbuttons['togglecontact'] = array(
1055
                            'buttontype' => 'togglecontact',
1056
                            'title' => get_string($contacttitle, 'message'),
1057
                            'url' => new moodle_url(
1058
                                '/message/index.php',
1059
                                array(
1060
                                    'user1' => $USER->id,
1061
                                    'user2' => $user->id,
1062
                                    $contacturlaction => $user->id,
1063
                                    'sesskey' => sesskey()
1064
                                )
1065
                            ),
1066
                            'image' => $contactimage,
1067
                            'linkattributes' => \core_message\helper::togglecontact_link_params($user, $iscontact),
1068
                            'page' => $this->page
1069
                        );
1070
                    }
1071
 
1072
                    $this->page->requires->string_for_js('changesmadereallygoaway', 'moodle');
1073
                }
1074
            } else {
1075
                $heading = null;
1076
            }
1077
        }
1078
 
1079
        $prefix = null;
1080
        if ($context->contextlevel == CONTEXT_MODULE) {
1081
            if ($this->page->course->format === 'singleactivity') {
1082
                $heading = $this->page->course->fullname;
1083
            } else {
1084
                $heading = $this->page->cm->get_formatted_name();
1085
                $imagedata = $this->pix_icon('monologo', '', $this->page->activityname, ['class' => 'activityicon']);
1086
                $purposeclass = plugin_supports('mod', $this->page->activityname, FEATURE_MOD_PURPOSE);
1087
                $purposeclass .= ' activityiconcontainer';
1088
                $purposeclass .= ' modicon_' . $this->page->activityname;
1089
                $imagedata = html_writer::tag('div', $imagedata, ['class' => $purposeclass]);
1090
                $prefix = get_string('modulename', $this->page->activityname);
1091
            }
1092
        }
1093
 
1094
        $contextheader = new \context_header($heading, $headinglevel, $imagedata, $userbuttons, $prefix);
1095
        return $this->render_context_header($contextheader);
1096
    }
1097
 
1098
 
1099
    /**
1100
     * Construct a user menu, returning HTML that can be echoed out by a
1101
     * layout file.
1102
     *
1103
     * @param stdClass $user A user object, usually $USER.
1104
     * @param bool $withlinks true if a dropdown should be built.
1105
     * @return string HTML fragment.
1106
     */
161 ariadna 1107
    public function user_menu($user = null, $withlinks = null)
1108
    {
1 efrain 1109
        global $USER, $CFG;
1110
        require_once($CFG->dirroot . '/user/lib.php');
1111
 
1112
        if (is_null($user)) {
1113
            $user = $USER;
1114
        }
1115
 
1116
        // Note: this behaviour is intended to match that of core_renderer::login_info,
1117
        // but should not be considered to be good practice; layout options are
1118
        // intended to be theme-specific. Please don't copy this snippet anywhere else.
1119
        if (is_null($withlinks)) {
1120
            $withlinks = empty($this->page->layout_options['nologinlinks']);
1121
        }
1122
 
1123
        // Add a class for when $withlinks is false.
1124
        $usermenuclasses = 'usermenu';
1125
        if (!$withlinks) {
1126
            $usermenuclasses .= ' withoutlinks';
1127
        }
1128
 
1129
        $returnstr = "";
1130
 
1131
        // If during initial install, return the empty return string.
1132
        if (during_initial_install()) {
1133
            return $returnstr;
1134
        }
1135
 
1136
        $loginpage = $this->is_login_page();
1137
        $loginurl = get_login_url();
1138
        // If not logged in, show the typical not-logged-in string.
1139
        if (!isloggedin()) {
1140
            if (!$loginpage) {
1141
                $returnstr .= "<a class=\"rui-topbar-btn rui-login-btn\" href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1142
                    get_string('login') .
1143
                    '</span>
1144
                <svg class="ml-2" width="20" height="20" fill="none" viewBox="0 0 24 24">
1145
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1146
                d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1147
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1148
                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">
1149
                </path>
1150
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 12H4.75"></path>
1151
                </svg></a>';
1152
            }
1153
            return html_writer::div(
1154
                html_writer::span(
1155
                    $returnstr,
1156
                    'login'
1157
                ),
1158
                $usermenuclasses
1159
            );
1160
        }
1161
 
1162
        // If logged in as a guest user, show a string to that effect.
1163
        if (isguestuser()) {
1164
            $icon = '<svg class="mr-2"
1165
                width="24"
1166
                height="24"
1167
                viewBox="0 0 24 24"
1168
                fill="none"
1169
                xmlns="http://www.w3.org/2000/svg">
1170
            <path d="M10 12C10 12.5523 9.55228 13 9 13C8.44772 13 8 12.5523 8
1171
            12C8 11.4477 8.44772 11 9 11C9.55228 11 10 11.4477 10 12Z"
1172
                fill="currentColor"
1173
                />
1174
            <path d="M15 13C15.5523 13 16 12.5523 16 12C16 11.4477 15.5523 11
1175
            15 11C14.4477 11 14 11.4477 14 12C14 12.5523 14.4477 13 15 13Z"
1176
                fill="currentColor"
1177
                />
1178
            <path fill-rule="evenodd"
1179
                clip-rule="evenodd"
1180
                d="M12.0244 2.00003L12 2C6.47715 2 2 6.47715 2 12C2 17.5228
1181
                6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.74235
1182
            17.9425 2.43237 12.788 2.03059L12.7886 2.0282C12.5329 2.00891
1183
            12.278 1.99961 12.0244 2.00003ZM12 20C16.4183 20 20 16.4183 20
1184
            12C20 11.3014 19.9105 10.6237 19.7422
1185
            9.97775C16.1597 10.2313 12.7359 8.52461 10.7605 5.60246C9.31322
1186
            7.07886 7.2982 7.99666 5.06879 8.00253C4.38902 9.17866 4 10.5439 4
1187
            12C4 16.4183 7.58172 20
1188
            12 20ZM11.9785 4.00003L12.0236 4.00003L12 4L11.9785 4.00003Z"
1189
                fill="currentColor"
1190
                /></svg>';
1191
            $returnstr = '<div class="rui-badge-guest">' . $icon . get_string('loggedinasguest') . '</div>';
1192
            if (!$loginpage && $withlinks) {
1193
                $returnstr .= "<a class=\"rui-topbar-btn rui-login-btn\"
1194
                    href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1195
                    get_string('login') .
1196
                    '</span>
1197
                <svg class="ml-2"
1198
                    width="20"
1199
                    height="20"
1200
                    fill="none"
1201
                    viewBox="0 0 24 24">
1202
                <path stroke="currentColor"
1203
                    stroke-linecap="round"
1204
                    stroke-linejoin="round"
1205
                    stroke-width="2"
1206
                    d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1207
                <path stroke="currentColor"
1208
                    stroke-linecap="round"
1209
                    stroke-linejoin="round"
1210
                    stroke-width="2"
1211
                    d="M9.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25
1212
                    6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H9.75"></path>
1213
                    <path stroke="currentColor"
1214
                        stroke-linecap="round"
1215
                        stroke-linejoin="round"
1216
                        stroke-width="2"
1217
                        d="M13 12H4.75"></path></svg></a>';
1218
            }
1219
 
1220
            return html_writer::div(
1221
                html_writer::span(
1222
                    $returnstr,
1223
                    'login'
1224
                ),
1225
                $usermenuclasses
1226
            );
1227
        }
1228
 
1229
        // Get some navigation opts.
1230
        $opts = user_get_user_navigation_info($user, $this->page, array('avatarsize' => 56));
1231
 
1232
        $avatarclasses = "avatars";
1233
        $avatarcontents = html_writer::span($opts->metadata['useravatar'], 'avatar current');
1234
        $usertextcontents = '<span class="rui-fullname">' . $opts->metadata['userfullname'] . '</span>';
1235
        $usertextmail = $user->email;
1236
        $usernick = '<svg class="mr-1"
1237
            width="16"
1238
            height="16"
1239
            fill="none"
1240
            viewBox="0 0 24 24">
1241
        <path stroke="currentColor"
1242
            stroke-linecap="round"
1243
            stroke-linejoin="round"
1244
            stroke-width="2"
1245
            d="M12 13V15"></path>
1246
        <circle cx="12"
1247
            cy="9"
1248
            r="1"
1249
            fill="currentColor"></circle>
1250
        <circle cx="12"
1251
            cy="12"
1252
            r="7.25"
1253
            stroke="currentColor"
1254
            stroke-linecap="round"
1255
            stroke-linejoin="round"
1256
            stroke-width="1.5"></circle>
1257
        </svg>' . $user->username;
1258
 
1259
        // Other user.
1260
        $usermeta = '';
1261
        if (!empty($opts->metadata['asotheruser'])) {
1262
            $avatarcontents .= html_writer::span(
1263
                $opts->metadata['realuseravatar'],
1264
                'avatar realuser'
1265
            );
1266
            $usermeta .= $opts->metadata['realuserfullname'];
1267
            $usermeta .= html_writer::tag(
1268
                'span',
1269
                get_string(
1270
                    'loggedinas',
1271
                    'moodle',
1272
                    html_writer::span(
1273
                        $opts->metadata['userfullname'],
1274
                        'value'
1275
                    )
1276
                ),
1277
                array('class' => 'meta viewingas')
1278
            );
1279
        }
1280
 
1281
        // Role.
1282
        if (!empty($opts->metadata['asotherrole'])) {
1283
            $role = core_text::strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['rolename'])));
1284
            $usermeta .= html_writer::span(
1285
                $opts->metadata['rolename'],
1286
                'meta role role-' . $role
1287
            );
1288
        }
1289
 
1290
        // User login failures.
1291
        if (!empty($opts->metadata['userloginfail'])) {
1292
            $usermeta .= html_writer::div(
1293
                '<svg class="mr-1"
1294
                width="16"
1295
                height="16"
1296
                fill="none"
1297
                viewBox="0 0 24 24"><path stroke="currentColor"
1298
                stroke-linecap="round"
1299
                stroke-linejoin="round"
1300
                stroke-width="1.5"
1301
                d="M4.9522 16.3536L10.2152 5.85658C10.9531 4.38481 13.0539
1302
                4.3852 13.7913 5.85723L19.0495 16.3543C19.7156 17.6841 18.7487
1303
                19.25 17.2613 19.25H6.74007C5.25234
1304
                19.25 4.2854 17.6835 4.9522 16.3536Z">
1305
                </path><path stroke="currentColor"
1306
                stroke-linecap="round"
1307
                stroke-linejoin="round"
1308
                stroke-width="2"
1309
                d="M12 10V12"></path>
1310
                <circle cx="12" cy="16" r="1" fill="currentColor"></circle></svg>' .
1311
                    $opts->metadata['userloginfail'],
1312
                'meta loginfailures'
1313
            );
1314
        }
1315
 
1316
        // MNet.
1317
        if (!empty($opts->metadata['asmnetuser'])) {
1318
            $mnet = strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['mnetidprovidername'])));
1319
            $usermeta .= html_writer::span(
1320
                $opts->metadata['mnetidprovidername'],
1321
                'meta mnet mnet-' . $mnet
1322
            );
1323
        }
1324
 
1325
        $returnstr .= html_writer::span(
1326
            html_writer::span($avatarcontents, $avatarclasses),
1327
            'userbutton'
1328
        );
1329
 
1330
        // Create a divider (well, a filler).
1331
        $divider = new action_menu_filler();
1332
        $divider->primary = false;
1333
 
1334
        $am = new action_menu();
1335
        $am->set_menu_trigger(
1336
            $returnstr
1337
        );
1338
        $am->set_action_label(get_string('usermenu'));
1339
        $am->set_nowrap_on_items();
1340
 
1341
        if ($CFG->enabledashboard) {
1342
            $dashboardlink = '<div class="dropdown-item-wrapper"><a class="dropdown-item" href="' .
1343
                new moodle_url('/my/') .
1344
                '" data-identifier="dashboard,moodle" title="dashboard,moodle">' .
1345
                get_string('myhome', 'moodle') .
1346
                '</a></div>';
1347
        } else {
1348
            $dashboardlink = null;
1349
        }
1350
 
1351
        $am->add(
1352
            '<div class="dropdown-user-wrapper"><div class="dropdown-user">' . $usertextcontents  . '</div>'
1353
                . '<div class="dropdown-user-mail text-truncate" title="' . $usertextmail . '">' . $usertextmail . '</div>'
1354
                . '<span class="dropdown-user-nick w-100">' . $usernick . '</span>'
1355
                . '<div class="dropdown-user-meta"><span class="badge-xs badge-sq badge-warning flex-wrap">' .
1356
                $usermeta . '</span></div>'
1357
                . '</div><div class="dropdown-divider dropdown-divider-user"></div>' . $dashboardlink
1358
        );
1359
 
1360
        if ($withlinks) {
1361
            $navitemcount = count($opts->navitems);
1362
            $idx = 0;
1363
            foreach ($opts->navitems as $key => $value) {
1364
 
1365
                switch ($value->itemtype) {
1366
                    case 'divider':
1367
                        // If the nav item is a divider, add one and skip link processing.
1368
                        $am->add($divider);
1369
                        break;
1370
 
1371
                    case 'invalid':
1372
                        // Silently skip invalid entries (should we post a notification?).
1373
                        break;
1374
 
1375
                    case 'link':
1376
                        $al = '<a class="dropdown-item" href="' .
1377
                            $value->url .
1378
                            '" data-identifier="' .
1379
                            $value->titleidentifier .
1380
                            '" title="' .
1381
                            $value->titleidentifier .
1382
                            '">' .
1383
                            $value->title . '</a>';
1384
                        $am->add($al);
1385
                        break;
1386
                }
1387
 
1388
                $idx++;
1389
 
1390
                // Add dividers after the first item and before the last item.
1391
                if ($idx == 1 || $idx == $navitemcount - 1) {
1392
                    $am->add($divider);
1393
                }
1394
            }
1395
        }
1396
 
1397
        return html_writer::div(
1398
            $this->render($am),
1399
            $usermenuclasses
1400
        );
1401
    }
1402
 
1403
 
1404
    /**
1405
     * Returns standard main content placeholder.
1406
     * Designed to be called in theme layout.php files.
1407
     *
1408
     * @return string HTML fragment.
1409
     */
161 ariadna 1410
    public function main_content()
1411
    {
1 efrain 1412
        // This is here because it is the only place we can inject the "main" role over the entire main content area
1413
        // without requiring all theme's to manually do it, and without creating yet another thing people need to
1414
        // remember in the theme.
1415
        // This is an unfortunate hack. DO NO EVER add anything more here.
1416
        // DO NOT add classes.
1417
        // DO NOT add an id.
1418
        return '<div class="main-content" role="main">' . $this->unique_main_content_token . '</div>';
1419
    }
1420
 
1421
    /**
1422
     * Outputs a heading
1423
     *
1424
     * @param string $text The text of the heading
1425
     * @param int $level The level of importance of the heading. Defaulting to 2
1426
     * @param string $classes A space-separated list of CSS classes. Defaulting to null
1427
     * @param string $id An optional ID
1428
     * @return string the HTML to output.
1429
     */
161 ariadna 1430
    public function heading($text, $level = 2, $classes = null, $id = null)
1431
    {
1 efrain 1432
        $level = (int) $level;
1433
        if ($level < 1 || $level > 6) {
1434
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1435
        }
1436
        return html_writer::tag('div', html_writer::tag('h' .
1437
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1438
            ' rui-main-content-title rui-main-content-title--h' .
1439
            $level)), array('class' => 'rui-title-container'));
1440
    }
1441
 
1442
 
161 ariadna 1443
    public function headingwithavatar($text, $level = 2, $classes = null, $id = null)
1444
    {
1 efrain 1445
        $level = (int) $level;
1446
        if ($level < 1 || $level > 6) {
1447
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1448
        }
1449
        return html_writer::tag('div', html_writer::tag('h' .
1450
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1451
            ' rui-main-content-title-with-avatar')), array('class' => 'rui-title-container-with-avatar'));
1452
    }
1453
 
1454
    /**
1455
     * Renders the login form.
1456
     *
1457
     * @param \core_auth\output\login $form The renderable.
1458
     * @return string
1459
     */
161 ariadna 1460
    public function render_login(\core_auth\output\login $form)
1461
    {
1 efrain 1462
        global $CFG, $SITE;
1463
 
1464
        $context = $form->export_for_template($this);
1465
 
1466
        // Override because rendering is not supported in template yet.
1467
        if ($CFG->rememberusername == 0) {
1468
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
1469
        } else {
1470
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
1471
        }
1472
        $context->errorformatted = $this->error_text($context->error);
1473
        $url = $this->get_logo_url();
1474
        if ($url) {
1475
            $url = $url->out(false);
1476
        }
1477
        $context->logourl = $url;
1478
        $context->sitename = format_string(
1479
            $SITE->fullname,
1480
            true,
1481
            ['context' => context_course::instance(SITEID), "escape" => false]
1482
        );
1483
 
1484
        if ($this->page->theme->settings->setloginlayout == 1) {
1485
            $context->loginlayout1 = 1;
1486
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1487
            $context->loginlayout2 = 1;
1488
            if (isset($this->page->theme->settings->loginbg)) {
1489
                $context->loginlayoutimg = 1;
1490
            }
1491
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1492
            $context->loginlayout3 = 1;
1493
            if (isset($this->page->theme->settings->loginbg)) {
1494
                $context->loginlayoutimg = 1;
1495
            }
1496
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1497
            $context->loginlayout4 = 1;
1498
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1499
            $context->loginlayout5 = 1;
1500
        }
1501
 
1502
        if (isset($this->page->theme->settings->loginlogooutside)) {
1503
            $context->loginlogooutside = $this->page->theme->settings->loginlogooutside;
1504
        }
1505
 
1506
        if (isset($this->page->theme->settings->customsignupoutside)) {
1507
            $context->customsignupoutside = $this->page->theme->settings->customsignupoutside;
1508
        }
1509
 
1510
        if (isset($this->page->theme->settings->loginidprovtop)) {
1511
            $context->loginidprovtop = $this->page->theme->settings->loginidprovtop;
1512
        }
1513
 
1514
        if (isset($this->page->theme->settings->stringca)) {
1515
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1516
                FORMAT_HTML,
1517
                array('noclean' => true)
1518
            );
1519
        }
1520
 
1521
        if (isset($this->page->theme->settings->stringca)) {
1522
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1523
                FORMAT_HTML,
1524
                array('noclean' => true)
1525
            );
1526
        }
1527
 
1528
        if (isset($this->page->theme->settings->loginhtmlcontent1)) {
1529
            $context->loginhtmlcontent1 = format_text(($this->page->theme->settings->loginhtmlcontent1),
1530
                FORMAT_HTML,
1531
                array('noclean' => true)
1532
            );
1533
        }
1534
 
1535
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1536
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1537
                FORMAT_HTML,
1538
                array('noclean' => true)
1539
            );
1540
        }
1541
 
1542
        if (isset($this->page->theme->settings->loginhtmlcontent3)) {
1543
            $context->loginhtmlcontent3 = format_text(($this->page->theme->settings->loginhtmlcontent3),
1544
                FORMAT_HTML,
1545
                array('noclean' => true)
1546
            );
1547
        }
1548
 
1549
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1550
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1551
                FORMAT_HTML,
1552
                array('noclean' => true)
1553
            );
1554
        }
1555
 
1556
        if (isset($this->page->theme->settings->logincustomfooterhtml)) {
1557
            $context->logincustomfooterhtml = format_text(($this->page->theme->settings->logincustomfooterhtml),
1558
                FORMAT_HTML,
1559
                array('noclean' => true)
1560
            );
1561
        }
1562
 
1563
        if (isset($this->page->theme->settings->loginhtmlblockbottom)) {
1564
            $context->loginhtmlblockbottom = format_text(($this->page->theme->settings->loginhtmlblockbottom),
1565
                FORMAT_HTML,
1566
                array('noclean' => true)
1567
            );
1568
        }
1569
 
1570
        if (isset($this->page->theme->settings->loginfootercontent)) {
1571
            $context->loginfootercontent = format_text(($this->page->theme->settings->loginfootercontent),
1572
                FORMAT_HTML,
1573
                array('noclean' => true)
1574
            );
1575
        }
1576
 
1577
        if (isset($this->page->theme->settings->footercopy)) {
1578
            $context->footercopy = format_text(($this->page->theme->settings->footercopy),
1579
                FORMAT_HTML,
1580
                array('noclean' => true)
1581
            );
1582
        }
1583
 
1584
        if (isset($this->page->theme->settings->loginintrotext)) {
1585
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1586
                FORMAT_HTML,
1587
                array('noclean' => true)
1588
            );
1589
        }
1590
 
1591
        if (isset($this->page->theme->settings->loginintrotext)) {
1592
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1593
                FORMAT_HTML,
1594
                array('noclean' => true)
1595
            );
1596
        }
1597
 
1598
        if (isset($this->page->theme->settings->customloginlogo)) {
1599
            $context->customloginlogo = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1600
        }
1601
 
1602
        if (isset($this->page->theme->settings->loginbg)) {
1603
            $context->loginbg = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1604
        }
1605
 
1606
        if (isset($this->page->theme->settings->hideforgotpassword)) {
1607
            $context->hideforgotpassword = $this->page->theme->settings->hideforgotpassword == 1;
1608
        }
1609
 
1610
        if (isset($this->page->theme->settings->logininfobox)) {
1611
            $context->logininfobox = format_text(($this->page->theme->settings->logininfobox),
1612
                FORMAT_HTML,
1613
                array('noclean' => true)
1614
            );
1615
        }
1616
 
1617
        return $this->render_from_template('core/loginform', $context);
1618
    }
1619
 
1620
    /**
1621
     * Render the login signup form into a nice template for the theme.
1622
     *
1623
     * @param mform $form
1624
     * @return string
1625
     */
161 ariadna 1626
    public function render_login_signup_form($form)
1627
    {
1 efrain 1628
        global $SITE;
1629
 
1630
        $context = $form->export_for_template($this);
1631
        $url = $this->get_logo_url();
1632
        if ($url) {
1633
            $url = $url->out(false);
1634
        }
1635
        $context['logourl'] = $url;
1636
        $context['sitename'] = format_string(
1637
            $SITE->fullname,
1638
            true,
1639
            ['context' => context_course::instance(SITEID), "escape" => false]
1640
        );
1641
 
1642
        if ($this->page->theme->settings->setloginlayout == 1) {
1643
            $context['loginlayout1'] = 1;
1644
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1645
            $context['loginlayout2'] = 1;
1646
            if (isset($this->page->theme->settings->loginbg)) {
1647
                $context['loginlayoutimg'] = 1;
1648
            }
1649
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1650
            $context['loginlayout3'] = 1;
1651
            if (isset($this->page->theme->settings->loginbg)) {
1652
                $context['loginlayoutimg'] = 1;
1653
            }
1654
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1655
            $context['loginlayout4'] = 1;
1656
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1657
            $context['loginlayout5'] = 1;
1658
        }
1659
 
1660
        if (isset($this->page->theme->settings->loginlogooutside)) {
1661
            $context['loginlogooutside'] = $this->page->theme->settings->loginlogooutside;
1662
        }
1663
 
1664
        if (isset($this->page->theme->settings->stringbacktologin)) {
1665
            $context['stringbacktologin'] = format_text(($this->page->theme->settings->stringbacktologin),
1666
                FORMAT_HTML,
1667
                array('noclean' => true)
1668
            );
1669
        }
1670
        if (isset($this->page->theme->settings->signupintrotext)) {
1671
            $context['signupintrotext'] = format_text(($this->page->theme->settings->signupintrotext),
1672
                FORMAT_HTML,
1673
                array('noclean' => true)
1674
            );
1675
        }
1676
        if (isset($this->page->theme->settings->signuptext)) {
1677
            $context['signuptext'] = format_text(($this->page->theme->settings->signuptext),
1678
                FORMAT_HTML,
1679
                array('noclean' => true)
1680
            );
1681
        }
1682
 
1683
        if (!empty($this->page->theme->settings->customloginlogo)) {
1684
            $url = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1685
            $context['customloginlogo'] = $url;
1686
        }
1687
 
1688
        if (!empty($this->page->theme->settings->loginbg)) {
1689
            $url = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1690
            $context['loginbg'] = $url;
1691
        }
1692
 
1693
        if (isset($this->page->theme->settings->loginfootercontent)) {
1694
            $context['loginfootercontent'] = format_text(($this->page->theme->settings->loginfootercontent),
1695
                FORMAT_HTML,
1696
                array('noclean' => true)
1697
            );
1698
        }
1699
 
1700
        return $this->render_from_template('core/signup_form_layout', $context);
1701
    }
1702
 
1703
 
1704
    /**
1705
     * Renders the header bar.
1706
     *
1707
     * @param context_header $contextheader Header bar object.
1708
     * @return string HTML for the header bar.
1709
     */
161 ariadna 1710
    protected function render_context_header(\context_header $contextheader)
1711
    {
1 efrain 1712
        $heading = null;
1713
        $imagedata = null;
1714
        $html = null;
1715
 
1716
        // Generate the heading first and before everything else as we might have to do an early return.
1717
        if (!isset($contextheader->heading)) {
1718
            $heading = $this->heading($this->page->heading, $contextheader->headinglevel);
1719
        } else {
1720
            $heading = $this->heading($contextheader->heading, $contextheader->headinglevel);
1721
        }
1722
 
1723
        // All the html stuff goes here.
1724
        $html = html_writer::start_div('page-context-header d-flex align-items-center flex-wrap');
1725
 
1726
        // Image data.
1727
        if (isset($contextheader->imagedata)) {
1728
            // Header specific image.
1729
            $html .= html_writer::div($contextheader->imagedata, 'page-header-image');
1730
        }
1731
 
1732
        // Headings.
1733
        if (isset($contextheader->prefix)) {
1734
            $prefix = html_writer::div($contextheader->prefix, 'text-muted text-uppercase small line-height-3');
1735
            $heading = $prefix . $heading;
1736
        }
1737
 
1738
        if (!isset($contextheader->heading)) {
1739
            $html .= html_writer::tag('h3', $heading, array('class' => 'rui-page-title rui-page-title--page'));
1740
        } else if (isset($contextheader->imagedata)) {
1741
            $html .= html_writer::tag(
1742
                'div',
1743
                $this->heading($contextheader->heading, 4),
1744
                array('class' => 'rui-page-title rui-page-title--icon')
1745
            );
1746
        } else {
1747
            $html .= html_writer::tag('h2', $heading, array('class' => 'page-header-headings
1748
                rui-page-title rui-page-title--context'));
1749
        }
1750
 
1751
        // Buttons.
1752
        if (isset($contextheader->additionalbuttons)) {
1753
            $html .= html_writer::start_div('btn-group header-button-group my-2 my-lg-0 ml-lg-4');
1754
            foreach ($contextheader->additionalbuttons as $button) {
1755
                if (!isset($button->page)) {
1756
                    // Include js for messaging.
1757
                    if ($button['buttontype'] === 'togglecontact') {
1758
                        \core_message\helper::togglecontact_requirejs();
1759
                    }
1760
                    if ($button['buttontype'] === 'message') {
1761
                        \core_message\helper::messageuser_requirejs();
1762
                    }
1763
                    $image = $this->pix_icon($button['formattedimage'], $button['title'], 'moodle', array(
1764
                        'class' => 'iconsmall',
1765
                        'role' => 'presentation'
1766
                    ));
1767
                    $image .= html_writer::span($button['title'], 'header-button-title');
1768
                } else {
1769
                    $image = html_writer::empty_tag('img', array(
1770
                        'src' => $button['formattedimage'],
1771
                        'role' => 'presentation'
1772
                    ));
1773
                }
1774
                $html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
1775
            }
1776
            $html .= html_writer::end_div();
1777
        }
1778
        $html .= html_writer::end_div();
1779
 
1780
        return $html;
1781
    }
1782
 
161 ariadna 1783
    public function header()
1784
    {
1 efrain 1785
        global $USER, $COURSE;
1786
        $theme = theme_config::load('universe');
1787
 
1788
        $context = context_course::instance($COURSE->id);
1789
        $roles = get_user_roles($context, $USER->id, true);
1790
 
1791
        if (is_array($roles) && !empty($roles)) {
1792
            foreach ($roles as $role) {
1793
                $this->page->add_body_class('role-' . $role->shortname);
1794
            }
1795
        } else {
1796
            $this->page->add_body_class('role-none');
1797
        }
1798
 
1799
        if ($theme->settings->topbareditmode == '1') {
1800
            $this->page->add_body_class('rui-editmode--top');
1801
        } else {
1802
            $this->page->add_body_class('rui-editmode--footer');
1803
        }
1804
 
1805
        return parent::header();
1806
    }
1807
 
1808
 
1809
    /**
1810
     * See if this is the first view of the current cm in the session if it has fake blocks.
1811
     *
1812
     * (We track up to 100 cms so as not to overflow the session.)
1813
     * This is done for drawer regions containing fake blocks so we can show blocks automatically.
1814
     *
1815
     * @return boolean true if the page has fakeblocks and this is the first visit.
1816
     */
161 ariadna 1817
    public function firstview_fakeblocks(): bool
1818
    {
1 efrain 1819
        global $SESSION;
1820
 
1821
        $firstview = false;
1822
        if ($this->page->cm) {
1823
            if (!$this->page->blocks->region_has_fakeblocks('side-pre')) {
1824
                return false;
1825
            }
1826
            if (!property_exists($SESSION, 'firstview_fakeblocks')) {
1827
                $SESSION->firstview_fakeblocks = [];
1828
            }
1829
            if (array_key_exists($this->page->cm->id, $SESSION->firstview_fakeblocks)) {
1830
                $firstview = false;
1831
            } else {
1832
                $SESSION->firstview_fakeblocks[$this->page->cm->id] = true;
1833
                $firstview = true;
1834
                if (count($SESSION->firstview_fakeblocks) > 100) {
1835
                    array_shift($SESSION->firstview_fakeblocks);
1836
                }
1837
            }
1838
        }
1839
        return $firstview;
1840
    }
1841
 
1842
 
1843
    /**
1844
     * Build the guest access hint HTML code.
1845
     *
1846
     * @param int $courseid The course ID.
1847
     * @return string.
1848
     */
161 ariadna 1849
    public function theme_universe_get_course_guest_access_hint($courseid)
1850
    {
1 efrain 1851
        global $CFG;
1852
        require_once($CFG->dirroot . '/enrol/self/lib.php');
1853
 
1854
        $html = '';
1855
        $instances = enrol_get_instances($courseid, true);
1856
        $plugins = enrol_get_plugins(true);
1857
        foreach ($instances as $instance) {
1858
            if (!isset($plugins[$instance->enrol])) {
1859
                continue;
1860
            }
1861
            $plugin = $plugins[$instance->enrol];
1862
            if ($plugin->show_enrolme_link($instance)) {
1863
                $html = html_writer::tag('div', get_string(
1864
                    'showhintcourseguestaccesssettinglink',
1865
                    'theme_universe',
1866
                    array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
1867
                ));
1868
                break;
1869
            }
1870
        }
1871
 
1872
        return $html;
1873
    }
1874
 
1875
 
1876
    /**
1877
     * Color Customization
1878
     * @return string HTML fragment.
1879
     */
161 ariadna 1880
    public function additional_head_html()
1881
    {
1 efrain 1882
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1883
 
1884
        $output = null;
1885
 
1886
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1887
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1888
                // Get custom field by name
1889
                $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1890
                // Get value
1891
                $mainthemecolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id));
1892
            } else {
1893
                $mainthemecolor = null;
1894
            }
1895
 
1896
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1897
                $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1898
                $mainthemecolor2 = $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id));
1899
            }
1900
 
1901
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1902
                // Get custom field by name
1903
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1904
                // Get value
1905
                $topbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1906
            }
1907
 
1908
            if ($DB->record_exists('customfield_field', array('shortname' => 'dmtopbarcolor'), 'id')) {
1909
                // Get custom field by name
1910
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1911
                // Get value
1912
                $dmtopbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1913
            } else {
1914
                $dmtopbarcolor = null;
1915
            }
1916
 
1917
 
1918
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1919
                // Get custom field by name
1920
                $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1921
                // Get value
1922
                $footercolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id));
1923
            } else {
1924
                $footercolor = null;
1925
            }
1926
 
1927
 
1928
            $css = '';
1929
 
1930
            $css .= ':root { ';
1931
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1932
                if ($mainthemecolor != null) {
1933
                    $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1934
                    $css .= '--primary-color-100: ' . $mainthemecolor->value . '30; ';
1935
                    $css .= '--primary-color-300: ' . $mainthemecolor->value . '70; ';
1936
                    $css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1937
                    $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1938
                    $css .= '--btn-primary-color-bg-hover: ' . $mainthemecolor->value . '95; ';
1939
 
1940
                    if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1941
                        if ($mainthemecolor2 != null) {
1942
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor2->value . '; ';
1943
                        } else {
1944
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor->value . '30; ';
1945
                        }
1946
                    }
1947
                }
1948
            }
1949
 
1950
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1951
                if ($topbarcolor != null) {
1952
                    $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1953
                    if ($dmtopbarcolor != null) {
1954
                        $css .= '--dm-topbar-color: ' . $dmtopbarcolor->value . '; ';
1955
                    } else {
1956
                        $css .= '--dm-topbar-color: ' . $topbarcolor->value . '; ';
1957
                    }
1958
                }
1959
            }
1960
 
1961
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1962
                if ($footercolor != null) {
1963
                    $css .= '--footer-color: ' . $footercolor->value . '; ';
1964
                }
1965
            }
1966
 
1967
            $css .= '}';
1968
 
1969
            if ($css) {
1970
                $output .= '<style>' . $css . '</style>';
1971
            }
1972
        }
1973
 
1974
        return $output;
1975
    }
1976
 
161 ariadna 1977
    public function custom_course_logo()
1978
    {
1 efrain 1979
        global $DB, $CFG, $COURSE, $PAGE;
1980
 
1981
        $output = null;
1982
 
1983
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1984
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1985
                // Get custom field ID
1986
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1987
                $customfieldpicid = $customfieldpic->id;
1988
                // Get value
1989
                $customlogo = $DB->get_record(
1990
                    'customfield_data',
1991
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1992
                );
1993
 
1994
                $customlogoid = $customlogo->id;
1995
                $contextid = $customlogo->contextid;
1996
 
1997
                if ($customfieldpic != null) {
1998
                    $files = get_file_storage()->get_area_files(
1999
                        $contextid,
2000
                        'customfield_picture',
2001
                        'file',
2002
                        $customlogoid,
2003
                        '',
2004
                        false
2005
                    );
2006
 
2007
                    if (empty($files)) {
2008
                        return null;
2009
                    }
2010
 
2011
                    $file = reset($files);
2012
                    $fileurl = moodle_url::make_pluginfile_url(
2013
                        $file->get_contextid(),
2014
                        $file->get_component(),
2015
                        $file->get_filearea(),
2016
                        $file->get_itemid(),
2017
                        $file->get_filepath(),
2018
                        $file->get_filename()
2019
                    );
2020
 
2021
                    $output .= $fileurl;
2022
                }
2023
            }
2024
        }
2025
 
2026
        return $output;
2027
    }
2028
 
161 ariadna 2029
    public function custom_course_dmlogo()
2030
    {
1 efrain 2031
        global $DB, $CFG, $COURSE, $PAGE;
2032
 
2033
        $output = null;
2034
 
2035
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2036
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
2037
                // Get custom field ID
2038
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
2039
                $customfieldpicid = $customfieldpic->id;
2040
                // Get value
2041
                $customlogo = $DB->get_record(
2042
                    'customfield_data',
2043
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2044
                );
2045
 
2046
                $customlogoid = $customlogo->id;
2047
                $contextid = $customlogo->contextid;
2048
 
2049
                if ($customfieldpic != null) {
2050
                    $files = get_file_storage()->get_area_files(
2051
                        $contextid,
2052
                        'customfield_picture',
2053
                        'file',
2054
                        $customlogoid,
2055
                        '',
2056
                        false
2057
                    );
2058
 
2059
                    if (empty($files)) {
2060
                        return null;
2061
                    }
2062
 
2063
                    $file = reset($files);
2064
                    $fileurl = moodle_url::make_pluginfile_url(
2065
                        $file->get_contextid(),
2066
                        $file->get_component(),
2067
                        $file->get_filearea(),
2068
                        $file->get_itemid(),
2069
                        $file->get_filepath(),
2070
                        $file->get_filename()
2071
                    );
2072
 
2073
                    $output .= $fileurl;
2074
                }
2075
            }
2076
        }
2077
 
2078
        return $output;
2079
    }
2080
 
161 ariadna 2081
    public function custom_course_favicon()
2082
    {
1 efrain 2083
        global $DB, $CFG, $COURSE, $PAGE;
2084
 
2085
        $output = null;
2086
 
2087
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2088
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2089
                // Get custom field ID
2090
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2091
                $customfieldpicid = $customfieldpic->id;
2092
                // Get value
2093
                $customfavicon = $DB->get_record(
2094
                    'customfield_data',
2095
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2096
                );
2097
 
2098
                $customfaviconid = $customfavicon->id;
2099
                $contextid = $customfavicon->contextid;
2100
 
2101
                if ($customfieldpic != null) {
2102
                    $files = get_file_storage()->get_area_files(
2103
                        $contextid,
2104
                        'customfield_picture',
2105
                        'file',
2106
                        $customfaviconid,
2107
                        '',
2108
                        false
2109
                    );
2110
 
2111
                    if (empty($files)) {
2112
                        return null;
2113
                    }
2114
 
2115
                    $file = reset($files);
2116
                    $fileurl = moodle_url::make_pluginfile_url(
2117
                        $file->get_contextid(),
2118
                        $file->get_component(),
2119
                        $file->get_filearea(),
2120
                        $file->get_itemid(),
2121
                        $file->get_filepath(),
2122
                        $file->get_filename()
2123
                    );
2124
 
2125
                    $output .= $fileurl;
2126
                }
2127
            }
2128
        }
2129
 
2130
        return $output;
2131
    }
2132
 
161 ariadna 2133
    public function custom_course_name()
2134
    {
1 efrain 2135
        global $DB, $CFG, $COURSE, $PAGE;
2136
 
2137
        $output = null;
2138
 
2139
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2140
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2141
                // Get custom field by name
2142
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2143
                // Get value
2144
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2145
                if (!empty($customcoursename)) {
2146
                    $output .= $customcoursename->value;
2147
                }
2148
            } else {
2149
                $customcoursename = null;
2150
            }
2151
        }
2152
 
2153
        return $output;
2154
    }
2155
 
161 ariadna 2156
    /**
1 efrain 2157
     * Get the course pattern datauri to show on a course card.
2158
     *
2159
     * The datauri is an encoded svg that can be passed as a url.
2160
     * @param int $id Id to use when generating the pattern
2161
     * @return string datauri
2162
     */
161 ariadna 2163
    public function get_generated_image_for_id($id)
2164
    {
1 efrain 2165
        global $CFG;
2166
 
2167
        $theme = \theme_config::load('universe');
2168
        // Add custom course cover.
2169
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2170
 
2171
        if (!empty(($customcover))) {
2172
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2173
            $customcover = str_replace($urlreplace, '', $customcover);
2174
            $txt = new moodle_url($customcover);
2175
            return strval($txt);
2176
        } else {
2177
            $color = $this->get_generated_color_for_id($id);
2178
            $pattern = new \core_geopattern();
2179
            $pattern->setColor($color);
2180
            $pattern->patternbyid($id);
2181
            return $pattern->datauri();
2182
        }
2183
    }
161 ariadna 2184
 
2185
    public function moremenu_group_item()
2186
    {
1 efrain 2187
        global $CFG, $COURSE;
2188
 
2189
        $theme = \theme_config::load('universe');
2190
        $courseid = $COURSE->id;
2191
        $sitehomeurl = new moodle_url('/');
2192
 
2193
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2194
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2195
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2196
                return $html;
2197
            }
2198
        }
2199
    }
2200
 
161 ariadna 2201
    public function moremenu_custom_items()
2202
    {
1 efrain 2203
        global $CFG, $COURSE, $USER;
2204
 
2205
        $theme = \theme_config::load('universe');
2206
        $html = '';
2207
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2208
 
2209
        // Get current user role ID.
2210
        $context = context_course::instance($COURSE->id);
2211
        $roles = get_user_roles($context, $USER->id, true);
2212
        $role = 999;
2213
        $roleid = 999;
2214
        $role = key($roles);
2215
        if ($role != null) {
2216
            $roleid = $roles[$role]->roleid;
2217
        }
2218
 
2219
        // End.
2220
 
2221
        if ($this->page->theme->settings->secnavitems == 1) {
2222
 
2223
            $secnav = new stdClass();
2224
            for ($i = 1; $i <= $secnavcount; $i++) {
2225
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2226
 
2227
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2228
                $courseid = $COURSE->id;
2229
                $newurl = str_replace("{{courseID}}", $courseid, $url);
161 ariadna 2230
 
1 efrain 2231
                // User role restriction.
2232
                $selectrole = theme_universe_get_setting("secnavuserroles" . $i);
161 ariadna 2233
 
2234
                if ($roleid == $selectrole) {
1 efrain 2235
                    $secnav->url = $newurl;
2236
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
161 ariadna 2237
                }
2238
                if ($roleid != $selectrole) {
1 efrain 2239
                    $secnav->url = $newurl;
2240
                }
161 ariadna 2241
                if ($selectrole == 0) {
1 efrain 2242
                    $secnav->url = $newurl;
2243
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
161 ariadna 2244
                }
1 efrain 2245
                // End.
2246
 
2247
            }
2248
        }
2249
        return $html;
2250
    }
2251
}