Proyectos de Subversion Moodle

Rev

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

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