Proyectos de Subversion Moodle

Rev

Rev 1312 | | 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
    {
1317 ariadna 1372
        $this->page->set_state(moodle_page::STATE_IN_BODY);
1373
        return $this->render_from_template('core/local/content', []);
1 efrain 1374
    }
1375
 
1376
    /**
1377
     * Outputs a heading
1378
     *
1379
     * @param string $text The text of the heading
1380
     * @param int $level The level of importance of the heading. Defaulting to 2
1381
     * @param string $classes A space-separated list of CSS classes. Defaulting to null
1382
     * @param string $id An optional ID
1383
     * @return string the HTML to output.
1384
     */
161 ariadna 1385
    public function heading($text, $level = 2, $classes = null, $id = null)
1386
    {
1 efrain 1387
        $level = (int) $level;
1388
        if ($level < 1 || $level > 6) {
1389
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1390
        }
1391
        return html_writer::tag('div', html_writer::tag('h' .
1392
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1393
            ' rui-main-content-title rui-main-content-title--h' .
1394
            $level)), array('class' => 'rui-title-container'));
1395
    }
1396
 
1397
 
161 ariadna 1398
    public function headingwithavatar($text, $level = 2, $classes = null, $id = null)
1399
    {
1 efrain 1400
        $level = (int) $level;
1401
        if ($level < 1 || $level > 6) {
1402
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1403
        }
1404
        return html_writer::tag('div', html_writer::tag('h' .
1405
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1406
            ' rui-main-content-title-with-avatar')), array('class' => 'rui-title-container-with-avatar'));
1407
    }
1408
 
1409
    /**
1410
     * Renders the login form.
1411
     *
1412
     * @param \core_auth\output\login $form The renderable.
1413
     * @return string
1414
     */
161 ariadna 1415
    public function render_login(\core_auth\output\login $form)
1416
    {
1 efrain 1417
        global $CFG, $SITE;
1418
 
1419
        $context = $form->export_for_template($this);
1420
 
1421
        // Override because rendering is not supported in template yet.
1422
        if ($CFG->rememberusername == 0) {
1423
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
1424
        } else {
1425
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
1426
        }
1427
        $context->errorformatted = $this->error_text($context->error);
1428
        $url = $this->get_logo_url();
1429
        if ($url) {
1430
            $url = $url->out(false);
1431
        }
1432
        $context->logourl = $url;
1433
        $context->sitename = format_string(
1434
            $SITE->fullname,
1435
            true,
1436
            ['context' => context_course::instance(SITEID), "escape" => false]
1437
        );
1438
 
1439
        if ($this->page->theme->settings->setloginlayout == 1) {
1440
            $context->loginlayout1 = 1;
1441
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1442
            $context->loginlayout2 = 1;
1443
            if (isset($this->page->theme->settings->loginbg)) {
1444
                $context->loginlayoutimg = 1;
1445
            }
1446
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1447
            $context->loginlayout3 = 1;
1448
            if (isset($this->page->theme->settings->loginbg)) {
1449
                $context->loginlayoutimg = 1;
1450
            }
1451
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1452
            $context->loginlayout4 = 1;
1453
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1454
            $context->loginlayout5 = 1;
1455
        }
1456
 
1457
        if (isset($this->page->theme->settings->loginlogooutside)) {
1458
            $context->loginlogooutside = $this->page->theme->settings->loginlogooutside;
1459
        }
1460
 
1461
        if (isset($this->page->theme->settings->customsignupoutside)) {
1462
            $context->customsignupoutside = $this->page->theme->settings->customsignupoutside;
1463
        }
1464
 
1465
        if (isset($this->page->theme->settings->loginidprovtop)) {
1466
            $context->loginidprovtop = $this->page->theme->settings->loginidprovtop;
1467
        }
1468
 
1469
        if (isset($this->page->theme->settings->stringca)) {
1470
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1471
                FORMAT_HTML,
1472
                array('noclean' => true)
1473
            );
1474
        }
1475
 
1476
        if (isset($this->page->theme->settings->stringca)) {
1477
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1478
                FORMAT_HTML,
1479
                array('noclean' => true)
1480
            );
1481
        }
1482
 
1483
        if (isset($this->page->theme->settings->loginhtmlcontent1)) {
1484
            $context->loginhtmlcontent1 = format_text(($this->page->theme->settings->loginhtmlcontent1),
1485
                FORMAT_HTML,
1486
                array('noclean' => true)
1487
            );
1488
        }
1489
 
1490
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1491
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1492
                FORMAT_HTML,
1493
                array('noclean' => true)
1494
            );
1495
        }
1496
 
1497
        if (isset($this->page->theme->settings->loginhtmlcontent3)) {
1498
            $context->loginhtmlcontent3 = format_text(($this->page->theme->settings->loginhtmlcontent3),
1499
                FORMAT_HTML,
1500
                array('noclean' => true)
1501
            );
1502
        }
1503
 
1504
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1505
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1506
                FORMAT_HTML,
1507
                array('noclean' => true)
1508
            );
1509
        }
1510
 
1511
        if (isset($this->page->theme->settings->logincustomfooterhtml)) {
1512
            $context->logincustomfooterhtml = format_text(($this->page->theme->settings->logincustomfooterhtml),
1513
                FORMAT_HTML,
1514
                array('noclean' => true)
1515
            );
1516
        }
1517
 
1518
        if (isset($this->page->theme->settings->loginhtmlblockbottom)) {
1519
            $context->loginhtmlblockbottom = format_text(($this->page->theme->settings->loginhtmlblockbottom),
1520
                FORMAT_HTML,
1521
                array('noclean' => true)
1522
            );
1523
        }
1524
 
1525
        if (isset($this->page->theme->settings->loginfootercontent)) {
1526
            $context->loginfootercontent = format_text(($this->page->theme->settings->loginfootercontent),
1527
                FORMAT_HTML,
1528
                array('noclean' => true)
1529
            );
1530
        }
1531
 
1532
        if (isset($this->page->theme->settings->footercopy)) {
1533
            $context->footercopy = format_text(($this->page->theme->settings->footercopy),
1534
                FORMAT_HTML,
1535
                array('noclean' => true)
1536
            );
1537
        }
1538
 
1539
        if (isset($this->page->theme->settings->loginintrotext)) {
1540
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1541
                FORMAT_HTML,
1542
                array('noclean' => true)
1543
            );
1544
        }
1545
 
1546
        if (isset($this->page->theme->settings->loginintrotext)) {
1547
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1548
                FORMAT_HTML,
1549
                array('noclean' => true)
1550
            );
1551
        }
1552
 
1553
        if (isset($this->page->theme->settings->customloginlogo)) {
1554
            $context->customloginlogo = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1555
        }
1556
 
1557
        if (isset($this->page->theme->settings->loginbg)) {
1558
            $context->loginbg = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1559
        }
1560
 
1561
        if (isset($this->page->theme->settings->hideforgotpassword)) {
1562
            $context->hideforgotpassword = $this->page->theme->settings->hideforgotpassword == 1;
1563
        }
1564
 
1565
        if (isset($this->page->theme->settings->logininfobox)) {
1566
            $context->logininfobox = format_text(($this->page->theme->settings->logininfobox),
1567
                FORMAT_HTML,
1568
                array('noclean' => true)
1569
            );
1570
        }
1571
 
1572
        return $this->render_from_template('core/loginform', $context);
1573
    }
1574
 
1575
    /**
1576
     * Render the login signup form into a nice template for the theme.
1577
     *
1578
     * @param mform $form
1579
     * @return string
1580
     */
161 ariadna 1581
    public function render_login_signup_form($form)
1582
    {
1 efrain 1583
        global $SITE;
1584
 
1585
        $context = $form->export_for_template($this);
1586
        $url = $this->get_logo_url();
1587
        if ($url) {
1588
            $url = $url->out(false);
1589
        }
1590
        $context['logourl'] = $url;
1591
        $context['sitename'] = format_string(
1592
            $SITE->fullname,
1593
            true,
1594
            ['context' => context_course::instance(SITEID), "escape" => false]
1595
        );
1596
 
1597
        if ($this->page->theme->settings->setloginlayout == 1) {
1598
            $context['loginlayout1'] = 1;
1599
        } else if ($this->page->theme->settings->setloginlayout == 2) {
1600
            $context['loginlayout2'] = 1;
1601
            if (isset($this->page->theme->settings->loginbg)) {
1602
                $context['loginlayoutimg'] = 1;
1603
            }
1604
        } else if ($this->page->theme->settings->setloginlayout == 3) {
1605
            $context['loginlayout3'] = 1;
1606
            if (isset($this->page->theme->settings->loginbg)) {
1607
                $context['loginlayoutimg'] = 1;
1608
            }
1609
        } else if ($this->page->theme->settings->setloginlayout == 4) {
1610
            $context['loginlayout4'] = 1;
1611
        } else if ($this->page->theme->settings->setloginlayout == 5) {
1612
            $context['loginlayout5'] = 1;
1613
        }
1614
 
1615
        if (isset($this->page->theme->settings->loginlogooutside)) {
1616
            $context['loginlogooutside'] = $this->page->theme->settings->loginlogooutside;
1617
        }
1618
 
1619
        if (isset($this->page->theme->settings->stringbacktologin)) {
1620
            $context['stringbacktologin'] = format_text(($this->page->theme->settings->stringbacktologin),
1621
                FORMAT_HTML,
1622
                array('noclean' => true)
1623
            );
1624
        }
1625
        if (isset($this->page->theme->settings->signupintrotext)) {
1626
            $context['signupintrotext'] = format_text(($this->page->theme->settings->signupintrotext),
1627
                FORMAT_HTML,
1628
                array('noclean' => true)
1629
            );
1630
        }
1631
        if (isset($this->page->theme->settings->signuptext)) {
1632
            $context['signuptext'] = format_text(($this->page->theme->settings->signuptext),
1633
                FORMAT_HTML,
1634
                array('noclean' => true)
1635
            );
1636
        }
1637
 
1638
        if (!empty($this->page->theme->settings->customloginlogo)) {
1639
            $url = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1640
            $context['customloginlogo'] = $url;
1641
        }
1642
 
1643
        if (!empty($this->page->theme->settings->loginbg)) {
1644
            $url = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1645
            $context['loginbg'] = $url;
1646
        }
1647
 
1648
        if (isset($this->page->theme->settings->loginfootercontent)) {
1649
            $context['loginfootercontent'] = format_text(($this->page->theme->settings->loginfootercontent),
1650
                FORMAT_HTML,
1651
                array('noclean' => true)
1652
            );
1653
        }
1654
 
1655
        return $this->render_from_template('core/signup_form_layout', $context);
1656
    }
1657
 
1658
 
1659
    /**
1660
     * Renders the header bar.
1661
     *
1662
     * @param context_header $contextheader Header bar object.
1663
     * @return string HTML for the header bar.
1664
     */
161 ariadna 1665
    protected function render_context_header(\context_header $contextheader)
1666
    {
1 efrain 1667
        $heading = null;
1668
        $imagedata = null;
1669
        $html = null;
1670
 
1671
        // Generate the heading first and before everything else as we might have to do an early return.
1672
        if (!isset($contextheader->heading)) {
1673
            $heading = $this->heading($this->page->heading, $contextheader->headinglevel);
1674
        } else {
1675
            $heading = $this->heading($contextheader->heading, $contextheader->headinglevel);
1676
        }
1677
 
1678
        // All the html stuff goes here.
1679
        $html = html_writer::start_div('page-context-header d-flex align-items-center flex-wrap');
1680
 
1681
        // Image data.
1682
        if (isset($contextheader->imagedata)) {
1683
            // Header specific image.
1684
            $html .= html_writer::div($contextheader->imagedata, 'page-header-image');
1685
        }
1686
 
1687
        // Headings.
1688
        if (isset($contextheader->prefix)) {
1689
            $prefix = html_writer::div($contextheader->prefix, 'text-muted text-uppercase small line-height-3');
1690
            $heading = $prefix . $heading;
1691
        }
1692
 
1693
        if (!isset($contextheader->heading)) {
1694
            $html .= html_writer::tag('h3', $heading, array('class' => 'rui-page-title rui-page-title--page'));
1695
        } else if (isset($contextheader->imagedata)) {
1696
            $html .= html_writer::tag(
1697
                'div',
1698
                $this->heading($contextheader->heading, 4),
1699
                array('class' => 'rui-page-title rui-page-title--icon')
1700
            );
1701
        } else {
1702
            $html .= html_writer::tag('h2', $heading, array('class' => 'page-header-headings
1703
                rui-page-title rui-page-title--context'));
1704
        }
1705
 
1706
        // Buttons.
1707
        if (isset($contextheader->additionalbuttons)) {
1708
            $html .= html_writer::start_div('btn-group header-button-group my-2 my-lg-0 ml-lg-4');
1709
            foreach ($contextheader->additionalbuttons as $button) {
1710
                if (!isset($button->page)) {
1711
                    // Include js for messaging.
1712
                    if ($button['buttontype'] === 'togglecontact') {
1713
                        \core_message\helper::togglecontact_requirejs();
1714
                    }
1715
                    if ($button['buttontype'] === 'message') {
1716
                        \core_message\helper::messageuser_requirejs();
1717
                    }
1718
                    $image = $this->pix_icon($button['formattedimage'], $button['title'], 'moodle', array(
1719
                        'class' => 'iconsmall',
1720
                        'role' => 'presentation'
1721
                    ));
1722
                    $image .= html_writer::span($button['title'], 'header-button-title');
1723
                } else {
1724
                    $image = html_writer::empty_tag('img', array(
1725
                        'src' => $button['formattedimage'],
1726
                        'role' => 'presentation'
1727
                    ));
1728
                }
1729
                $html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
1730
            }
1731
            $html .= html_writer::end_div();
1732
        }
1733
        $html .= html_writer::end_div();
1734
 
1735
        return $html;
1736
    }
1737
 
161 ariadna 1738
    public function header()
1739
    {
1 efrain 1740
        global $USER, $COURSE;
1741
        $theme = theme_config::load('universe');
1742
 
1743
        $context = context_course::instance($COURSE->id);
1744
        $roles = get_user_roles($context, $USER->id, true);
1745
 
1746
        if (is_array($roles) && !empty($roles)) {
1747
            foreach ($roles as $role) {
1748
                $this->page->add_body_class('role-' . $role->shortname);
1749
            }
1750
        } else {
1751
            $this->page->add_body_class('role-none');
1752
        }
1753
 
1754
        if ($theme->settings->topbareditmode == '1') {
1755
            $this->page->add_body_class('rui-editmode--top');
1756
        } else {
1757
            $this->page->add_body_class('rui-editmode--footer');
1758
        }
1759
 
1760
        return parent::header();
1761
    }
1762
 
1763
 
1764
    /**
1765
     * See if this is the first view of the current cm in the session if it has fake blocks.
1766
     *
1767
     * (We track up to 100 cms so as not to overflow the session.)
1768
     * This is done for drawer regions containing fake blocks so we can show blocks automatically.
1769
     *
1770
     * @return boolean true if the page has fakeblocks and this is the first visit.
1771
     */
161 ariadna 1772
    public function firstview_fakeblocks(): bool
1773
    {
1 efrain 1774
        global $SESSION;
1775
 
1776
        $firstview = false;
1777
        if ($this->page->cm) {
1778
            if (!$this->page->blocks->region_has_fakeblocks('side-pre')) {
1779
                return false;
1780
            }
1781
            if (!property_exists($SESSION, 'firstview_fakeblocks')) {
1782
                $SESSION->firstview_fakeblocks = [];
1783
            }
1784
            if (array_key_exists($this->page->cm->id, $SESSION->firstview_fakeblocks)) {
1785
                $firstview = false;
1786
            } else {
1787
                $SESSION->firstview_fakeblocks[$this->page->cm->id] = true;
1788
                $firstview = true;
1789
                if (count($SESSION->firstview_fakeblocks) > 100) {
1790
                    array_shift($SESSION->firstview_fakeblocks);
1791
                }
1792
            }
1793
        }
1794
        return $firstview;
1795
    }
1796
 
1797
 
1798
    /**
1799
     * Build the guest access hint HTML code.
1800
     *
1801
     * @param int $courseid The course ID.
1802
     * @return string.
1803
     */
161 ariadna 1804
    public function theme_universe_get_course_guest_access_hint($courseid)
1805
    {
1 efrain 1806
        global $CFG;
1807
        require_once($CFG->dirroot . '/enrol/self/lib.php');
1808
 
1809
        $html = '';
1810
        $instances = enrol_get_instances($courseid, true);
1811
        $plugins = enrol_get_plugins(true);
1812
        foreach ($instances as $instance) {
1813
            if (!isset($plugins[$instance->enrol])) {
1814
                continue;
1815
            }
1816
            $plugin = $plugins[$instance->enrol];
1817
            if ($plugin->show_enrolme_link($instance)) {
1818
                $html = html_writer::tag('div', get_string(
1819
                    'showhintcourseguestaccesssettinglink',
1820
                    'theme_universe',
1821
                    array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
1822
                ));
1823
                break;
1824
            }
1825
        }
1826
 
1827
        return $html;
1828
    }
1829
 
1830
 
1831
    /**
1832
     * Color Customization
1833
     * @return string HTML fragment.
1834
     */
161 ariadna 1835
    public function additional_head_html()
1836
    {
1 efrain 1837
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1838
 
1839
        $output = null;
1840
 
1841
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1842
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1843
                // Get custom field by name
1844
                $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1845
                // Get value
1846
                $mainthemecolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id));
1847
            } else {
1848
                $mainthemecolor = null;
1849
            }
1850
 
1851
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1852
                $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1853
                $mainthemecolor2 = $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id));
1854
            }
1855
 
1856
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1857
                // Get custom field by name
1858
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1859
                // Get value
1860
                $topbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1861
            }
1862
 
1863
            if ($DB->record_exists('customfield_field', array('shortname' => 'dmtopbarcolor'), 'id')) {
1864
                // Get custom field by name
1865
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1866
                // Get value
1867
                $dmtopbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1868
            } else {
1869
                $dmtopbarcolor = null;
1870
            }
1871
 
1872
 
1873
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1874
                // Get custom field by name
1875
                $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1876
                // Get value
1877
                $footercolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id));
1878
            } else {
1879
                $footercolor = null;
1880
            }
1881
 
1882
 
1883
            $css = '';
1884
 
1885
            $css .= ':root { ';
1886
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1887
                if ($mainthemecolor != null) {
1888
                    $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1889
                    $css .= '--primary-color-100: ' . $mainthemecolor->value . '30; ';
1890
                    $css .= '--primary-color-300: ' . $mainthemecolor->value . '70; ';
1891
                    $css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1892
                    $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1893
                    $css .= '--btn-primary-color-bg-hover: ' . $mainthemecolor->value . '95; ';
1894
 
1895
                    if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1896
                        if ($mainthemecolor2 != null) {
1897
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor2->value . '; ';
1898
                        } else {
1899
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor->value . '30; ';
1900
                        }
1901
                    }
1902
                }
1903
            }
1904
 
1905
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1906
                if ($topbarcolor != null) {
1907
                    $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1908
                    if ($dmtopbarcolor != null) {
1909
                        $css .= '--dm-topbar-color: ' . $dmtopbarcolor->value . '; ';
1910
                    } else {
1911
                        $css .= '--dm-topbar-color: ' . $topbarcolor->value . '; ';
1912
                    }
1913
                }
1914
            }
1915
 
1916
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1917
                if ($footercolor != null) {
1918
                    $css .= '--footer-color: ' . $footercolor->value . '; ';
1919
                }
1920
            }
1921
 
1922
            $css .= '}';
1923
 
1924
            if ($css) {
1925
                $output .= '<style>' . $css . '</style>';
1926
            }
1927
        }
1928
 
1929
        return $output;
1930
    }
1931
 
161 ariadna 1932
    public function custom_course_logo()
1933
    {
1 efrain 1934
        global $DB, $CFG, $COURSE, $PAGE;
1935
 
1936
        $output = null;
1937
 
1938
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1939
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1940
                // Get custom field ID
1941
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1942
                $customfieldpicid = $customfieldpic->id;
1943
                // Get value
1944
                $customlogo = $DB->get_record(
1945
                    'customfield_data',
1946
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1947
                );
1948
 
1949
                $customlogoid = $customlogo->id;
1950
                $contextid = $customlogo->contextid;
1951
 
1952
                if ($customfieldpic != null) {
1953
                    $files = get_file_storage()->get_area_files(
1954
                        $contextid,
1955
                        'customfield_picture',
1956
                        'file',
1957
                        $customlogoid,
1958
                        '',
1959
                        false
1960
                    );
1961
 
1962
                    if (empty($files)) {
1963
                        return null;
1964
                    }
1965
 
1966
                    $file = reset($files);
1967
                    $fileurl = moodle_url::make_pluginfile_url(
1968
                        $file->get_contextid(),
1969
                        $file->get_component(),
1970
                        $file->get_filearea(),
1971
                        $file->get_itemid(),
1972
                        $file->get_filepath(),
1973
                        $file->get_filename()
1974
                    );
1975
 
1976
                    $output .= $fileurl;
1977
                }
1978
            }
1979
        }
1980
 
1981
        return $output;
1982
    }
1983
 
161 ariadna 1984
    public function custom_course_dmlogo()
1985
    {
1 efrain 1986
        global $DB, $CFG, $COURSE, $PAGE;
1987
 
1988
        $output = null;
1989
 
1990
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1991
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
1992
                // Get custom field ID
1993
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
1994
                $customfieldpicid = $customfieldpic->id;
1995
                // Get value
1996
                $customlogo = $DB->get_record(
1997
                    'customfield_data',
1998
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1999
                );
2000
 
2001
                $customlogoid = $customlogo->id;
2002
                $contextid = $customlogo->contextid;
2003
 
2004
                if ($customfieldpic != null) {
2005
                    $files = get_file_storage()->get_area_files(
2006
                        $contextid,
2007
                        'customfield_picture',
2008
                        'file',
2009
                        $customlogoid,
2010
                        '',
2011
                        false
2012
                    );
2013
 
2014
                    if (empty($files)) {
2015
                        return null;
2016
                    }
2017
 
2018
                    $file = reset($files);
2019
                    $fileurl = moodle_url::make_pluginfile_url(
2020
                        $file->get_contextid(),
2021
                        $file->get_component(),
2022
                        $file->get_filearea(),
2023
                        $file->get_itemid(),
2024
                        $file->get_filepath(),
2025
                        $file->get_filename()
2026
                    );
2027
 
2028
                    $output .= $fileurl;
2029
                }
2030
            }
2031
        }
2032
 
2033
        return $output;
2034
    }
2035
 
161 ariadna 2036
    public function custom_course_favicon()
2037
    {
1 efrain 2038
        global $DB, $CFG, $COURSE, $PAGE;
2039
 
2040
        $output = null;
2041
 
2042
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2043
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2044
                // Get custom field ID
2045
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2046
                $customfieldpicid = $customfieldpic->id;
2047
                // Get value
2048
                $customfavicon = $DB->get_record(
2049
                    'customfield_data',
2050
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2051
                );
2052
 
2053
                $customfaviconid = $customfavicon->id;
2054
                $contextid = $customfavicon->contextid;
2055
 
2056
                if ($customfieldpic != null) {
2057
                    $files = get_file_storage()->get_area_files(
2058
                        $contextid,
2059
                        'customfield_picture',
2060
                        'file',
2061
                        $customfaviconid,
2062
                        '',
2063
                        false
2064
                    );
2065
 
2066
                    if (empty($files)) {
2067
                        return null;
2068
                    }
2069
 
2070
                    $file = reset($files);
2071
                    $fileurl = moodle_url::make_pluginfile_url(
2072
                        $file->get_contextid(),
2073
                        $file->get_component(),
2074
                        $file->get_filearea(),
2075
                        $file->get_itemid(),
2076
                        $file->get_filepath(),
2077
                        $file->get_filename()
2078
                    );
2079
 
2080
                    $output .= $fileurl;
2081
                }
2082
            }
2083
        }
2084
 
2085
        return $output;
2086
    }
2087
 
161 ariadna 2088
    public function custom_course_name()
2089
    {
1 efrain 2090
        global $DB, $CFG, $COURSE, $PAGE;
2091
 
2092
        $output = null;
2093
 
2094
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2095
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2096
                // Get custom field by name
2097
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2098
                // Get value
2099
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2100
                if (!empty($customcoursename)) {
2101
                    $output .= $customcoursename->value;
2102
                }
2103
            } else {
2104
                $customcoursename = null;
2105
            }
2106
        }
2107
 
2108
        return $output;
2109
    }
2110
 
161 ariadna 2111
    /**
1 efrain 2112
     * Get the course pattern datauri to show on a course card.
2113
     *
2114
     * The datauri is an encoded svg that can be passed as a url.
2115
     * @param int $id Id to use when generating the pattern
2116
     * @return string datauri
2117
     */
161 ariadna 2118
    public function get_generated_image_for_id($id)
2119
    {
1 efrain 2120
        global $CFG;
2121
 
2122
        $theme = \theme_config::load('universe');
2123
        // Add custom course cover.
2124
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2125
 
2126
        if (!empty(($customcover))) {
2127
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2128
            $customcover = str_replace($urlreplace, '', $customcover);
2129
            $txt = new moodle_url($customcover);
2130
            return strval($txt);
2131
        } else {
2132
            $color = $this->get_generated_color_for_id($id);
2133
            $pattern = new \core_geopattern();
2134
            $pattern->setColor($color);
2135
            $pattern->patternbyid($id);
2136
            return $pattern->datauri();
2137
        }
2138
    }
161 ariadna 2139
 
2140
    public function moremenu_group_item()
2141
    {
1 efrain 2142
        global $CFG, $COURSE;
2143
 
2144
        $theme = \theme_config::load('universe');
2145
        $courseid = $COURSE->id;
2146
        $sitehomeurl = new moodle_url('/');
2147
 
2148
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2149
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2150
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2151
                return $html;
2152
            }
2153
        }
2154
    }
2155
 
161 ariadna 2156
    public function moremenu_custom_items()
2157
    {
1 efrain 2158
        global $CFG, $COURSE, $USER;
2159
 
2160
        $theme = \theme_config::load('universe');
2161
        $html = '';
2162
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2163
 
2164
        // Get current user role ID.
2165
        $context = context_course::instance($COURSE->id);
2166
        $roles = get_user_roles($context, $USER->id, true);
2167
        $role = 999;
2168
        $roleid = 999;
2169
        $role = key($roles);
2170
        if ($role != null) {
2171
            $roleid = $roles[$role]->roleid;
2172
        }
2173
 
2174
        // End.
2175
 
2176
        if ($this->page->theme->settings->secnavitems == 1) {
2177
 
2178
            $secnav = new stdClass();
2179
            for ($i = 1; $i <= $secnavcount; $i++) {
2180
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2181
 
2182
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2183
                $courseid = $COURSE->id;
2184
                $newurl = str_replace("{{courseID}}", $courseid, $url);
161 ariadna 2185
 
1 efrain 2186
                // User role restriction.
2187
                $selectrole = theme_universe_get_setting("secnavuserroles" . $i);
161 ariadna 2188
 
2189
                if ($roleid == $selectrole) {
1 efrain 2190
                    $secnav->url = $newurl;
2191
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
161 ariadna 2192
                }
2193
                if ($roleid != $selectrole) {
1 efrain 2194
                    $secnav->url = $newurl;
2195
                }
161 ariadna 2196
                if ($selectrole == 0) {
1 efrain 2197
                    $secnav->url = $newurl;
2198
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
161 ariadna 2199
                }
1 efrain 2200
                // End.
2201
 
2202
            }
2203
        }
2204
        return $html;
2205
    }
2206
}