1 |
efrain |
1 |
<?php
|
|
|
2 |
// This file is part of Moodle - http://moodle.org/
|
|
|
3 |
//
|
|
|
4 |
// Moodle is free software: you can redistribute it and/or modify
|
|
|
5 |
// it under the terms of the GNU General Public License as published by
|
|
|
6 |
// the Free Software Foundation, either version 3 of the License, or
|
|
|
7 |
// (at your option) any later version.
|
|
|
8 |
//
|
|
|
9 |
// Moodle is distributed in the hope that it will be useful,
|
|
|
10 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
11 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
12 |
// GNU General Public License for more details.
|
|
|
13 |
//
|
|
|
14 |
// You should have received a copy of the GNU General Public License
|
|
|
15 |
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
16 |
|
|
|
17 |
/**
|
|
|
18 |
* Theme functions.
|
|
|
19 |
*
|
|
|
20 |
* @package theme_universe
|
|
|
21 |
* @copyright 2023 Marcin Czaja (https://rosea.io)
|
|
|
22 |
* @license Commercial https://themeforest.net/licenses
|
|
|
23 |
*/
|
|
|
24 |
|
|
|
25 |
/**
|
|
|
26 |
* Get theme setting
|
|
|
27 |
*
|
|
|
28 |
* @param string $setting
|
|
|
29 |
* @param bool $format
|
|
|
30 |
* @return string
|
|
|
31 |
*/
|
126 |
ariadna |
32 |
function theme_universe_get_setting($setting, $format = false)
|
|
|
33 |
{
|
1 |
efrain |
34 |
$theme = theme_config::load('universe');
|
|
|
35 |
|
|
|
36 |
if (empty($theme->settings->$setting)) {
|
|
|
37 |
return false;
|
|
|
38 |
}
|
|
|
39 |
|
|
|
40 |
if (!$format) {
|
|
|
41 |
return $theme->settings->$setting;
|
|
|
42 |
}
|
|
|
43 |
|
|
|
44 |
if ($format === 'format_text') {
|
|
|
45 |
return format_text($theme->settings->$setting, FORMAT_PLAIN);
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
if ($format === 'format_html') {
|
|
|
49 |
return format_text($theme->settings->$setting, FORMAT_HTML, array('trusted' => true, 'noclean' => true));
|
|
|
50 |
}
|
|
|
51 |
|
|
|
52 |
return format_string($theme->settings->$setting);
|
|
|
53 |
}
|
|
|
54 |
|
|
|
55 |
/**
|
|
|
56 |
* Post process the CSS tree.
|
|
|
57 |
*
|
|
|
58 |
* @param string $tree The CSS tree.
|
|
|
59 |
* @param theme_config $theme The theme config object.
|
|
|
60 |
*/
|
126 |
ariadna |
61 |
function theme_universe_css_tree_post_processor($tree, $theme)
|
|
|
62 |
{
|
1 |
efrain |
63 |
debugging('theme_universe_css_tree_post_processor() is deprecated. Required' .
|
|
|
64 |
'prefixes for Bootstrap are now in theme/universe/scss/moodle/prefixes.scss');
|
|
|
65 |
$prefixer = new theme_universe\autoprefixer($tree);
|
|
|
66 |
$prefixer->prefix();
|
|
|
67 |
}
|
|
|
68 |
|
|
|
69 |
/**
|
|
|
70 |
* Get the current user preferences that are available
|
|
|
71 |
*
|
|
|
72 |
* @return array[]
|
|
|
73 |
*/
|
126 |
ariadna |
74 |
function theme_universe_user_preferences(): array
|
|
|
75 |
{
|
1 |
efrain |
76 |
return [
|
|
|
77 |
'drawer-open-block' => [
|
|
|
78 |
'type' => PARAM_BOOL,
|
|
|
79 |
'null' => NULL_NOT_ALLOWED,
|
|
|
80 |
'default' => false,
|
|
|
81 |
'permissioncallback' => [core_user::class, 'is_current_user'],
|
|
|
82 |
],
|
|
|
83 |
'drawer-open-index' => [
|
|
|
84 |
'type' => PARAM_BOOL,
|
|
|
85 |
'null' => NULL_NOT_ALLOWED,
|
|
|
86 |
'default' => true,
|
|
|
87 |
'permissioncallback' => [core_user::class, 'is_current_user'],
|
|
|
88 |
],
|
|
|
89 |
'darkmode-on' => [
|
|
|
90 |
'type' => PARAM_BOOL,
|
|
|
91 |
'null' => NULL_NOT_ALLOWED,
|
|
|
92 |
'default' => false,
|
|
|
93 |
'permissioncallback' => [core_user::class, 'is_current_user'],
|
|
|
94 |
],
|
|
|
95 |
'sidepre-open' => [
|
|
|
96 |
'type' => PARAM_BOOL,
|
|
|
97 |
'null' => NULL_NOT_ALLOWED,
|
|
|
98 |
'default' => true,
|
|
|
99 |
'permissioncallback' => [core_user::class, 'is_current_user'],
|
|
|
100 |
],
|
|
|
101 |
];
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
/**
|
|
|
105 |
* Inject additional SCSS.
|
|
|
106 |
*
|
|
|
107 |
* @param theme_config $theme The theme config object.
|
|
|
108 |
* @return string
|
|
|
109 |
*/
|
126 |
ariadna |
110 |
function theme_universe_get_extra_scss($theme)
|
|
|
111 |
{
|
1 |
efrain |
112 |
$content = '';
|
|
|
113 |
|
|
|
114 |
// Sets the login background image.
|
|
|
115 |
// Check login layout, only layout #1 has background image.
|
|
|
116 |
$loginlayout = theme_universe_get_setting('setloginlayout');
|
|
|
117 |
$loginlayoutimg = false;
|
|
|
118 |
|
|
|
119 |
if ($loginlayout == 1 || $loginlayout == 4 || $loginlayout == 5) {
|
|
|
120 |
$loginlayoutimg = true;
|
|
|
121 |
}
|
|
|
122 |
if ($loginlayout == 2 || $loginlayout == 3) {
|
|
|
123 |
$loginlayoutimg = false;
|
|
|
124 |
} else {
|
|
|
125 |
$loginlayoutimg = false;
|
|
|
126 |
}
|
|
|
127 |
|
|
|
128 |
$loginbackgroundimageurl = $theme->setting_file_url('loginbg', 'loginbg');
|
|
|
129 |
if ($loginlayout == 1) {
|
|
|
130 |
if (!empty($loginbackgroundimageurl)) {
|
|
|
131 |
$content .= 'body.path-login { ';
|
|
|
132 |
$content .= "background-image: url('$loginbackgroundimageurl')!important; background-size: cover!important;";
|
|
|
133 |
$content .= ' }';
|
|
|
134 |
}
|
|
|
135 |
}
|
|
|
136 |
|
|
|
137 |
$forcefwvideo = theme_universe_get_setting('forcefwvideo');
|
|
|
138 |
if ($forcefwvideo == 1) {
|
|
|
139 |
$content .= '.mediaplugin.mediaplugin_videojs div[style*="max-width"] {margin-left:auto;margin-right:auto;
|
|
|
140 |
width: 100%; max-width: 100% !important;}';
|
|
|
141 |
$content .= '.mediaplugin div {max-width:100%!important;}';
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
// Always return the background image with the scss when we have it.
|
|
|
145 |
return !empty($theme->settings->scss) ? $theme->settings->scss . ' ' . $content : $content;
|
|
|
146 |
}
|
|
|
147 |
|
|
|
148 |
/**
|
|
|
149 |
* Serves any files associated with the theme settings.
|
|
|
150 |
*
|
|
|
151 |
* @param stdClass $course
|
|
|
152 |
* @param stdClass $cm
|
|
|
153 |
* @param context $context
|
|
|
154 |
* @param string $filearea
|
|
|
155 |
* @param array $args
|
|
|
156 |
* @param bool $forcedownload
|
|
|
157 |
* @param array $options
|
|
|
158 |
* @return bool
|
|
|
159 |
*/
|
126 |
ariadna |
160 |
function theme_universe_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array())
|
|
|
161 |
{
|
1 |
efrain |
162 |
if ($context->contextlevel == CONTEXT_SYSTEM) {
|
|
|
163 |
$theme = theme_config::load('universe');
|
|
|
164 |
// By default, theme files must be cache-able by both browsers and proxies.
|
|
|
165 |
if (!array_key_exists('cacheability', $options)) {
|
|
|
166 |
$options['cacheability'] = 'public';
|
|
|
167 |
}
|
|
|
168 |
if ($filearea === 'hvp') {
|
|
|
169 |
return theme_universe_serve_hvp_css($args[1], $theme);
|
|
|
170 |
}
|
|
|
171 |
if ($filearea === 'favicon') {
|
|
|
172 |
return $theme->setting_file_serve('favicon', $args, $forcedownload, $options);
|
|
|
173 |
} else if ($filearea === 'logo') {
|
|
|
174 |
return $theme->setting_file_serve('logo', $args, $forcedownload, $options);
|
|
|
175 |
} else if ($filearea === 'loginbg') {
|
|
|
176 |
return $theme->setting_file_serve('loginbg', $args, $forcedownload, $options);
|
|
|
177 |
} else if ($filearea === 'customloginlogo') {
|
|
|
178 |
return $theme->setting_file_serve('customloginlogo', $args, $forcedownload, $options);
|
|
|
179 |
} else if ($filearea === 'customlogo') {
|
|
|
180 |
return $theme->setting_file_serve('customlogo', $args, $forcedownload, $options);
|
|
|
181 |
} else if ($filearea === 'customdmlogo') {
|
|
|
182 |
return $theme->setting_file_serve('customdmlogo', $args, $forcedownload, $options);
|
|
|
183 |
} else if ($filearea === 'customsidebarlogo') {
|
|
|
184 |
return $theme->setting_file_serve('customsidebarlogo', $args, $forcedownload, $options);
|
|
|
185 |
} else if ($filearea === 'customsidebardmlogo') {
|
|
|
186 |
return $theme->setting_file_serve('customsidebardmlogo', $args, $forcedownload, $options);
|
|
|
187 |
} else if ($filearea === 'fontfiles') {
|
|
|
188 |
return $theme->setting_file_serve('fontfiles', $args, $forcedownload, $options);
|
|
|
189 |
} else if ($filearea === 'universesettingsimgs') {
|
|
|
190 |
return $theme->setting_file_serve('universesettingsimgs', $args, $forcedownload, $options);
|
|
|
191 |
} else if (preg_match("/^block1slideimg[1-9][0-9]?$/", $filearea) !== false) {
|
|
|
192 |
return $theme->setting_file_serve($filearea, $args, $forcedownload, $options);
|
|
|
193 |
} else if (preg_match("/^block5itemimg[1-9][0-9]?$/", $filearea) !== false) {
|
|
|
194 |
return $theme->setting_file_serve($filearea, $args, $forcedownload, $options);
|
|
|
195 |
} else if ($filearea === 'block2videoposter') {
|
|
|
196 |
return $theme->setting_file_serve('block2videoposter', $args, $forcedownload, $options);
|
|
|
197 |
} else if ($filearea === 'block2img') {
|
|
|
198 |
return $theme->setting_file_serve('block2img', $args, $forcedownload, $options);
|
|
|
199 |
} else if ($filearea === 'block2videomp4') {
|
|
|
200 |
return $theme->setting_file_serve('block2videomp4', $args, $forcedownload, $options);
|
|
|
201 |
} else if ($filearea === 'block2videowebm') {
|
|
|
202 |
return $theme->setting_file_serve('block2videowebm', $args, $forcedownload, $options);
|
|
|
203 |
} else if ($filearea === 'footerbgimg') {
|
|
|
204 |
return $theme->setting_file_serve('footerbgimg', $args, $forcedownload, $options);
|
|
|
205 |
} else {
|
|
|
206 |
send_file_not_found();
|
|
|
207 |
}
|
|
|
208 |
}
|
|
|
209 |
}
|
|
|
210 |
|
|
|
211 |
/**
|
|
|
212 |
* Get the URL of files from theme settings.
|
|
|
213 |
*
|
|
|
214 |
* @param $setting
|
|
|
215 |
* @param $filearea
|
|
|
216 |
* @param $theme
|
|
|
217 |
* @return array|false|string|string[]|null
|
|
|
218 |
* @throws dml_exception
|
|
|
219 |
*/
|
126 |
ariadna |
220 |
function theme_universe_setting_file_url($setting, $filearea, $theme)
|
|
|
221 |
{
|
1 |
efrain |
222 |
global $CFG;
|
|
|
223 |
|
|
|
224 |
$component = 'theme_universe';
|
|
|
225 |
$itemid = 0;
|
|
|
226 |
$filepath = $theme->settings->$filearea;
|
|
|
227 |
|
|
|
228 |
if (empty($filepath)) {
|
|
|
229 |
return false;
|
|
|
230 |
}
|
|
|
231 |
$syscontext = context_system::instance();
|
|
|
232 |
|
|
|
233 |
$url = moodle_url::make_file_url("$CFG->wwwroot/pluginfile.php", "/$syscontext->id/$component/$filearea/$itemid" . $filepath);
|
|
|
234 |
|
|
|
235 |
// Now this is tricky because the we can not hardcode http or https here, lets use the relative link.
|
|
|
236 |
// Note: unfortunately moodle_url does not support //urls yet.
|
|
|
237 |
|
|
|
238 |
$url = preg_replace('|^https?://|i', '//', $url->out(false));
|
|
|
239 |
|
|
|
240 |
return $url;
|
|
|
241 |
}
|
|
|
242 |
|
|
|
243 |
/**
|
|
|
244 |
* Returns the main SCSS content.
|
|
|
245 |
*
|
|
|
246 |
* @param theme_config $theme The theme config object.
|
|
|
247 |
* @return string
|
|
|
248 |
*/
|
126 |
ariadna |
249 |
function theme_universe_get_main_scss_content($theme)
|
|
|
250 |
{
|
1 |
efrain |
251 |
global $CFG;
|
|
|
252 |
|
|
|
253 |
$scss = '';
|
|
|
254 |
$filename = !empty($theme->settings->preset) ? $theme->settings->preset : null;
|
|
|
255 |
$fs = get_file_storage();
|
|
|
256 |
|
|
|
257 |
$context = context_system::instance();
|
|
|
258 |
if ($filename == 'default.scss') {
|
|
|
259 |
$scss .= file_get_contents($CFG->dirroot . '/theme/universe/scss/preset/default.scss');
|
|
|
260 |
} else if ($filename == 'plain.scss') {
|
|
|
261 |
$scss .= file_get_contents($CFG->dirroot . '/theme/universe/scss/preset/plain.scss');
|
|
|
262 |
} else if ($filename && ($presetfile = $fs->get_file($context->id, 'theme_universe', 'preset', 0, '/', $filename))) {
|
|
|
263 |
$scss .= $presetfile->get_content();
|
|
|
264 |
} else {
|
|
|
265 |
// Safety fallback - maybe new installs etc.
|
|
|
266 |
$scss .= file_get_contents($CFG->dirroot . '/theme/universe/scss/preset/default.scss');
|
|
|
267 |
}
|
|
|
268 |
|
|
|
269 |
return $scss;
|
|
|
270 |
}
|
|
|
271 |
|
|
|
272 |
/**
|
|
|
273 |
* Get compiled css.
|
|
|
274 |
*
|
|
|
275 |
* @return string compiled css
|
|
|
276 |
*/
|
126 |
ariadna |
277 |
function theme_universe_get_precompiled_css()
|
|
|
278 |
{
|
1 |
efrain |
279 |
global $CFG;
|
|
|
280 |
return file_get_contents($CFG->dirroot . '/theme/universe/style/moodle.css');
|
|
|
281 |
}
|
|
|
282 |
|
|
|
283 |
/**
|
|
|
284 |
* Get SCSS to prepend.
|
|
|
285 |
*
|
|
|
286 |
* @param theme_config $theme The theme config object.
|
|
|
287 |
* @return array
|
|
|
288 |
*/
|
126 |
ariadna |
289 |
function theme_universe_get_pre_scss($theme)
|
|
|
290 |
{
|
1 |
efrain |
291 |
global $CFG;
|
|
|
292 |
|
|
|
293 |
$scss = '';
|
|
|
294 |
$configurable = [
|
|
|
295 |
// Config key => [variableName, ...].
|
|
|
296 |
'colorloginbgtext' => ['colorloginbgtext'],
|
|
|
297 |
// Blocks.
|
|
|
298 |
'block1sliderwrapperbg' => ['block1-wrapper-bg'],
|
|
|
299 |
'block2wrapperbg' => ['block2-wrapper-bg'],
|
|
|
300 |
'block3wrapperbg' => ['block3-wrapper-bg'],
|
|
|
301 |
'block4sliderwrapperbg' => ['block4-wrapper-bg'],
|
|
|
302 |
// Customization.
|
|
|
303 |
'fontweightheadings' => ['headings-font-weight'],
|
|
|
304 |
'fontbody' => ['font-family-base'],
|
|
|
305 |
'fontweightregular' => ['font-weight-normal'],
|
|
|
306 |
'fontweightmedium' => ['font-weight-medium'],
|
|
|
307 |
'fontweightbold' => ['font-weight-bold'],
|
|
|
308 |
'fontheadings' => ['fontheadings'],
|
|
|
309 |
// 'coursedescwidth' => ['coursedescwidth'],
|
|
|
310 |
// 'incoursedescwidth' => ['incoursedescwidth'],
|
|
|
311 |
// Text.
|
|
|
312 |
'colorbody' => ['body-color'],
|
|
|
313 |
'colorbodysecondary' => ['body-color-secondary'],
|
|
|
314 |
'colorbodylight' => ['body-color-light'],
|
|
|
315 |
'colorlink' => ['link-color'],
|
|
|
316 |
'colorlinkhover' => ['link-color-hover'],
|
|
|
317 |
// Grays.
|
|
|
318 |
'white' => ['white'],
|
|
|
319 |
'black' => ['black'],
|
|
|
320 |
'colorgray100' => ['gray-100'],
|
|
|
321 |
'colorgray200' => ['gray-200'],
|
|
|
322 |
'colorgray300' => ['gray-300'],
|
|
|
323 |
'colorgray400' => ['gray-400'],
|
|
|
324 |
'colorgray500' => ['gray-500'],
|
|
|
325 |
'colorgray600' => ['gray-600'],
|
|
|
326 |
'colorgray700' => ['gray-700'],
|
|
|
327 |
'colorgray800' => ['gray-800'],
|
|
|
328 |
'colorgray900' => ['gray-900'],
|
|
|
329 |
// Primary.
|
|
|
330 |
'colorprimary100' => ['primary-color-100'],
|
|
|
331 |
'colorprimary200' => ['primary-color-200'],
|
|
|
332 |
'colorprimary300' => ['primary-color-300'],
|
|
|
333 |
'colorprimary400' => ['primary-color-400'],
|
|
|
334 |
'colorprimary500' => ['primary-color-500'],
|
|
|
335 |
'colorprimary600' => ['primary-color-600'],
|
|
|
336 |
'colorprimary700' => ['primary-color-700'],
|
|
|
337 |
'colorprimary800' => ['primary-color-800'],
|
|
|
338 |
'colorprimary900' => ['primary-color-900'],
|
|
|
339 |
// Others.
|
|
|
340 |
'colorbodybg' => ['body-bg'],
|
|
|
341 |
'colorborder' => ['border-color'],
|
|
|
342 |
//'colorcoursecardmask' => ['course-card-shadow-color'],
|
|
|
343 |
// Topbar.
|
|
|
344 |
'topbarheight' => ['navbar-height'],
|
|
|
345 |
'colortopbarbg1' => ['topbar-bg'],
|
|
|
346 |
'colortopbarbg2' => ['topbar-bg-2'],
|
|
|
347 |
'dmcolortopbarbg1' => ['topbar-bg'],
|
|
|
348 |
'dmcolortopbarbg2' => ['dm-topbar-bg-2'],
|
|
|
349 |
'colortopbartext' => ['dm-topbar-text'],
|
|
|
350 |
'colortopbarlink' => ['topbar-link'],
|
|
|
351 |
'colortopbarlinkhover' => ['topbar-link-hover'],
|
|
|
352 |
'colortopbarbtntext' => ['topbar-btn-text'],
|
|
|
353 |
'colortopbarbtnhover' => ['topbar-btn-hover'],
|
|
|
354 |
'colortopbarbtnhovertext' => ['topbar-btn-hover-text'],
|
|
|
355 |
// Buttons.
|
|
|
356 |
'btnborderradius' => ['btn-border-radius'],
|
|
|
357 |
// Sidebar.
|
|
|
358 |
'colordrawerbg' => ['drawer-bg'],
|
|
|
359 |
'colordrawertext' => ['drawer-text'],
|
|
|
360 |
'colordrawernavcontainer' => ['drawer-nav-container'],
|
|
|
361 |
'colordrawernavbtntext' => ['drawer-nav-btn-text'],
|
|
|
362 |
'colordrawernavbtnicon' => ['drawer-nav-btn-icon'],
|
|
|
363 |
'colordrawernavbtntexth' => ['drawer-nav-btn-text-hover'],
|
|
|
364 |
'colordrawernavbtniconh' => ['drawer-nav-btn-icon-hover'],
|
|
|
365 |
'colordrawernavbtnbgh' => ['drawer-nav-btn-bg-hover'],
|
|
|
366 |
'colordrawernavbtntextlight' => ['drawer-nav-btn-text-light'],
|
|
|
367 |
'colordrawerscrollbar' => ['drawer-scroll-bg-track'],
|
|
|
368 |
'colordrawerlink' => ['drawer-link'],
|
|
|
369 |
'colordrawerlinkh' => ['drawer-link-h'],
|
|
|
370 |
'colordrawernavboxbg' => ['drawer-nav-box-bg'],
|
|
|
371 |
'colordrawernavbtnicon' => ['drawer-nav-btn-icon'],
|
|
|
372 |
// Footer.
|
|
|
373 |
'colorfooterbg' => ['footer-bg'],
|
|
|
374 |
'colorfooterborder' => ['footer-border'],
|
|
|
375 |
'colorfootertext' => ['footer-text-color'],
|
|
|
376 |
'colorfooterlink' => ['footer-link-color'],
|
|
|
377 |
'colorfooterlinkhover' => ['footer-link-color-hover'],
|
|
|
378 |
'colorcoursecardmask' => ['course-card-mask-color'],
|
|
|
379 |
'showcolorcoursecardmask' => ['showcolorcoursecardmask'],
|
|
|
380 |
// Login.
|
|
|
381 |
'loginbgcolor' => ['login-bgcolor'],
|
|
|
382 |
// Icon Colors.
|
|
|
383 |
'iconadministration' => ['icon-color-administraion'],
|
|
|
384 |
'iconassessment' => ['icon-color-assessment'],
|
|
|
385 |
'iconcolleboration' => ['icon-color-collaboration'],
|
|
|
386 |
'iconcommunication' => ['icon-color-communication'],
|
|
|
387 |
'iconcontent' => ['icon-color-content'],
|
|
|
388 |
'iconinterface' => ['icon-color-interface']
|
|
|
389 |
];
|
|
|
390 |
|
|
|
391 |
// Prepend variables first.
|
|
|
392 |
foreach ($configurable as $configkey => $targets) {
|
|
|
393 |
$value = isset($theme->settings->{$configkey}) ? $theme->settings->{$configkey} : null;
|
|
|
394 |
if (empty($value)) {
|
|
|
395 |
continue;
|
|
|
396 |
}
|
|
|
397 |
array_map(function ($target) use (&$scss, $value) {
|
|
|
398 |
$scss .= '$' . $target . ': ' . $value . ";\n";
|
|
|
399 |
}, (array) $targets);
|
|
|
400 |
}
|
|
|
401 |
|
|
|
402 |
// Prepend pre-scss.
|
|
|
403 |
if (!empty($theme->settings->scsspre)) {
|
|
|
404 |
$scss .= $theme->settings->scsspre;
|
|
|
405 |
}
|
|
|
406 |
|
|
|
407 |
return $scss;
|
|
|
408 |
}
|
|
|
409 |
|
|
|
410 |
/**
|
|
|
411 |
* Build the guest access hint HTML code.
|
|
|
412 |
*
|
|
|
413 |
* @param int $courseid The course ID.
|
|
|
414 |
* @return string.
|
|
|
415 |
*/
|
126 |
ariadna |
416 |
function theme_universe_get_course_guest_access_hint($courseid)
|
|
|
417 |
{
|
1 |
efrain |
418 |
global $CFG;
|
|
|
419 |
require_once($CFG->dirroot . '/enrol/self/lib.php');
|
|
|
420 |
|
|
|
421 |
$html = '';
|
|
|
422 |
$instances = enrol_get_instances($courseid, true);
|
|
|
423 |
$plugins = enrol_get_plugins(true);
|
|
|
424 |
foreach ($instances as $instance) {
|
|
|
425 |
if (!isset($plugins[$instance->enrol])) {
|
|
|
426 |
continue;
|
|
|
427 |
}
|
|
|
428 |
$plugin = $plugins[$instance->enrol];
|
|
|
429 |
if ($plugin->show_enrolme_link($instance)) {
|
|
|
430 |
$html = html_writer::tag('div', get_string(
|
|
|
431 |
'showhintcourseguestaccesslink',
|
|
|
432 |
'theme_universe',
|
|
|
433 |
array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
|
|
|
434 |
));
|
|
|
435 |
break;
|
|
|
436 |
}
|
|
|
437 |
}
|
|
|
438 |
|
|
|
439 |
return $html;
|
|
|
440 |
}
|
|
|
441 |
|
|
|
442 |
/**
|
|
|
443 |
* Build the course page information banners HTML code.
|
|
|
444 |
* This function evaluates and composes all information banners which may appear on a course page below the full header.
|
|
|
445 |
*
|
|
|
446 |
* @return string.
|
|
|
447 |
*/
|
126 |
ariadna |
448 |
function theme_universe_get_course_information_banners()
|
|
|
449 |
{
|
1 |
efrain |
450 |
global $CFG, $COURSE, $PAGE, $USER, $OUTPUT;
|
|
|
451 |
|
|
|
452 |
// Require user library.
|
|
|
453 |
require_once($CFG->dirroot . '/user/lib.php');
|
|
|
454 |
|
|
|
455 |
// Initialize HTML code.
|
|
|
456 |
$html = '';
|
|
|
457 |
|
|
|
458 |
// Check if user is admin, teacher or editing teacher.
|
|
|
459 |
if (
|
|
|
460 |
user_has_role_assignment($USER->id, '1') ||
|
|
|
461 |
user_has_role_assignment($USER->id, '2') ||
|
|
|
462 |
user_has_role_assignment($USER->id, '3') ||
|
|
|
463 |
user_has_role_assignment($USER->id, '4')
|
|
|
464 |
) {
|
|
|
465 |
$allowtoshowhint = true;
|
|
|
466 |
} else {
|
|
|
467 |
$allowtoshowhint = false;
|
|
|
468 |
}
|
|
|
469 |
|
|
|
470 |
// If the setting showhintcoursehidden is set and the visibility of the course is hidden and
|
|
|
471 |
// a hint for the visibility will be shown.
|
|
|
472 |
if (
|
|
|
473 |
get_config('theme_universe', 'showhintcoursehidden') == 1
|
|
|
474 |
&& $allowtoshowhint == true
|
|
|
475 |
&& $PAGE->has_set_url()
|
|
|
476 |
&& $PAGE->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)
|
|
|
477 |
&& $COURSE->visible == false
|
|
|
478 |
) {
|
|
|
479 |
|
|
|
480 |
// Prepare template context.
|
|
|
481 |
$templatecontext = array('courseid' => $COURSE->id);
|
|
|
482 |
|
|
|
483 |
// If the user has the capability to change the course settings, an additional link to the course settings is shown.
|
|
|
484 |
if (has_capability('moodle/course:update', context_course::instance($COURSE->id))) {
|
|
|
485 |
$templatecontext['showcoursesettingslink'] = true;
|
|
|
486 |
} else {
|
|
|
487 |
$templatecontext['showcoursesettingslink'] = false;
|
|
|
488 |
}
|
|
|
489 |
|
|
|
490 |
// Render template and add it to HTML code.
|
|
|
491 |
$html .= $OUTPUT->render_from_template('theme_universe/course-hint-hidden', $templatecontext);
|
|
|
492 |
}
|
|
|
493 |
|
|
|
494 |
// If the setting showhintcourseguestaccess is set and the user is accessing the course with guest access,
|
|
|
495 |
// a hint for users is shown.
|
|
|
496 |
// We also check that the user did not switch the role. This is a special case for roles that can fully access the course
|
|
|
497 |
// without being enrolled. A role switch would show the guest access hint additionally in that case and this is not
|
|
|
498 |
// intended.
|
|
|
499 |
if (
|
|
|
500 |
get_config('theme_universe', 'showhintcourseguestaccess') == 1
|
|
|
501 |
&& is_guest(\context_course::instance($COURSE->id), $USER->id)
|
|
|
502 |
&& $PAGE->has_set_url()
|
|
|
503 |
&& $PAGE->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)
|
|
|
504 |
&& !is_role_switched($COURSE->id)
|
|
|
505 |
) {
|
|
|
506 |
|
|
|
507 |
// Require self enrolment library.
|
|
|
508 |
require_once($CFG->dirroot . '/enrol/self/lib.php');
|
|
|
509 |
|
|
|
510 |
// Prepare template context.
|
|
|
511 |
$templatecontext = array(
|
|
|
512 |
'courseid' => $COURSE->id,
|
|
|
513 |
'role' => role_get_name(get_guest_role())
|
|
|
514 |
);
|
|
|
515 |
|
|
|
516 |
// Search for an available self enrolment link in this course.
|
|
|
517 |
$templatecontext['showselfenrollink'] = false;
|
|
|
518 |
$instances = enrol_get_instances($COURSE->id, true);
|
|
|
519 |
$plugins = enrol_get_plugins(true);
|
|
|
520 |
foreach ($instances as $instance) {
|
|
|
521 |
// If the enrolment plugin isn't enabled currently, skip it.
|
|
|
522 |
if (!isset($plugins[$instance->enrol])) {
|
|
|
523 |
continue;
|
|
|
524 |
}
|
|
|
525 |
|
|
|
526 |
// Remember the enrolment plugin.
|
|
|
527 |
$plugin = $plugins[$instance->enrol];
|
|
|
528 |
|
|
|
529 |
// If there is a self enrolment link.
|
|
|
530 |
if ($plugin->show_enrolme_link($instance)) {
|
|
|
531 |
$templatecontext['showselfenrollink'] = true;
|
|
|
532 |
break;
|
|
|
533 |
}
|
|
|
534 |
}
|
|
|
535 |
|
|
|
536 |
// Render template and add it to HTML code.
|
|
|
537 |
$html .= $OUTPUT->render_from_template('theme_universe/course-hint-guestaccess', $templatecontext);
|
|
|
538 |
}
|
|
|
539 |
|
|
|
540 |
// If the setting showhintcourseselfenrol is set, a hint for users is shown that the course allows unrestricted self
|
|
|
541 |
// enrolment. This hint is only shown if the course is visible, the self enrolment is visible and if the user has the
|
|
|
542 |
// capability "theme/universe:viewhintcourseselfenrol".
|
|
|
543 |
if (
|
|
|
544 |
get_config('theme_universe', 'showhintcourseselfenrol') == 1
|
|
|
545 |
&& $allowtoshowhint == true
|
|
|
546 |
&& $PAGE->has_set_url()
|
|
|
547 |
&& $PAGE->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)
|
|
|
548 |
&& $COURSE->visible == true
|
|
|
549 |
) {
|
|
|
550 |
|
|
|
551 |
// Get the active enrol instances for this course.
|
|
|
552 |
$enrolinstances = enrol_get_instances($COURSE->id, true);
|
|
|
553 |
|
|
|
554 |
// Prepare to remember when self enrolment is / will be possible.
|
|
|
555 |
$selfenrolmentpossiblecurrently = false;
|
|
|
556 |
$selfenrolmentpossiblefuture = false;
|
|
|
557 |
foreach ($enrolinstances as $instance) {
|
|
|
558 |
// Check if unrestricted self enrolment is possible currently or in the future.
|
|
|
559 |
$now = (new \DateTime("now", \core_date::get_server_timezone_object()))->getTimestamp();
|
|
|
560 |
if (
|
|
|
561 |
$instance->enrol == 'self' && empty($instance->password) && $instance->customint6 == 1 &&
|
|
|
562 |
(empty($instance->enrolenddate) || $instance->enrolenddate > $now)
|
|
|
563 |
) {
|
|
|
564 |
|
|
|
565 |
// Build enrol instance object with all necessary information for rendering the note later.
|
|
|
566 |
$instanceobject = new stdClass();
|
|
|
567 |
|
|
|
568 |
// Remember instance name.
|
|
|
569 |
if (empty($instance->name)) {
|
|
|
570 |
$instanceobject->name = get_string('pluginname', 'enrol_self') .
|
|
|
571 |
" (" . get_string('defaultcoursestudent', 'core') . ")";
|
|
|
572 |
} else {
|
|
|
573 |
$instanceobject->name = $instance->name;
|
|
|
574 |
}
|
|
|
575 |
|
|
|
576 |
// Remember type of unrestrictedness.
|
|
|
577 |
if (empty($instance->enrolenddate) && empty($instance->enrolstartdate)) {
|
|
|
578 |
$instanceobject->unrestrictedness = 'unlimited';
|
|
|
579 |
$selfenrolmentpossiblecurrently = true;
|
|
|
580 |
} else if (
|
|
|
581 |
empty($instance->enrolstartdate) &&
|
|
|
582 |
!empty($instance->enrolenddate) && $instance->enrolenddate > $now
|
|
|
583 |
) {
|
|
|
584 |
$instanceobject->unrestrictedness = 'until';
|
|
|
585 |
$selfenrolmentpossiblecurrently = true;
|
|
|
586 |
} else if (
|
|
|
587 |
empty($instance->enrolenddate) &&
|
|
|
588 |
!empty($instance->enrolstartdate) && $instance->enrolstartdate > $now
|
|
|
589 |
) {
|
|
|
590 |
$instanceobject->unrestrictedness = 'from';
|
|
|
591 |
$selfenrolmentpossiblefuture = true;
|
|
|
592 |
} else if (
|
|
|
593 |
empty($instance->enrolenddate) &&
|
|
|
594 |
!empty($instance->enrolstartdate) && $instance->enrolstartdate <= $now
|
|
|
595 |
) {
|
|
|
596 |
$instanceobject->unrestrictedness = 'since';
|
|
|
597 |
$selfenrolmentpossiblecurrently = true;
|
|
|
598 |
} else if (
|
|
|
599 |
!empty($instance->enrolstartdate) && $instance->enrolstartdate > $now &&
|
|
|
600 |
!empty($instance->enrolenddate) && $instance->enrolenddate > $now
|
|
|
601 |
) {
|
|
|
602 |
$instanceobject->unrestrictedness = 'fromuntil';
|
|
|
603 |
$selfenrolmentpossiblefuture = true;
|
|
|
604 |
} else if (
|
|
|
605 |
!empty($instance->enrolstartdate) && $instance->enrolstartdate <= $now &&
|
|
|
606 |
!empty($instance->enrolenddate) && $instance->enrolenddate > $now
|
|
|
607 |
) {
|
|
|
608 |
$instanceobject->unrestrictedness = 'sinceuntil';
|
|
|
609 |
$selfenrolmentpossiblecurrently = true;
|
|
|
610 |
} else {
|
|
|
611 |
// This should not happen, thus continue to next instance.
|
|
|
612 |
continue;
|
|
|
613 |
}
|
|
|
614 |
|
|
|
615 |
// Remember enrol start date.
|
|
|
616 |
if (!empty($instance->enrolstartdate)) {
|
|
|
617 |
$instanceobject->startdate = $instance->enrolstartdate;
|
|
|
618 |
} else {
|
|
|
619 |
$instanceobject->startdate = null;
|
|
|
620 |
}
|
|
|
621 |
|
|
|
622 |
// Remember enrol end date.
|
|
|
623 |
if (!empty($instance->enrolenddate)) {
|
|
|
624 |
$instanceobject->enddate = $instance->enrolenddate;
|
|
|
625 |
} else {
|
|
|
626 |
$instanceobject->enddate = null;
|
|
|
627 |
}
|
|
|
628 |
|
|
|
629 |
// Remember this instance.
|
|
|
630 |
$selfenrolinstances[$instance->id] = $instanceobject;
|
|
|
631 |
}
|
|
|
632 |
}
|
|
|
633 |
|
|
|
634 |
// If there is at least one unrestricted enrolment instance,
|
|
|
635 |
// show the hint with information about each unrestricted active self enrolment in the course.
|
|
|
636 |
if (
|
|
|
637 |
!empty($selfenrolinstances) &&
|
|
|
638 |
($selfenrolmentpossiblecurrently == true || $selfenrolmentpossiblefuture == true)
|
|
|
639 |
) {
|
|
|
640 |
|
|
|
641 |
// Prepare template context.
|
|
|
642 |
$templatecontext = array();
|
|
|
643 |
|
|
|
644 |
// Add the start of the hint t the template context
|
|
|
645 |
// depending on the fact if enrolment is already possible currently or will be in the future.
|
|
|
646 |
if ($selfenrolmentpossiblecurrently == true) {
|
|
|
647 |
$templatecontext['selfenrolhintstart'] = get_string('showhintcourseselfenrolstartcurrently', 'theme_universe');
|
|
|
648 |
} else if ($selfenrolmentpossiblefuture == true) {
|
|
|
649 |
$templatecontext['selfenrolhintstart'] = get_string('showhintcourseselfenrolstartfuture', 'theme_universe');
|
|
|
650 |
}
|
|
|
651 |
|
|
|
652 |
// Iterate over all enrolment instances to output the details.
|
|
|
653 |
foreach ($selfenrolinstances as $selfenrolinstanceid => $selfenrolinstanceobject) {
|
|
|
654 |
// If the user has the capability to config self enrolments, enrich the instance name with the settings link.
|
|
|
655 |
if (has_capability('enrol/self:config', \context_course::instance($COURSE->id))) {
|
|
|
656 |
$url = new moodle_url('/enrol/editinstance.php', array(
|
|
|
657 |
'courseid' => $COURSE->id,
|
126 |
ariadna |
658 |
'id' => $selfenrolinstanceid,
|
|
|
659 |
'type' => 'self'
|
1 |
efrain |
660 |
));
|
|
|
661 |
$selfenrolinstanceobject->name = html_writer::link($url, $selfenrolinstanceobject->name);
|
|
|
662 |
}
|
|
|
663 |
|
|
|
664 |
// Add the enrolment instance information to the template context depending on the instance configuration.
|
|
|
665 |
if ($selfenrolinstanceobject->unrestrictedness == 'unlimited') {
|
|
|
666 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
667 |
'showhintcourseselfenrolunlimited',
|
|
|
668 |
'theme_universe',
|
|
|
669 |
array('name' => $selfenrolinstanceobject->name)
|
|
|
670 |
);
|
|
|
671 |
} else if ($selfenrolinstanceobject->unrestrictedness == 'until') {
|
|
|
672 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
673 |
'showhintcourseselfenroluntil',
|
|
|
674 |
'theme_universe',
|
|
|
675 |
array(
|
|
|
676 |
'name' => $selfenrolinstanceobject->name,
|
|
|
677 |
'until' => userdate($selfenrolinstanceobject->enddate)
|
|
|
678 |
)
|
|
|
679 |
);
|
|
|
680 |
} else if ($selfenrolinstanceobject->unrestrictedness == 'from') {
|
|
|
681 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
682 |
'showhintcourseselfenrolfrom',
|
|
|
683 |
'theme_universe',
|
|
|
684 |
array(
|
|
|
685 |
'name' => $selfenrolinstanceobject->name,
|
|
|
686 |
'from' => userdate($selfenrolinstanceobject->startdate)
|
|
|
687 |
)
|
|
|
688 |
);
|
|
|
689 |
} else if ($selfenrolinstanceobject->unrestrictedness == 'since') {
|
|
|
690 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
691 |
'showhintcourseselfenrolsince',
|
|
|
692 |
'theme_universe',
|
|
|
693 |
array(
|
|
|
694 |
'name' => $selfenrolinstanceobject->name,
|
|
|
695 |
'since' => userdate($selfenrolinstanceobject->startdate)
|
|
|
696 |
)
|
|
|
697 |
);
|
|
|
698 |
} else if ($selfenrolinstanceobject->unrestrictedness == 'fromuntil') {
|
|
|
699 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
700 |
'showhintcourseselfenrolfromuntil',
|
|
|
701 |
'theme_universe',
|
|
|
702 |
array(
|
|
|
703 |
'name' => $selfenrolinstanceobject->name,
|
|
|
704 |
'until' => userdate($selfenrolinstanceobject->enddate),
|
|
|
705 |
'from' => userdate($selfenrolinstanceobject->startdate)
|
|
|
706 |
)
|
|
|
707 |
);
|
|
|
708 |
} else if ($selfenrolinstanceobject->unrestrictedness == 'sinceuntil') {
|
|
|
709 |
$templatecontext['selfenrolinstances'][] = get_string(
|
|
|
710 |
'showhintcourseselfenrolsinceuntil',
|
|
|
711 |
'theme_universe',
|
|
|
712 |
array(
|
|
|
713 |
'name' => $selfenrolinstanceobject->name,
|
|
|
714 |
'until' => userdate($selfenrolinstanceobject->enddate),
|
|
|
715 |
'since' => userdate($selfenrolinstanceobject->startdate)
|
|
|
716 |
)
|
|
|
717 |
);
|
|
|
718 |
}
|
|
|
719 |
}
|
|
|
720 |
|
|
|
721 |
// If the user has the capability to config self enrolments, add the call for action to the template context.
|
|
|
722 |
if (has_capability('enrol/self:config', \context_course::instance($COURSE->id))) {
|
|
|
723 |
$templatecontext['calltoaction'] = true;
|
|
|
724 |
} else {
|
|
|
725 |
$templatecontext['calltoaction'] = false;
|
|
|
726 |
}
|
|
|
727 |
|
|
|
728 |
// Render template and add it to HTML code.
|
|
|
729 |
$html .= $OUTPUT->render_from_template('theme_universe/course-hint-selfenrol', $templatecontext);
|
|
|
730 |
}
|
|
|
731 |
}
|
|
|
732 |
|
|
|
733 |
// If the setting showswitchedroleincourse is set and the user has switched his role,
|
|
|
734 |
// a hint for the role switch will be shown.
|
|
|
735 |
if (
|
|
|
736 |
get_config('theme_universe', 'showswitchedroleincourse') == 1
|
|
|
737 |
&& is_role_switched($COURSE->id)
|
|
|
738 |
) {
|
|
|
739 |
|
|
|
740 |
// Get the role name switched to.
|
|
|
741 |
$opts = \user_get_user_navigation_info($USER, $PAGE);
|
|
|
742 |
$role = $opts->metadata['rolename'];
|
|
|
743 |
|
|
|
744 |
// Get the URL to switch back (normal role).
|
|
|
745 |
$url = new moodle_url(
|
|
|
746 |
'/course/switchrole.php',
|
|
|
747 |
array(
|
|
|
748 |
'id' => $COURSE->id,
|
|
|
749 |
'sesskey' => sesskey(),
|
|
|
750 |
'switchrole' => 0,
|
|
|
751 |
'returnurl' => $PAGE->url->out_as_local_url(false)
|
|
|
752 |
)
|
|
|
753 |
);
|
|
|
754 |
|
|
|
755 |
// Prepare template context.
|
|
|
756 |
$templatecontext = array(
|
|
|
757 |
'role' => $role,
|
|
|
758 |
'url' => $url->out()
|
|
|
759 |
);
|
|
|
760 |
|
|
|
761 |
// Render template and add it to HTML code.
|
|
|
762 |
$html .= $OUTPUT->render_from_template('theme_universe/course-hint-switchedrole', $templatecontext);
|
|
|
763 |
}
|
|
|
764 |
|
|
|
765 |
// Return HTML code.
|
|
|
766 |
return $html;
|
|
|
767 |
}
|
|
|
768 |
|
|
|
769 |
/**
|
|
|
770 |
* Serves the H5P Custom CSS.
|
|
|
771 |
*
|
|
|
772 |
* @param string $filename The filename.
|
|
|
773 |
* @param theme_config $theme The theme config object.
|
|
|
774 |
*
|
|
|
775 |
* @throws dml_exception
|
|
|
776 |
*/
|
126 |
ariadna |
777 |
function theme_universe_serve_hvp_css($filename, $theme)
|
|
|
778 |
{
|
1 |
efrain |
779 |
global $CFG, $PAGE;
|
|
|
780 |
|
|
|
781 |
require_once($CFG->dirroot . '/lib/configonlylib.php'); // For min_enable_zlib_compression.
|
|
|
782 |
|
|
|
783 |
$PAGE->set_context(context_system::instance());
|
|
|
784 |
$themename = $theme->name;
|
|
|
785 |
|
|
|
786 |
$settings = new \theme_universe\util\theme_settings();
|
|
|
787 |
$content = $settings->hvpcss;
|
|
|
788 |
|
|
|
789 |
$md5content = md5($content);
|
|
|
790 |
$md5stored = get_config('theme_universe', 'hvpccssmd5');
|
|
|
791 |
if ((empty($md5stored)) || ($md5stored != $md5content)) {
|
|
|
792 |
// Content changed, so the last modified time needs to change.
|
|
|
793 |
set_config('hvpccssmd5', $md5content, $themename);
|
|
|
794 |
$lastmodified = time();
|
|
|
795 |
set_config('hvpccsslm', $lastmodified, $themename);
|
|
|
796 |
} else {
|
|
|
797 |
$lastmodified = get_config($themename, 'hvpccsslm');
|
|
|
798 |
if (empty($lastmodified)) {
|
|
|
799 |
$lastmodified = time();
|
|
|
800 |
}
|
|
|
801 |
}
|
|
|
802 |
|
|
|
803 |
// Sixty days only - the revision may get incremented quite often.
|
|
|
804 |
$lifetime = 60 * 60 * 24 * 60;
|
|
|
805 |
|
|
|
806 |
header('HTTP/1.1 200 OK');
|
|
|
807 |
|
|
|
808 |
header('Etag: "' . $md5content . '"');
|
|
|
809 |
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
|
810 |
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT');
|
|
|
811 |
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
|
|
|
812 |
header('Pragma: ');
|
|
|
813 |
header('Cache-Control: public, max-age=' . $lifetime);
|
|
|
814 |
header('Accept-Ranges: none');
|
|
|
815 |
header('Content-Type: text/css; charset=utf-8');
|
|
|
816 |
if (!min_enable_zlib_compression()) {
|
|
|
817 |
header('Content-Length: ' . strlen($content));
|
|
|
818 |
}
|
|
|
819 |
|
|
|
820 |
echo $content;
|
|
|
821 |
|
|
|
822 |
die;
|
|
|
823 |
}
|
|
|
824 |
|
|
|
825 |
/**
|
|
|
826 |
* Return the files from the additionalresources file area as templatecontext structure.
|
|
|
827 |
* It was designed to compose the files for the settings-additionalresources-filelist.mustache template.
|
|
|
828 |
* This function always loads the files from the filearea which is not really performant.
|
|
|
829 |
* Thus, you have to take care where and how often you use it (or add some caching).
|
|
|
830 |
*
|
|
|
831 |
* @return array|null
|
|
|
832 |
* @throws coding_exception
|
|
|
833 |
* @throws dml_exception
|
|
|
834 |
*/
|
126 |
ariadna |
835 |
function theme_universe_get_additionalresources_templatecontext()
|
|
|
836 |
{
|
1 |
efrain |
837 |
global $OUTPUT;
|
|
|
838 |
|
|
|
839 |
// Static variable to remember the files for subsequent calls of this function.
|
|
|
840 |
static $filesforcontext = null;
|
|
|
841 |
|
|
|
842 |
if ($filesforcontext == null) {
|
|
|
843 |
// Get the system context.
|
|
|
844 |
$systemcontext = \context_system::instance();
|
|
|
845 |
|
|
|
846 |
// Get filearea.
|
|
|
847 |
$fs = get_file_storage();
|
|
|
848 |
|
|
|
849 |
// Get all files from filearea.
|
|
|
850 |
$files = $fs->get_area_files($systemcontext->id, 'theme_universe', 'additionalresources', false, 'itemid', false);
|
|
|
851 |
|
|
|
852 |
// Iterate over the files and fill the templatecontext of the file list.
|
|
|
853 |
$filesforcontext = [];
|
|
|
854 |
foreach ($files as $af) {
|
126 |
ariadna |
855 |
$urlpersistent = new moodle_url('/pluginfile.php/1/theme_universe/additionalresources/0/' . $af->get_filename());
|
|
|
856 |
$urlrevisioned = new moodle_url('/pluginfile.php/1/theme_universe/additionalresources/' . theme_get_revision() .
|
|
|
857 |
'/' . $af->get_filename());
|
|
|
858 |
$filesforcontext[] = [
|
|
|
859 |
'filename' => $af->get_filename(),
|
|
|
860 |
'filetype' => $af->get_mimetype(),
|
|
|
861 |
'filesize' => display_size($af->get_filesize()),
|
|
|
862 |
'fileicon' => $OUTPUT->image_icon(file_file_icon($af), get_mimetype_description($af)),
|
|
|
863 |
'fileurlpersistent' => $urlpersistent->out(),
|
|
|
864 |
'fileurlrevisioned' => $urlrevisioned->out(),
|
|
|
865 |
];
|
1 |
efrain |
866 |
}
|
|
|
867 |
}
|
|
|
868 |
|
|
|
869 |
return $filesforcontext;
|
|
|
870 |
}
|
|
|
871 |
|
|
|
872 |
/**
|
|
|
873 |
* Return the files from the customfonts file area as templatecontext structure.
|
|
|
874 |
* It was designed to compose the files for the settings-customfonts-filelist.mustache template.
|
|
|
875 |
* This function always loads the files from the filearea which is not really performant.
|
|
|
876 |
* Thus, you have to take care where and how often you use it (or add some caching).
|
|
|
877 |
*
|
|
|
878 |
* @return array|null
|
|
|
879 |
* @throws coding_exception
|
|
|
880 |
* @throws dml_exception
|
|
|
881 |
* Credits: Boost_Union
|
|
|
882 |
*/
|
126 |
ariadna |
883 |
function theme_universe_get_customfonts_templatecontext()
|
|
|
884 |
{
|
1 |
efrain |
885 |
global $OUTPUT;
|
|
|
886 |
|
|
|
887 |
// Static variable to remember the files for subsequent calls of this function.
|
|
|
888 |
static $filesforcontext = null;
|
|
|
889 |
|
|
|
890 |
if ($filesforcontext == null) {
|
|
|
891 |
// Get the system context.
|
|
|
892 |
$systemcontext = \context_system::instance();
|
|
|
893 |
|
|
|
894 |
// Get filearea.
|
|
|
895 |
$fs = get_file_storage();
|
|
|
896 |
|
|
|
897 |
// Get all files from filearea.
|
|
|
898 |
$files = $fs->get_area_files($systemcontext->id, 'theme_universe', 'fontfiles', false, 'itemid', false);
|
|
|
899 |
|
|
|
900 |
// Get the webfonts extensions list.
|
|
|
901 |
$webfonts = theme_universe_get_webfonts_extensions();
|
|
|
902 |
|
|
|
903 |
// Iterate over the files.
|
|
|
904 |
$filesforcontext = [];
|
|
|
905 |
foreach ($files as $af) {
|
|
|
906 |
// Get the filename.
|
|
|
907 |
$filename = $af->get_filename();
|
|
|
908 |
|
|
|
909 |
// Check if the file is really a font file (as we can't really rely on the upload restriction in settings.php)
|
|
|
910 |
// according to its file suffix (as the filetype might not have a known mimetype).
|
|
|
911 |
// If it isn't a font file, skip it.
|
|
|
912 |
$filenamesuffix = pathinfo($filename, PATHINFO_EXTENSION);
|
126 |
ariadna |
913 |
if (!in_array('.' . $filenamesuffix, $webfonts)) {
|
1 |
efrain |
914 |
continue;
|
|
|
915 |
}
|
|
|
916 |
|
|
|
917 |
// Otherwise, fill the templatecontext of the file list.
|
126 |
ariadna |
918 |
$urlpersistent = new moodle_url('/pluginfile.php/1/theme_universe/fontfiles/0/' . $filename);
|
|
|
919 |
$filesforcontext[] = [
|
|
|
920 |
'filename' => $filename,
|
|
|
921 |
'fileurlpersistent' => $urlpersistent->out(),
|
|
|
922 |
];
|
1 |
efrain |
923 |
}
|
|
|
924 |
}
|
|
|
925 |
|
|
|
926 |
return $filesforcontext;
|
|
|
927 |
}
|
|
|
928 |
|
|
|
929 |
/**
|
|
|
930 |
* Helper function which returns an array of accepted webfonts extensions (including the dots).
|
|
|
931 |
*
|
|
|
932 |
* @return array
|
|
|
933 |
* Credits: Boost_Union
|
|
|
934 |
*/
|
126 |
ariadna |
935 |
function theme_universe_get_webfonts_extensions()
|
|
|
936 |
{
|
1 |
efrain |
937 |
return ['.eot', '.otf', '.svg', '.ttf', '.woff', '.woff2'];
|
|
|
938 |
}
|
|
|
939 |
|
|
|
940 |
/**
|
|
|
941 |
* Helper function which makes sure that all webfont file types are registered in the system.
|
|
|
942 |
* The webfont file types need to be registered in the system, otherwise the admin settings filepicker wouldn't allow restricting
|
|
|
943 |
* the uploadable file types to webfonts only.
|
|
|
944 |
*
|
|
|
945 |
* Please note: If custom filetypes are defined in config.php, registering additional filetypes is not possible
|
|
|
946 |
* due to a restriction in the set_custom_types() function in Moodle core. In this case, this function does not
|
|
|
947 |
* register anything and will return false.
|
|
|
948 |
*
|
|
|
949 |
* @return boolean true if the filetypes were registered, false if not.
|
|
|
950 |
* @throws coding_exception
|
|
|
951 |
* Credits: Boost_Union
|
|
|
952 |
*/
|
126 |
ariadna |
953 |
function theme_universe_register_webfonts_filetypes()
|
|
|
954 |
{
|
1 |
efrain |
955 |
global $CFG;
|
|
|
956 |
|
|
|
957 |
// If customfiletypes are set in config.php or PHP tests are running, we can't do anything.
|
|
|
958 |
if (array_key_exists('customfiletypes', $CFG->config_php_settings) || PHPUNIT_TEST) {
|
|
|
959 |
return false;
|
|
|
960 |
}
|
|
|
961 |
|
|
|
962 |
// Our array of webfont file types to register.
|
|
|
963 |
// As we want to keep things simple, we do not set a particular icon for these file types.
|
|
|
964 |
// Likewise, we do not set any type groups or use descriptions from the language pack.
|
|
|
965 |
$webfonts = [
|
126 |
ariadna |
966 |
'eot' => [
|
|
|
967 |
'extension' => 'eot',
|
|
|
968 |
'mimetype' => 'application/vnd.ms-fontobject',
|
|
|
969 |
'coreicon' => 'unknown',
|
|
|
970 |
],
|
|
|
971 |
'otf' => [
|
|
|
972 |
'extension' => 'otf',
|
|
|
973 |
'mimetype' => 'font/otf',
|
|
|
974 |
'coreicon' => 'unknown',
|
|
|
975 |
],
|
|
|
976 |
'svg' => [
|
|
|
977 |
'extension' => 'svg',
|
|
|
978 |
'mimetype' => 'image/svg+xml',
|
|
|
979 |
'coreicon' => 'unknown',
|
|
|
980 |
],
|
|
|
981 |
'ttf' => [
|
|
|
982 |
'extension' => 'ttf',
|
|
|
983 |
'mimetype' => 'font/ttf',
|
|
|
984 |
'coreicon' => 'unknown',
|
|
|
985 |
],
|
|
|
986 |
'woff' => [
|
|
|
987 |
'extension' => 'woff',
|
|
|
988 |
'mimetype' => 'font/woff',
|
|
|
989 |
'coreicon' => 'unknown',
|
|
|
990 |
],
|
|
|
991 |
'woff2' => [
|
|
|
992 |
'extension' => 'woff2',
|
|
|
993 |
'mimetype' => 'font/woff2',
|
|
|
994 |
'coreicon' => 'unknown',
|
|
|
995 |
],
|
1 |
efrain |
996 |
];
|
|
|
997 |
|
|
|
998 |
// First, get the list of currently registered file types.
|
|
|
999 |
$currenttypes = core_filetypes::get_types();
|
|
|
1000 |
|
|
|
1001 |
// Iterate over the webfonts file types.
|
|
|
1002 |
foreach ($webfonts as $f) {
|
|
|
1003 |
// If the file type is already registered, skip it.
|
|
|
1004 |
if (array_key_exists($f['extension'], $currenttypes)) {
|
|
|
1005 |
continue;
|
|
|
1006 |
}
|
|
|
1007 |
|
|
|
1008 |
// Otherwise, register the file type.
|
|
|
1009 |
core_filetypes::add_type($f['extension'], $f['mimetype'], $f['coreicon']);
|
|
|
1010 |
}
|
|
|
1011 |
|
|
|
1012 |
return true;
|
|
|
1013 |
}
|
156 |
ariadna |
1014 |
|
161 |
ariadna |
1015 |
function theme_universe_get_default_blocks()
|
156 |
ariadna |
1016 |
{
|
|
|
1017 |
return array(
|
|
|
1018 |
'incourse' => array(
|
168 |
ariadna |
1019 |
'bellow-content' => array('block_comments', 'block_comments')
|
156 |
ariadna |
1020 |
),
|
|
|
1021 |
);
|
|
|
1022 |
}
|