Proyectos de Subversion Moodle

Rev

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

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