Proyectos de Subversion Moodle

Rev

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