Proyectos de Subversion Moodle

Rev

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