Proyectos de Subversion Moodle

Rev

Rev 1169 | | 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
 
1191 ariadna 1756
        // Verificar si el curso está definido
1757
        if (!isset($COURSE) || empty($COURSE->id)) {
1758
            debugging('Error: No se pudo obtener el contexto del curso.', DEBUG_DEVELOPER);
1759
            return parent::header();
1760
        }
1761
 
1762
        // Verificar si el usuario está autenticado
1763
        if (!isset($USER->id)) {
1764
            debugging('Error: Usuario no autenticado.', DEBUG_DEVELOPER);
1765
            return parent::header();
1766
        }
1767
 
1768
        // Obtener contexto del curso
257 ariadna 1769
        $context = context_course::instance($COURSE->id);
1191 ariadna 1770
        $roles = get_user_roles($context, $USER->id, true) ?: [];
257 ariadna 1771
 
1191 ariadna 1772
        // Agregar clases según los roles del usuario
1773
        if (!empty($roles)) {
257 ariadna 1774
            foreach ($roles as $role) {
1775
                $this->page->add_body_class('role-' . $role->shortname);
1776
            }
1777
        } else {
1778
            $this->page->add_body_class('role-none');
1779
        }
1780
 
1191 ariadna 1781
        // Verificar configuración de edición
1782
        if (!empty($theme->settings->topbareditmode) && $theme->settings->topbareditmode == '1') {
257 ariadna 1783
            $this->page->add_body_class('rui-editmode--top');
1784
        } else {
1785
            $this->page->add_body_class('rui-editmode--footer');
1786
        }
1787
 
1788
        return parent::header();
1789
    }
1790
 
1791
 
1191 ariadna 1792
 
257 ariadna 1793
    /**
1794
     * See if this is the first view of the current cm in the session if it has fake blocks.
1795
     *
1796
     * (We track up to 100 cms so as not to overflow the session.)
1797
     * This is done for drawer regions containing fake blocks so we can show blocks automatically.
1798
     *
1799
     * @return boolean true if the page has fakeblocks and this is the first visit.
1800
     */
1801
    public function firstview_fakeblocks(): bool
1802
    {
1803
        global $SESSION;
1804
 
1805
        $firstview = false;
1806
        if ($this->page->cm) {
1807
            if (!$this->page->blocks->region_has_fakeblocks('side-pre')) {
1808
                return false;
1809
            }
1810
            if (!property_exists($SESSION, 'firstview_fakeblocks')) {
1811
                $SESSION->firstview_fakeblocks = [];
1812
            }
1813
            if (array_key_exists($this->page->cm->id, $SESSION->firstview_fakeblocks)) {
1814
                $firstview = false;
1815
            } else {
1816
                $SESSION->firstview_fakeblocks[$this->page->cm->id] = true;
1817
                $firstview = true;
1818
                if (count($SESSION->firstview_fakeblocks) > 100) {
1819
                    array_shift($SESSION->firstview_fakeblocks);
1820
                }
1821
            }
1822
        }
1823
        return $firstview;
1824
    }
1825
 
1826
 
1827
    /**
1828
     * Build the guest access hint HTML code.
1829
     *
1830
     * @param int $courseid The course ID.
1831
     * @return string.
1832
     */
1833
    public function theme_universe_get_course_guest_access_hint($courseid)
1834
    {
1835
        global $CFG;
1836
        require_once($CFG->dirroot . '/enrol/self/lib.php');
1837
 
1838
        $html = '';
1839
        $instances = enrol_get_instances($courseid, true);
1840
        $plugins = enrol_get_plugins(true);
1841
        foreach ($instances as $instance) {
1842
            if (!isset($plugins[$instance->enrol])) {
1843
                continue;
1844
            }
1845
            $plugin = $plugins[$instance->enrol];
1846
            if ($plugin->show_enrolme_link($instance)) {
1847
                $html = html_writer::tag('div', get_string(
1848
                    'showhintcourseguestaccesssettinglink',
1849
                    'theme_universe',
1850
                    array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
1851
                ));
1852
                break;
1853
            }
1854
        }
1855
 
1856
        return $html;
1857
    }
1858
 
256 ariadna 1859
    public function render_statics_blocks($userid = null)
1860
    {
1861
        global $USER;
1862
 
1863
        if (!$userid) {
1864
            $userid = $USER->id;
1865
        }
1866
 
1867
        // Instanciamos StaticsBlocks para renderizar los bloques
379 ariadna 1868
        $statics_blocks = new \StaticsBlocks(
383 ariadna 1869
            'side-pre',
968 ariadna 1870
            ['messageteacher', 'comments', 'cesa_course_rating', 'cesa_notes']
379 ariadna 1871
        );
1872
 
256 ariadna 1873
        $blocks = $statics_blocks->renderBlocks();
1874
 
1875
        return $blocks;
1876
    }
257 ariadna 1877
 
1878
 
1879
    /**
1880
     * Color Customization
1881
     * @return string HTML fragment.
1882
     */
1883
    public function additional_head_html()
1884
    {
1885
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1886
 
1887
        $output = null;
1888
 
1889
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1890
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1891
                // Get custom field by name
1892
                $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1893
                // Get value
1894
                $mainthemecolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id));
1895
            } else {
1896
                $mainthemecolor = null;
1897
            }
1898
 
1899
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1900
                $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1901
                $mainthemecolor2 = $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id));
1902
            }
1903
 
1904
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1905
                // Get custom field by name
1906
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1907
                // Get value
1908
                $topbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1909
            }
1910
 
1911
            if ($DB->record_exists('customfield_field', array('shortname' => 'dmtopbarcolor'), 'id')) {
1912
                // Get custom field by name
1913
                $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1914
                // Get value
1915
                $dmtopbarcolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id));
1916
            } else {
1917
                $dmtopbarcolor = null;
1918
            }
1919
 
1920
 
1921
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1922
                // Get custom field by name
1923
                $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1924
                // Get value
1925
                $footercolor = $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id));
1926
            } else {
1927
                $footercolor = null;
1928
            }
1929
 
1930
 
1931
            $css = '';
1932
 
1933
            $css .= ':root { ';
1934
            if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor1'), 'id')) {
1935
                if ($mainthemecolor != null) {
1936
                    $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1937
                    $css .= '--primary-color-100: ' . $mainthemecolor->value . '30; ';
1938
                    $css .= '--primary-color-300: ' . $mainthemecolor->value . '70; ';
1939
                    $css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1940
                    $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1941
                    $css .= '--btn-primary-color-bg-hover: ' . $mainthemecolor->value . '95; ';
1942
 
1943
                    if ($DB->record_exists('customfield_field', array('shortname' => 'maincolor2'), 'id')) {
1944
                        if ($mainthemecolor2 != null) {
1945
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor2->value . '; ';
1946
                        } else {
1947
                            $css .= '--main-theme-color-gradient-2: ' . $mainthemecolor->value . '30; ';
1948
                        }
1949
                    }
1950
                }
1951
            }
1952
 
1953
            if ($DB->record_exists('customfield_field', array('shortname' => 'topbarcolor'), 'id')) {
1954
                if ($topbarcolor != null) {
1955
                    $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1956
                    if ($dmtopbarcolor != null) {
1957
                        $css .= '--dm-topbar-color: ' . $dmtopbarcolor->value . '; ';
1958
                    } else {
1959
                        $css .= '--dm-topbar-color: ' . $topbarcolor->value . '; ';
1960
                    }
1961
                }
1962
            }
1963
 
1964
            if ($DB->record_exists('customfield_field', array('shortname' => 'footerbgcolor'), 'id')) {
1965
                if ($footercolor != null) {
1966
                    $css .= '--footer-color: ' . $footercolor->value . '; ';
1967
                }
1968
            }
1969
 
1970
            $css .= '}';
1971
 
1972
            if ($css) {
1973
                $output .= '<style>' . $css . '</style>';
1974
            }
1975
        }
1976
 
1977
        return $output;
1978
    }
1979
 
1980
    public function custom_course_logo()
1981
    {
1982
        global $DB, $CFG, $COURSE, $PAGE;
1983
 
1984
        $output = null;
1985
 
1986
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1987
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1988
                // Get custom field ID
1989
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1990
                $customfieldpicid = $customfieldpic->id;
1991
                // Get value
1992
                $customlogo = $DB->get_record(
1993
                    'customfield_data',
1994
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
1995
                );
1996
 
1997
                $customlogoid = $customlogo->id;
1998
                $contextid = $customlogo->contextid;
1999
 
2000
                if ($customfieldpic != null) {
2001
                    $files = get_file_storage()->get_area_files(
2002
                        $contextid,
2003
                        'customfield_picture',
2004
                        'file',
2005
                        $customlogoid,
2006
                        '',
2007
                        false
2008
                    );
2009
 
2010
                    if (empty($files)) {
2011
                        return null;
2012
                    }
2013
 
2014
                    $file = reset($files);
2015
                    $fileurl = moodle_url::make_pluginfile_url(
2016
                        $file->get_contextid(),
2017
                        $file->get_component(),
2018
                        $file->get_filearea(),
2019
                        $file->get_itemid(),
2020
                        $file->get_filepath(),
2021
                        $file->get_filename()
2022
                    );
2023
 
2024
                    $output .= $fileurl;
2025
                }
2026
            }
2027
        }
2028
 
2029
        return $output;
2030
    }
2031
 
2032
    public function custom_course_dmlogo()
2033
    {
2034
        global $DB, $CFG, $COURSE, $PAGE;
2035
 
2036
        $output = null;
2037
 
2038
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2039
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
2040
                // Get custom field ID
2041
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
2042
                $customfieldpicid = $customfieldpic->id;
2043
                // Get value
2044
                $customlogo = $DB->get_record(
2045
                    'customfield_data',
2046
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2047
                );
2048
 
2049
                $customlogoid = $customlogo->id;
2050
                $contextid = $customlogo->contextid;
2051
 
2052
                if ($customfieldpic != null) {
2053
                    $files = get_file_storage()->get_area_files(
2054
                        $contextid,
2055
                        'customfield_picture',
2056
                        'file',
2057
                        $customlogoid,
2058
                        '',
2059
                        false
2060
                    );
2061
 
2062
                    if (empty($files)) {
2063
                        return null;
2064
                    }
2065
 
2066
                    $file = reset($files);
2067
                    $fileurl = moodle_url::make_pluginfile_url(
2068
                        $file->get_contextid(),
2069
                        $file->get_component(),
2070
                        $file->get_filearea(),
2071
                        $file->get_itemid(),
2072
                        $file->get_filepath(),
2073
                        $file->get_filename()
2074
                    );
2075
 
2076
                    $output .= $fileurl;
2077
                }
2078
            }
2079
        }
2080
 
2081
        return $output;
2082
    }
2083
 
2084
    public function custom_course_favicon()
2085
    {
2086
        global $DB, $CFG, $COURSE, $PAGE;
2087
 
2088
        $output = null;
2089
 
2090
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2091
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2092
                // Get custom field ID
2093
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2094
                $customfieldpicid = $customfieldpic->id;
2095
                // Get value
2096
                $customfavicon = $DB->get_record(
2097
                    'customfield_data',
2098
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2099
                );
2100
 
2101
                $customfaviconid = $customfavicon->id;
2102
                $contextid = $customfavicon->contextid;
2103
 
2104
                if ($customfieldpic != null) {
2105
                    $files = get_file_storage()->get_area_files(
2106
                        $contextid,
2107
                        'customfield_picture',
2108
                        'file',
2109
                        $customfaviconid,
2110
                        '',
2111
                        false
2112
                    );
2113
 
2114
                    if (empty($files)) {
2115
                        return null;
2116
                    }
2117
 
2118
                    $file = reset($files);
2119
                    $fileurl = moodle_url::make_pluginfile_url(
2120
                        $file->get_contextid(),
2121
                        $file->get_component(),
2122
                        $file->get_filearea(),
2123
                        $file->get_itemid(),
2124
                        $file->get_filepath(),
2125
                        $file->get_filename()
2126
                    );
2127
 
2128
                    $output .= $fileurl;
2129
                }
2130
            }
2131
        }
2132
 
2133
        return $output;
2134
    }
2135
 
2136
    public function custom_course_name()
2137
    {
2138
        global $DB, $CFG, $COURSE, $PAGE;
2139
 
2140
        $output = null;
2141
 
2142
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2143
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2144
                // Get custom field by name
2145
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2146
                // Get value
2147
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2148
                if (!empty($customcoursename)) {
2149
                    $output .= $customcoursename->value;
2150
                }
2151
            } else {
2152
                $customcoursename = null;
2153
            }
2154
        }
2155
 
2156
        return $output;
2157
    }
2158
 
2159
    /**
2160
     * Get the course pattern datauri to show on a course card.
2161
     *
2162
     * The datauri is an encoded svg that can be passed as a url.
2163
     * @param int $id Id to use when generating the pattern
2164
     * @return string datauri
2165
     */
2166
    public function get_generated_image_for_id($id)
2167
    {
2168
        global $CFG;
2169
 
2170
        $theme = \theme_config::load('universe');
2171
        // Add custom course cover.
2172
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2173
 
2174
        if (!empty(($customcover))) {
2175
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2176
            $customcover = str_replace($urlreplace, '', $customcover);
2177
            $txt = new moodle_url($customcover);
2178
            return strval($txt);
2179
        } else {
2180
            $color = $this->get_generated_color_for_id($id);
2181
            $pattern = new \core_geopattern();
2182
            $pattern->setColor($color);
2183
            $pattern->patternbyid($id);
2184
            return $pattern->datauri();
2185
        }
2186
    }
2187
 
2188
    public function moremenu_group_item()
2189
    {
2190
        global $CFG, $COURSE;
2191
 
2192
        $theme = \theme_config::load('universe');
2193
        $courseid = $COURSE->id;
2194
        $sitehomeurl = new moodle_url('/');
2195
 
2196
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2197
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2198
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2199
                return $html;
2200
            }
2201
        }
2202
    }
2203
 
369 ariadna 2204
 
2205
    public function cesa_navigation_course_completion()
2206
    {
2207
        global $COURSE, $PAGE, $USER, $CFG;
2208
 
2209
        if (empty($PAGE->cm->id) || empty($COURSE->enablecompletion)) {
2210
            return '';
2211
        }
2212
 
2213
        $course_context = context_course::instance($COURSE->id);
2214
        $roles = get_user_roles($course_context, $USER->id, true);
2215
 
2216
        $completion_visible = true;
2217
        foreach ($roles as $role) {
2218
            if ($role->shortname != 'student') {
2219
                $completion_visible  = false;
2220
            }
2221
        }
2222
 
2223
        if (!$completion_visible) {
891 ariadna 2224
            return '';
369 ariadna 2225
        }
2226
        $PAGE->requires->js(new \moodle_url($CFG->wwwroot . '/local/cesanavigation/javascript/terminacion.js'));
2227
 
2228
        $page_context = $PAGE->cm;
2229
 
2230
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2231
 
2232
        $mods = [];
2233
        foreach ($modules as $module) {
2234
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2235
                continue;
2236
            }
2237
            $mods[$module->id] = $module;
2238
        }
2239
 
2240
 
2241
 
2242
        $nummods = count($mods);
2243
 
2244
        // If there is only one mod then do nothing.
2245
        if ($nummods == 1) {
2246
            return '';
2247
        }
2248
 
2249
        $modids = array_keys($mods);
2250
        $position = array_search($page_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2251
 
2252
        $currentmod = $mods[$modids[$position]];
2253
 
2254
        /*if(!$currentmod->completion) {
2255
            return '';
2256
        }*/
2257
 
2258
        $completioninfo = new \completion_info($COURSE);
2259
        $completiondata = $completioninfo->get_data($currentmod, true);
2260
        if ($completiondata->completionstate != COMPLETION_COMPLETE && $completiondata->completionstate != COMPLETION_COMPLETE_PASS) {
2261
            $url = new \moodle_url($CFG->wwwroot . '/local/cesanavigation/terminacion.php', ['courseid' => $COURSE->id, 'modid' =>  $currentmod->id]);
2262
 
2263
 
2264
            return '<div class="containerr">
2265
                        <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">
2266
                    </div>';
2267
        }
2268
 
891 ariadna 2269
        return '';
369 ariadna 2270
    }
2271
 
257 ariadna 2272
    public function moremenu_custom_items()
2273
    {
2274
        global $CFG, $COURSE, $USER;
2275
 
2276
        $theme = \theme_config::load('universe');
2277
        $html = '';
2278
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2279
 
2280
        // Get current user role ID.
2281
        $context = context_course::instance($COURSE->id);
2282
        $roles = get_user_roles($context, $USER->id, true);
2283
        $role = 999;
2284
        $roleid = 999;
2285
        $role = key($roles);
2286
        if ($role != null) {
2287
            $roleid = $roles[$role]->roleid;
2288
        }
2289
 
2290
        // End.
2291
 
2292
        if ($this->page->theme->settings->secnavitems == 1) {
2293
 
2294
            $secnav = new stdClass();
2295
            for ($i = 1; $i <= $secnavcount; $i++) {
2296
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2297
 
2298
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2299
                $courseid = $COURSE->id;
2300
                $newurl = str_replace("{{courseID}}", $courseid, $url);
2301
 
2302
                // User role restriction.
2303
                $selectrole = theme_universe_get_setting("secnavuserroles" . $i);
2304
 
2305
                if ($roleid == $selectrole) {
2306
                    $secnav->url = $newurl;
2307
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2308
                }
2309
                if ($roleid != $selectrole) {
2310
                    $secnav->url = $newurl;
2311
                }
2312
                if ($selectrole == 0) {
2313
                    $secnav->url = $newurl;
2314
                    $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
2315
                }
2316
                // End.
2317
 
2318
            }
2319
        }
2320
        return $html;
2321
    }
655 ariadna 2322
 
2323
    public function get_navbar_image_courses()
2324
    {
2325
        global $CFG;
2326
 
2327
        if (!empty($this->page->theme->settings->navbar_icon_courses)) {
2328
            $url = $this->page->theme->setting_file_url('navbar_icon_courses', 'navbar_icon_courses');
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
 
686 ariadna 2336
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-catalog-white.png';
655 ariadna 2337
    }
2338
 
2339
    public function get_navbar_image_progress()
2340
    {
2341
        global $CFG;
2342
 
2343
        if (!empty($this->page->theme->settings->navbar_icon_progress)) {
2344
            $url = $this->page->theme->setting_file_url('navbar_icon_progress', 'navbar_icon_progress');
2345
            // Get a URL suitable for moodle_url.
2346
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2347
            $url = str_replace($relativebaseurl, '', $url);
2348
            return new moodle_url($url);
2349
        }
2350
 
2351
 
2352
 
686 ariadna 2353
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-progress-white.png';
655 ariadna 2354
    }
2355
 
2356
    public function get_navbar_image_forums()
2357
    {
2358
        global $CFG;
2359
 
2360
 
2361
        if (!empty($this->page->theme->settings->navbar_icon_forums)) {
2362
            $url = $this->page->theme->setting_file_url('navbar_icon_forums', 'navbar_icon_forums');
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
 
686 ariadna 2369
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-forum-white.png';
655 ariadna 2370
    }
2371
 
2372
    public function get_navbar_image_calendar()
2373
    {
2374
        global $CFG;
2375
 
2376
 
2377
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2378
            $url = $this->page->theme->setting_file_url('navbar_icon_calendar', 'navbar_icon_calendar');
2379
            // Get a URL suitable for moodle_url.
2380
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2381
            $url = str_replace($relativebaseurl, '', $url);
2382
            return new moodle_url($url);
2383
        }
2384
 
687 ariadna 2385
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-calendar-white.png';
655 ariadna 2386
    }
669 ariadna 2387
 
682 ariadna 2388
    public function get_theme_image_login_bg()
669 ariadna 2389
    {
684 ariadna 2390
        global  $DB, $CFG;
681 ariadna 2391
 
682 ariadna 2392
        if (!empty($this->page->theme->settings->loginimagebackground)) {
2393
            $url = $this->page->theme->setting_file_url('loginimagebackground', 'loginimagebackground');
681 ariadna 2394
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2395
            $url = str_replace($relativebaseurl, '', $url);
2396
            return new moodle_url($url);
2397
        }
2398
 
684 ariadna 2399
        return '';
669 ariadna 2400
    }
693 ariadna 2401
 
2402
    public function get_navbar_image_personal_area()
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_personal_area', 'navbar_icon_personal_area');
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-personal-area-white.png';
2416
    }
694 ariadna 2417
 
2418
    public function get_navbar_image_messages()
2419
    {
2420
        global $CFG;
2421
 
2422
 
2423
        if (!empty($this->page->theme->settings->navbar_icon_calendar)) {
2424
            $url = $this->page->theme->setting_file_url('navbar_icon_messages', 'navbar_icon_messages');
2425
            // Get a URL suitable for moodle_url.
2426
            $relativebaseurl = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2427
            $url = str_replace($relativebaseurl, '', $url);
2428
            return new moodle_url($url);
2429
        }
2430
 
2431
        return $CFG->wwwroot . '/theme/universe_child/pix/icon-messages-white.png';
2432
    }
901 ariadna 2433
 
2434
    private function extractDurationFromVideo($record, $filename)
2435
    {
2436
        global $DB;
2437
 
2438
        $duration = 0;
2439
 
2440
        if (empty($record->duration)) {
2441
            $fs = get_file_storage();
2442
            $file = $fs->get_file($record->contextid, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename);
2443
            if ($file) {
2444
 
2445
                $data = $file->get_content();
2446
 
2447
                $path_temp = __DIR__ . DIRECTORY_SEPARATOR . 'tmp';
2448
                if (!file_exists($path_temp)) {
2449
                    mkdir($path_temp, 0755);
2450
                }
2451
 
2452
                $full_filename = $path_temp . DIRECTORY_SEPARATOR . uniqid() . '_' . $filename;
2453
                file_put_contents($full_filename, $data);
2454
 
2455
                if (file_exists($full_filename)) {
2456
                    $cmd = "/usr/bin/ffprobe -i $full_filename -show_entries format=duration -v quiet -of csv=\"p=0\" ";
2457
                    $response = trim(shell_exec($cmd));
2458
                    @unlink($full_filename);
2459
 
2460
 
2461
                    $duration = $response;
2462
 
2463
 
2464
                    if ($response) {
2465
                        $response = floatval($response);
2466
 
2467
                        if ($response > 60) {
2468
 
2469
                            //echo 'response = ' . $response . '<br>';
2470
 
2471
                            $minutes = intval($response / 60);
2472
                            //echo 'minutes = ' . $minutes . '<br>';
2473
 
2474
                            $seconds = round(($response - ($minutes * 60)));
2475
                            //echo 'seconds = ' . $seconds . '<br>';
2476
 
2477
 
2478
                            if ($minutes < 10) {
2479
                                $duration = '0' . $minutes;
2480
                            } else {
2481
                                $duration = $minutes;
2482
                            }
2483
 
2484
                            if ($seconds) {
2485
                                if ($seconds < 10) {
2486
                                    $duration = $duration . ':0' . $seconds;
2487
                                } else {
2488
                                    $duration = $duration . ':' . $seconds;
2489
                                }
2490
                            } else {
2491
                                $duration = $duration . ':00';
2492
                            }
2493
                        } else {
2494
                            $duration = '00:' . intval($response);
2495
                        }
2496
 
2497
 
2498
 
2499
                        $dataobject = new \stdClass();
2500
                        $dataobject->id = $record->id;
2501
                        $dataobject->duration = $duration;
2502
 
2503
 
2504
 
2505
                        $DB->update_record('files', $dataobject);
2506
                    }
2507
                }
2508
            }
2509
        }
2510
        return $duration;
2511
    }
2512
 
2513
    private function substr_cesa_navigation_course_menu_name($s, $l = 50)
2514
    {
2515
        $s = trim($s);
2516
        if (strlen($s) > $l) {
2517
            $s = substr($s, 0, $l) . '...';
2518
        }
2519
        return $s;
2520
    }
2521
 
2522
    public function cesa_navigation_course_menu_lateral_output()
2523
    {
1169 ariadna 2524
 
2525
 
2526
 
901 ariadna 2527
        global $CFG, $COURSE, $PAGE, $DB, $OUTPUT;
2528
 
2529
 
2530
 
2531
 
2532
        if (!$COURSE->id) {
2533
            return '';
2534
        }
2535
 
2536
        $course_id = $COURSE->id;
2537
 
2538
        $parent = optional_param('parent', 0, PARAM_INT); // Course module id
2539
        if (!$parent) {
2540
            $parent = optional_param('amp;parent', 0, PARAM_INT); // Course module id
2541
        }
2542
 
1158 efrain 2543
        //$PAGE->requires->js('/theme/edumynew/javascript/menu-lateral.js');
901 ariadna 2544
 
2545
 
2546
        if ($parent) {
2547
            $sql  = ' SELECT * FROM {subcourse} WHERE course = ' . $parent;
2548
            $sql .= ' AND refcourse = ' . $course_id;
2549
 
2550
            $recordParentRefCourse  = $DB->get_record_sql($sql);
2551
            if ($recordParentRefCourse) {
2552
                $course_id = $recordParentRefCourse->course;
2553
            }
2554
        }
2555
 
2556
 
2557
 
2558
        $course = get_course($course_id);
2559
        $course_context = context_course::instance($course->id);
2560
        $completioninfo = new \completion_info($course);
2561
 
2562
        // $course_context = !empty($PAGE->cm->id)  ? $PAGE->cm : \context_course::instance($COURSE->id);
2563
        // First we should check if we want to add navigation.
2564
        // Get a list of all the activities in the course.
2565
 
2566
 
2567
 
2568
        $menu = [];
2569
 
2570
        $currentServerLink = strtolower(trim($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']));
2571
        $currentServerLink = html_entity_decode($currentServerLink);
2572
        $currentServerLink = htmlentities($currentServerLink);
2573
 
2574
        $parts = explode('&', $currentServerLink);
2575
        if (count($parts) > 1) {
2576
            $currentServerLink = $parts[0];
2577
        }
2578
 
2579
 
2580
 
2581
 
2582
        $modules = get_fast_modinfo($course->id)->get_cms();
2583
 
2584
        $prevmod = null;
2585
        $nextmod = null;
2586
        $currentmod = new stdClass();
2587
        $currentmod->name = "Sin Módulos";
2588
        $mods = [];
2589
        $menu = [];
2590
        $numberOfTemary = 1;
2591
        $prevlink = new \StdClass();
2592
        $nextlink = new \StdClass();
2593
        $prevlink->url = "#";
2594
        $nextlink->url = "#";
2595
 
2596
        $isACoursePage = $course->id !== "1" ? true : false;
2597
 
2598
 
2599
 
2600
 
2601
        $modules = get_fast_modinfo($COURSE->id)->get_cms();
2602
        /*
2603
            echo '<pre>';
2604
            print_r($modules);
2605
            echo '</pre>';
2606
            */
2607
 
2608
        if (!empty($modules)) {
2609
            // Put the modules into an array in order by the position they are shown in the course.
2610
            foreach ($modules as $module) {
2611
                if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2612
                    continue;
2613
                }
2614
                $mods[$module->id] = $module;
2615
            }
2616
 
2617
 
2618
            $nummods = count($mods);
2619
 
2620
 
2621
            // If there is only one mod then do nothing.
2622
            if ($nummods == 1) {
2623
            }
2624
 
2625
            // Get an array of just the course module ids used to get the cmid value based on their position in the course.
2626
            $modids = array_keys($mods);
2627
 
2628
            // Get the position in the array of the course module we are viewing.
2629
            $position = array_search($course_context->id, $modids);   //array_search($this->page->cm->id, $modids);
2630
 
2631
            $currentmod = $mods[$modids[$position]];
2632
 
2633
 
2634
 
2635
            // Check if we have a previous mod to show.
2636
            if ($position > 0) {
2637
                $prevmod = $mods[$modids[$position - 1]];
2638
            }
2639
 
2640
            // Check if we have a next mod to show.
2641
            if ($position < ($nummods - 1)) {
2642
                $nextmod = $mods[$modids[$position + 1]];
2643
            }
2644
        }
2645
 
2646
 
2647
        //$sections = $DB->get_records('course_sections', ['course' => $COURSE->id], 'section ASC', 'id,name,section,sequence,visible');
2648
 
2649
 
2650
 
2651
 
2652
        $modinfo = get_fast_modinfo($course);
2653
        $records  =  $modinfo->get_section_info_all();
2654
        $sections = [];
2655
 
2656
        foreach ($records as $record) {
2657
            if (!$record->visible) {
2658
                continue;
2659
            }
2660
 
2661
            $section = new \stdClass();
2662
            $section->id = $record->id;
2663
            $section->section = $record->section;
2664
            $section->name = $record->name;
2665
            $section->parent = $record->parent;
2666
            $section->visible = 1;
2667
 
2668
 
2669
            array_push($sections, $section);
2670
        }
2671
 
2672
 
2673
 
2674
        $openParent = 0;
2675
        $maxSections = count($sections);
2676
        for ($i = 0; $i < $maxSections; $i++) {
2677
 
2678
 
2679
 
2680
            $j = $i + 1;
2681
            if ($j < $maxSections) {
2682
 
2683
                if ($sections[$j]->parent) {
2684
                    $openParent = true;
2685
                    $sections[$i]->close_section_parent = 0;
2686
                    $sections[$i]->close_section = 0;
2687
                } else {
2688
                    $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2689
 
2690
                    $sections[$i]->close_section = 1;
2691
                }
2692
            } else {
2693
                $sections[$i]->close_section_parent = $openParent ? 1 : 0;
2694
                $sections[$i]->close_section = 1;
2695
            }
2696
 
2697
            // print_r($section);
2698
 
2699
 
2700
        }
2701
 
2702
        /*
2703
             echo '<pre>';
2704
           print_r($sections);
2705
           echo '</pre>';
2706
 
2707
      */
2708
 
2709
 
2710
 
2711
 
2712
        foreach ($sections as $key =>  $section) {
2713
 
2714
            if (!$section->visible) {
2715
                continue;
2716
            }
2717
 
2718
            $activities = [];
2719
            $section_active = false;
2720
 
2721
            foreach ($modules as $module) {
2722
 
2723
                if ($module->section  != $section->id) {
2724
                    continue;
2725
                }
2726
 
2727
                if (!$module->uservisible || $module->is_stealth()) {
2728
                    // if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
2729
                    continue;
2730
                }
934 ariadna 2731
 
901 ariadna 2732
                $mods[$module->id] = $module;
2733
 
2734
                $duration = '';
2735
                $type = '';
2736
                $filepath = '';
2737
 
2738
                $sql = 'SELECT md.name, cm.instance  FROM {modules} md  ' .
2739
                    ' JOIN {course_modules} cm ON cm.module = md.id ' .
2740
                    ' WHERE cm.id = '  . $module->id . ' LIMIT 1 ';
2741
 
2742
                $record = $DB->get_record_sql($sql);
2743
                if ($record) {
2744
 
2745
                    /*
2746
                        echo '<pre>';
2747
                        print_r($record);
2748
                        echo '<pre>';
2749
                        */
2750
 
2751
                    $type = $record->name;
2752
 
2753
                    if ($type == 'hvp') {
2754
                        $instance   = $record->instance;
2755
 
2756
                        $sql = 'SELECT json_content FROM {hvp} WHERE id = ' . $instance . ' LIMIT 1';
2757
                        $record = $DB->get_record_sql($sql);
2758
 
2759
                        if ($record) {
2760
                            $json_content = json_decode($record->json_content);
2761
 
2762
                            if (!empty($json_content->interactiveVideo->video->files[0]->path)) {
2763
                                $filepath = trim($json_content->interactiveVideo->video->files[0]->path);
2764
                                $filepath = trim(str_replace('#tmp', '', $filepath));
2765
 
2766
 
2767
                                $arr = explode('/', $filepath);
2768
                                if (count($arr) > 1) {
2769
                                    $filename = $arr[count($arr) - 1];
2770
                                } else {
2771
                                    $filename = $arr[0];
2772
                                }
2773
 
2774
                                $record = $DB->get_record('files', ['filename' => $filename]);
2775
                                if ($record) {
2776
                                    $duration = $this->extractDurationFromVideo($record, $filename);
2777
                                }
2778
                            }
2779
                        }
2780
                    }
2781
                }
2782
 
934 ariadna 2783
                $modname = $module->get_formatted_name();
984 ariadna 2784
                $modcontent = $module->get_formatted_content();
901 ariadna 2785
 
2786
                if (empty($module->url)) {
2787
                    $linkurl = '';
2788
                    $currentLink = '';
2789
                } else {
2790
 
2791
                    $linkurl = new moodle_url($module->url, array('forceview' => 1));
2792
                    $linkurl = strtolower(trim($linkurl->__toString()));
2793
 
2794
                    $parts = explode('&', $linkurl);
2795
                    if (count($parts) > 1) {
2796
                        $currentLink = $parts[0];
2797
                    } else {
2798
                        $currentLink = $linkurl;
2799
                    }
2800
                }
2801
 
2802
                $completiondata = $completioninfo->get_data($module, true);
2803
 
2804
                if (strcasecmp($currentLink,  $currentServerLink) == 0) {
2805
                    $active = true;
2806
                    $section_active = true;
2807
                } else {
2808
                    $active = false;
2809
                }
2810
 
2811
                array_push($activities, [
2812
                    'active' => $active,
2813
                    'indexElement' => $key,
2814
                    'numberOfTemary' => $numberOfTemary,
2815
                    'activity' => true,
2816
                    'blank' => !empty($section->section),
2817
                    'name' => $this->substr_cesa_navigation_course_menu_name($modname),
984 ariadna 2818
                    'content' => $modcontent,
901 ariadna 2819
                    'duration' => $duration,
2820
                    'type' =>  $type,
2821
                    'completed' => $completiondata->completionstate == COMPLETION_COMPLETE || $completiondata->completionstate == COMPLETION_COMPLETE_PASS,
943 ariadna 2822
                    'failed' => $completiondata->completionstate == COMPLETION_COMPLETE_FAIL,
940 ariadna 2823
                    'url' => $linkurl
901 ariadna 2824
                ]);
2825
            }
2826
 
2827
 
2828
            if ($activities) {
2829
 
2830
                if ($section->section) {
2831
                    $sectionname = trim($section->name);
2832
                    $sectionname = $sectionname ? $sectionname : ' Tema ' . $section->section;
2833
                } else {
2834
                    $sectionname = 'Recursos';
2835
                }
2836
 
2837
                array_push($menu, [
2838
                    'active' => $section_active,
2839
                    'indexElement' => $key,
934 ariadna 2840
                    'id' => $section->id,
901 ariadna 2841
                    'numberOfTemary' => $numberOfTemary,
2842
                    'section' => true,
2843
                    'name' => $this->substr_cesa_navigation_course_menu_name($sectionname),
2844
                    'close_section_parent' => $section->close_section_parent,
2845
                    'close_section' => $section->close_section,
2846
                    'completed' => false,
2847
                    'url' => false,
2848
                    'activities' => $activities,
2849
 
2850
 
2851
                ]);
2852
            }
2853
 
2854
 
2855
            $numberOfTemary = ++$numberOfTemary;
2856
        }
2857
 
2858
        // Check if there is a previous module to display.
2859
        if ($prevmod) {
2860
            $linkurl = new \moodle_url($prevmod->url, array('forceview' => 1));
2861
            $attributes = [];
2862
            $prevlink = new \action_link($linkurl, $OUTPUT->larrow(), null, $attributes);
2863
        }
2864
 
2865
        // Check if there is a next module to display.
2866
        if ($nextmod) {
2867
            $linkurl = new \moodle_url($nextmod->url, array('forceview' => 1));
2868
            $attributes = [];
2869
            $nextlink = new \action_link($linkurl, $OUTPUT->rarrow(), null, $attributes);
2870
        }
2871
 
2872
 
2873
        //  echo '<pre>';
2874
        // print_r($activities);
2875
        // echo '</pre>';
2876
        // exit;
2877
 
2878
 
2879
        $progreso = number_format(progress::get_course_progress_percentage($course), 2); // Progreso por curso
2880
 
2881
        $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);
2882
        return $course_navigation->export_for_template($OUTPUT);
2883
    }
912 ariadna 2884
 
2885
    function universe_child_course_drawer(): string
2886
    {
2887
        global $PAGE;
2888
 
2889
        // If the course index is explicitly set and if it should be hidden.
2890
        if ($PAGE->get_show_course_index() === false) {
2891
            return '';
2892
        }
2893
 
2894
        // Only add course index on non-site course pages.
2895
        if (!$PAGE->course || $PAGE->course->id == SITEID) {
2896
            return '';
2897
        }
2898
 
2899
        // Show course index to users can access the course only.
2900
        if (!can_access_course($PAGE->course, null, '', true)) {
2901
            return '';
2902
        }
2903
 
2904
        $format = course_get_format($PAGE->course);
2905
        $renderer = $format->get_renderer($PAGE);
2906
        if (method_exists($renderer, 'course_index_drawer')) {
915 ariadna 2907
            return $this->render_from_template('theme_universe_child/courseindex/drawer', []);
912 ariadna 2908
        }
2909
 
2910
        return '';
2911
    }
256 ariadna 2912
}