Proyectos de Subversion Moodle

Rev

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