1 | <?php |
||
2 | /** |
||
3 | * @package midcom.helper |
||
4 | * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||
5 | * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||
6 | * @license http://www.gnu.org/licenses/gpl.html GNU General Public License |
||
7 | */ |
||
8 | |||
9 | use Symfony\Component\HttpKernel\KernelEvents; |
||
10 | use Symfony\Component\HttpKernel\Event\ResponseEvent; |
||
11 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||
12 | |||
13 | /** |
||
14 | * Helper functions for managing HTML head |
||
15 | * |
||
16 | * @package midcom.helper |
||
17 | */ |
||
18 | class midcom_helper_head implements EventSubscriberInterface |
||
19 | { |
||
20 | /** |
||
21 | * Array with all JavaScript declarations for the page's head. |
||
22 | */ |
||
23 | private array $_jshead = []; |
||
24 | |||
25 | /** |
||
26 | * Array with all JavaScript file inclusions. |
||
27 | */ |
||
28 | private array $_jsfiles = []; |
||
29 | |||
30 | /** |
||
31 | * Array with all prepend JavaScript declarations for the page's head. |
||
32 | */ |
||
33 | private array $_prepend_jshead = []; |
||
34 | |||
35 | /** |
||
36 | * Boolean showing if jQuery is enabled |
||
37 | */ |
||
38 | private bool $_jquery_enabled = false; |
||
39 | |||
40 | /** |
||
41 | * Array with all JQuery state scripts for the page's head. |
||
42 | */ |
||
43 | private array $_jquery_states = []; |
||
44 | |||
45 | /** |
||
46 | * Array with all linked URLs for HEAD. |
||
47 | */ |
||
48 | private array $_linkhrefs = []; |
||
49 | |||
50 | /** |
||
51 | * Array with all methods for the BODY's onload event. |
||
52 | */ |
||
53 | private array $_jsonload = []; |
||
54 | |||
55 | /** |
||
56 | * string with all metatags to go into the page head. |
||
57 | */ |
||
58 | private string $_meta_head = ''; |
||
59 | |||
60 | /** |
||
61 | * String with all css styles to go into a page's head. |
||
62 | */ |
||
63 | private string $_style_head = ''; |
||
64 | |||
65 | /** |
||
66 | * Array with all link elements to be included in a page's head. |
||
67 | */ |
||
68 | private array $_link_head = []; |
||
69 | |||
70 | const HEAD_PLACEHOLDER = '<!-- MIDCOM_HEAD_ELEMENTS -->'; |
||
71 | |||
72 | private static bool $placeholder_added = false; |
||
73 | |||
74 | private string $cachebusting = ''; |
||
75 | |||
76 | public static function getSubscribedEvents() |
||
77 | { |
||
78 | return [KernelEvents::RESPONSE => ['inject_head_elements']]; |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * Sets the page title for the current context. |
||
83 | * |
||
84 | * This can be retrieved by accessing the component context key |
||
85 | * MIDCOM_CONTEXT_PAGETITLE. |
||
86 | */ |
||
87 | 144 | public function set_pagetitle(string $string) |
|
88 | { |
||
89 | 144 | midcom_core_context::get()->set_key(MIDCOM_CONTEXT_PAGETITLE, $string); |
|
90 | } |
||
91 | |||
92 | /** |
||
93 | * Register JavaScript File for referring in the page. |
||
94 | * |
||
95 | * This allows MidCOM components to register JavaScript code |
||
96 | * during page processing. The site style code can then query this queued-up code |
||
97 | * at anytime it likes. The queue-up SHOULD be done during the code-init phase, |
||
98 | * while the print_head_elements output SHOULD be included in the HTML HEAD area and |
||
99 | * the HTTP onload attribute returned by print_jsonload SHOULD be included in the |
||
100 | * BODY-tag. Note, that these suggestions are not enforced, if you want a JScript |
||
101 | * clean site, just omit the print calls and you should be fine in almost all |
||
102 | * cases. |
||
103 | * |
||
104 | * The sequence of the add_jsfile and add_jscript commands is kept stable. |
||
105 | * |
||
106 | * @see add_jscript() |
||
107 | * @see add_jsonload() |
||
108 | * @see print_head_elements() |
||
109 | * @see print_jsonload() |
||
110 | */ |
||
111 | 252 | public function add_jsfile(string $url, bool $prepend = false) |
|
112 | { |
||
113 | // Adds a URL for a <script type="text/javascript" src="tinymce.js"></script> |
||
114 | // like call. $url is inserted into src. Duplicates are omitted. |
||
115 | 252 | if (!in_array($url, $this->_jsfiles)) { |
|
116 | 33 | $this->_jsfiles[] = $url; |
|
117 | 33 | $js_call = ['url' => $url]; |
|
118 | 33 | if ($prepend) { |
|
119 | // Add the javascript include to the beginning, not the end of array |
||
120 | array_unshift($this->_jshead, $js_call); |
||
121 | } else { |
||
122 | 33 | $this->_jshead[] = $js_call; |
|
123 | } |
||
124 | } |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Register JavaScript Code for output directly in the page. |
||
129 | * |
||
130 | * This allows components to register JavaScript code |
||
131 | * during page processing. The site style can then query this queued-up code |
||
132 | * at anytime it likes. The queue-up SHOULD be done during the code-init phase, |
||
133 | * while the print_head_elements output SHOULD be included in the HTML HEAD area and |
||
134 | * the HTTP onload attribute returned by print_jsonload SHOULD be included in the |
||
135 | * BODY-tag. Note, that these suggestions are not enforced |
||
136 | * |
||
137 | * The sequence of the add_jsfile and add_jscript commands is kept stable. |
||
138 | * |
||
139 | * @see add_jsfile() |
||
140 | * @see add_jsonload() |
||
141 | * @see print_head_elements() |
||
142 | * @see print_jsonload() |
||
143 | */ |
||
144 | 77 | public function add_jscript(string $script, $defer = '', bool $prepend = false) |
|
145 | { |
||
146 | 77 | $js_call = ['content' => trim($script), 'defer' => $defer]; |
|
147 | 77 | if ($prepend) { |
|
148 | $this->_prepend_jshead[] = $js_call; |
||
149 | } else { |
||
150 | 77 | $this->_jshead[] = $js_call; |
|
151 | } |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Register JavaScript snippets to jQuery states. |
||
156 | * |
||
157 | * This allows components to register JavaScript code to the jQuery states. |
||
158 | * Possible ready states: document.ready |
||
159 | * |
||
160 | * @see print_jquery_statuses() |
||
161 | */ |
||
162 | 3 | public function add_jquery_state_script(string $script, string $state = 'document.ready') |
|
163 | { |
||
164 | 3 | $this->_jquery_states[$state] ??= ''; |
|
165 | 3 | $this->_jquery_states[$state] .= "\n" . trim($script) . "\n"; |
|
166 | } |
||
167 | |||
168 | /** |
||
169 | * Register a metatag to be added to the head element. |
||
170 | * This allows components to register metatags to be placed in the |
||
171 | * head section of the page. |
||
172 | * |
||
173 | * @param array $attributes Array of attribute => value pairs to be placed in the tag. |
||
174 | * @see print_head_elements() |
||
175 | */ |
||
176 | public function add_meta_head(array $attributes) |
||
177 | { |
||
178 | $this->_meta_head .= '<meta' . $this->_get_attribute_string($attributes) . ' />' . "\n"; |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * Register a styleblock / style link to be added to the head element. |
||
183 | * This allows components to register extra CSS sheets they wants to include. |
||
184 | * in the head section of the page. |
||
185 | * |
||
186 | * @param string $script The input between the <style></style> tags. |
||
187 | * @param array $attributes Array of attribute=> value pairs to be placed in the tag. |
||
188 | * @see print_head_elements() |
||
189 | */ |
||
190 | public function add_style_head(string $script, array $attributes = []) |
||
191 | { |
||
192 | $this->_style_head .= '<style type="text/css"' . $this->_get_attribute_string($attributes) . '>' . $script . "</style>\n"; |
||
193 | } |
||
194 | |||
195 | 8 | private function _get_attribute_string(array $attributes) : string |
|
196 | { |
||
197 | 8 | $string = ''; |
|
198 | 8 | foreach ($attributes as $key => $val) { |
|
199 | 8 | if ($this->cachebusting && $key === 'href') { |
|
200 | $val .= $this->cachebusting; |
||
201 | } |
||
202 | 8 | $string .= ' ' . $key . '="' . htmlspecialchars($val, ENT_COMPAT) . '"'; |
|
203 | } |
||
204 | 8 | return $string; |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * Register a link element to be placed in the page head. |
||
209 | * |
||
210 | * This allows components to register extra CSS links. |
||
211 | * Example to use this to include a CSS link: |
||
212 | * <code> |
||
213 | * $attributes = array ('rel' => 'stylesheet', |
||
214 | * 'type' => 'text/css', |
||
215 | * 'href' => '/style.css' |
||
216 | * ); |
||
217 | * midcom::get()->head->add_link_head($attributes); |
||
218 | * </code> |
||
219 | * |
||
220 | * Each URL will only be added once. When trying to add the same URL a second time, |
||
221 | * it will be moved to the end of the stack, so that CSS overrides behave as the developer |
||
222 | * intended |
||
223 | * |
||
224 | * @param array $attributes Array of attribute => value pairs to be placed in the tag. |
||
225 | * @see print_head_elements() |
||
226 | */ |
||
227 | 295 | public function add_link_head(array $attributes, bool $prepend = false) |
|
228 | { |
||
229 | 295 | if (!array_key_exists('href', $attributes)) { |
|
230 | return; |
||
231 | } |
||
232 | |||
233 | // Register each URL only once |
||
234 | 295 | if (($key = array_search($attributes['href'], $this->_linkhrefs)) !== false) { |
|
235 | 287 | unset($this->_linkhrefs[$key]); |
|
236 | } |
||
237 | 295 | if ($prepend) { |
|
238 | 234 | array_unshift($this->_linkhrefs, $attributes['href']); |
|
239 | } else { |
||
240 | 276 | $this->_linkhrefs[] = $attributes['href']; |
|
241 | } |
||
242 | 295 | $this->_link_head[$attributes['href']] = $attributes; |
|
243 | } |
||
244 | |||
245 | /** |
||
246 | * Convenience shortcut for appending CSS files |
||
247 | * |
||
248 | * @param string $media The media type(s) for the stylesheet, if any |
||
249 | */ |
||
250 | 269 | public function add_stylesheet(string $url, ?string $media = null) |
|
251 | { |
||
252 | 269 | $this->add_link_head($this->prepare_stylesheet_attributes($url, $media)); |
|
253 | } |
||
254 | |||
255 | /** |
||
256 | * Convenience shortcut for prepending CSS files |
||
257 | * |
||
258 | * @param string $media The media type(s) for the stylesheet, if any |
||
259 | */ |
||
260 | 126 | public function prepend_stylesheet(string $url, ?string $media = null) |
|
261 | { |
||
262 | 126 | $this->add_link_head($this->prepare_stylesheet_attributes($url, $media), true); |
|
263 | } |
||
264 | |||
265 | 288 | private function prepare_stylesheet_attributes(string $url, ?string $media) : array |
|
266 | { |
||
267 | 288 | $attributes = [ |
|
268 | 288 | 'rel' => 'stylesheet', |
|
269 | 288 | 'type' => 'text/css', |
|
270 | 288 | 'href' => $url, |
|
271 | 288 | ]; |
|
272 | 288 | if ($media) { |
|
273 | 32 | $attributes['media'] = $media; |
|
274 | } |
||
275 | 288 | return $attributes; |
|
276 | } |
||
277 | |||
278 | /** |
||
279 | * Register a JavaScript method for the body onload event |
||
280 | * |
||
281 | * This allows components to register JavaScript code |
||
282 | * during page processing. The site style can then query this queued-up code |
||
283 | * at anytime it likes. The queue-up SHOULD be done during the code-init phase, |
||
284 | * while the print_head_elements output SHOULD be included in the HTML HEAD area and |
||
285 | * the HTTP onload attribute returned by print_jsonload SHOULD be included in the |
||
286 | * BODY-tag. Note that these suggestions are not enforced. |
||
287 | * |
||
288 | * @param string $method The name of the method to be called on page startup, including parameters but excluding the ';'. |
||
289 | * @see add_jsfile() |
||
290 | * @see add_jscript() |
||
291 | * @see print_head_elements() |
||
292 | * @see print_jsonload() |
||
293 | */ |
||
294 | public function add_jsonload(string $method) |
||
295 | { |
||
296 | // Adds a method name for <body onload=".."> The string must not end with a ;, it is added automagically |
||
297 | $this->_jsonload[] = $method; |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Echo the registered javascript code. |
||
302 | * |
||
303 | * This allows components to register JavaScript code |
||
304 | * during page processing. The site style code can then query this queued-up code |
||
305 | * at anytime it likes. The queue-up SHOULD be done during the code-init phase, |
||
306 | * while the print_head_elements output SHOULD be included in the HTML HEAD area and |
||
307 | * the HTTP onload attribute returned by print_jsonload SHOULD be included in the |
||
308 | * BODY-tag. Note, that these suggestions are not enforced |
||
309 | * |
||
310 | * The sequence of the add_jsfile and add_jscript commands is kept stable. |
||
311 | * |
||
312 | * This is usually called during the BODY region of your style: |
||
313 | * |
||
314 | * <code> |
||
315 | * <html> |
||
316 | * <body <?php midcom::get()->head->print_jsonload();?>> |
||
317 | * <!-- your actual body --> |
||
318 | * </body> |
||
319 | * </html> |
||
320 | * </code> |
||
321 | * |
||
322 | * @see add_jsfile() |
||
323 | * @see add_jscript() |
||
324 | * @see add_jsonload() |
||
325 | * @see print_head_elements() |
||
326 | */ |
||
327 | 23 | public function print_jsonload() |
|
328 | { |
||
329 | 23 | if (!empty($this->_jsonload)) { |
|
330 | $calls = implode("; ", $this->_jsonload); |
||
331 | echo " onload=\"$calls\" "; |
||
332 | } |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * Marks where the _head elements added should be rendered. |
||
337 | * |
||
338 | * Place the method within the <head> section of your page. |
||
339 | * |
||
340 | * This allows components to register HEAD elements |
||
341 | * during page processing. The site style can then query this queued-up code |
||
342 | * at anytime it likes. The queue-up SHOULD be done during the code-init phase, |
||
343 | * while the print_head_elements output SHOULD be included in the HTML HEAD area and |
||
344 | * the HTTP onload attribute returned by print_jsonload SHOULD be included in the |
||
345 | * BODY tag. Note that these suggestions are not enforced |
||
346 | * |
||
347 | * @see add_link_head() |
||
348 | * @see add_style_head() |
||
349 | * @see add_meta_head() |
||
350 | * @see add_jsfile() |
||
351 | * @see add_jscript() |
||
352 | */ |
||
353 | 29 | public function print_head_elements(string $cachebusting = '') |
|
354 | { |
||
355 | 29 | if ($cachebusting) { |
|
356 | $this->cachebusting = '?cb=' . $cachebusting; |
||
357 | } |
||
358 | 29 | echo self::HEAD_PLACEHOLDER; |
|
359 | 29 | self::$placeholder_added = true; |
|
360 | } |
||
361 | |||
362 | /** |
||
363 | * This function renders the elements added by the various add methods |
||
364 | * and injects them into the response |
||
365 | */ |
||
366 | 352 | public function inject_head_elements(ResponseEvent $event) |
|
367 | { |
||
368 | 352 | if (!self::$placeholder_added || !$event->isMainRequest()) { |
|
369 | 352 | return; |
|
370 | } |
||
371 | $response = $event->getResponse(); |
||
372 | $content = $response->getContent(); |
||
373 | |||
374 | $first = strpos($content, self::HEAD_PLACEHOLDER); |
||
375 | if ($first === false) { |
||
376 | return; |
||
377 | } |
||
378 | |||
379 | $head = $this->render(); |
||
380 | $new_content = substr_replace($content, $head, $first, strlen(self::HEAD_PLACEHOLDER)); |
||
381 | $response->setContent($new_content); |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
382 | if ($length = $response->headers->get('Content-Length')) { |
||
383 | $delta = strlen($head) - strlen(self::HEAD_PLACEHOLDER); |
||
384 | $response->headers->set('Content-Length', $length + $delta); |
||
385 | } |
||
386 | } |
||
387 | |||
388 | 8 | public function render() : string |
|
389 | { |
||
390 | 8 | $head = $this->_meta_head; |
|
391 | 8 | foreach ($this->_linkhrefs as $url) { |
|
392 | 8 | $attributes = $this->_link_head[$url]; |
|
393 | 8 | $is_conditional = false; |
|
394 | |||
395 | 8 | if (array_key_exists('condition', $attributes)) { |
|
396 | $head .= "<!--[if {$attributes['condition']}]>\n"; |
||
397 | $is_conditional = true; |
||
398 | unset($attributes['condition']); |
||
399 | } |
||
400 | |||
401 | 8 | $head .= "<link" . $this->_get_attribute_string($attributes) . " />\n"; |
|
402 | |||
403 | 8 | if ($is_conditional) { |
|
404 | $head .= "<![endif]-->\n"; |
||
405 | } |
||
406 | } |
||
407 | |||
408 | 8 | $head .= $this->_style_head; |
|
409 | |||
410 | 8 | if (!empty($this->_prepend_jshead)) { |
|
411 | 8 | $head .= array_reduce($this->_prepend_jshead, $this->render_js(...), ''); |
|
412 | } |
||
413 | |||
414 | 8 | $head .= array_reduce($this->_jshead, $this->render_js(...), ''); |
|
415 | 8 | return $head . $this->render_jquery_statuses(); |
|
416 | } |
||
417 | |||
418 | 8 | private function render_js(string $carry, array $js_call) : string |
|
419 | { |
||
420 | 8 | if (array_key_exists('url', $js_call)) { |
|
421 | 8 | if ($this->cachebusting) { |
|
422 | $js_call['url'] .= $this->cachebusting; |
||
423 | } |
||
424 | 8 | return $carry . '<script type="text/javascript" src="' . $js_call['url'] . "\"></script>\n"; |
|
425 | } |
||
426 | 8 | $carry .= '<script type="text/javascript"' . ($js_call['defer'] ?? '') . ">\n"; |
|
427 | 8 | $carry .= $js_call['content'] . "\n"; |
|
428 | 8 | return $carry . "</script>\n"; |
|
429 | } |
||
430 | |||
431 | 7 | public function get_jshead_elements() : array |
|
432 | { |
||
433 | 7 | return array_merge($this->_prepend_jshead, $this->_jshead); |
|
434 | } |
||
435 | |||
436 | public function get_link_head() : array |
||
437 | { |
||
438 | return $this->_link_head; |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * Init jQuery |
||
443 | * |
||
444 | * This method adds jQuery support to the page |
||
445 | */ |
||
446 | 234 | public function enable_jquery() |
|
447 | { |
||
448 | 234 | if ($this->_jquery_enabled) { |
|
449 | 233 | return; |
|
450 | } |
||
451 | |||
452 | 1 | $script = "const MIDCOM_STATIC_URL = '" . MIDCOM_STATIC_URL . "',\n"; |
|
453 | 1 | $script .= " MIDCOM_PAGE_PREFIX = '" . midcom_connection::get_url('self') . "';"; |
|
454 | 1 | array_unshift($this->_prepend_jshead, ['content' => $script]); |
|
455 | |||
456 | 1 | $version = midcom::get()->config->get('jquery_version'); |
|
457 | 1 | if (midcom::get()->config->get('jquery_load_from_google')) { |
|
458 | // Use Google's hosted jQuery version |
||
459 | array_unshift($this->_prepend_jshead, ['content' => 'google.load("jquery", "' . $version . '");']); |
||
460 | array_unshift($this->_prepend_jshead, ['url' => 'https://www.google.com/jsapi']); |
||
461 | } else { |
||
462 | 1 | $url = MIDCOM_STATIC_URL . "/jQuery/jquery-{$version}.js"; |
|
463 | 1 | array_unshift($this->_prepend_jshead, ['url' => $url]); |
|
464 | } |
||
465 | |||
466 | 1 | if (!defined('MIDCOM_JQUERY_UI_URL')) { |
|
467 | 1 | define('MIDCOM_JQUERY_UI_URL', MIDCOM_STATIC_URL . "/jQuery/jquery-ui-" . midcom::get()->config->get('jquery_ui_version')); |
|
468 | } |
||
469 | |||
470 | 1 | $this->_jquery_enabled = true; |
|
471 | } |
||
472 | |||
473 | /** |
||
474 | * Renders the scripts added by the add_jquery_state_script method. |
||
475 | * |
||
476 | * This method is called from print_head_elements method. |
||
477 | * |
||
478 | * @see add_jquery_state_script() |
||
479 | * @see print_head_elements() |
||
480 | */ |
||
481 | 8 | private function render_jquery_statuses() : string |
|
482 | { |
||
483 | 8 | if (empty($this->_jquery_states)) { |
|
484 | 7 | return ''; |
|
485 | } |
||
486 | |||
487 | 1 | $content = ''; |
|
488 | 1 | foreach ($this->_jquery_states as $status => $scripts) { |
|
489 | 1 | [$target, $method] = explode('.', $status); |
|
490 | 1 | $content .= "jQuery({$target}).{$method}(function() {\n"; |
|
491 | 1 | $content .= $scripts . "\n"; |
|
492 | 1 | $content .= "});\n"; |
|
493 | } |
||
494 | |||
495 | 1 | return $this->render_js('', ['content' => $content]); |
|
496 | } |
||
497 | |||
498 | /** |
||
499 | * Add jquery ui components |
||
500 | * |
||
501 | * core and widget are loaded automatically. Also loads jquery.ui theme, |
||
502 | * either the configured theme one or a hardcoded default (base theme) |
||
503 | */ |
||
504 | 225 | public function enable_jquery_ui(array $components = []) |
|
505 | { |
||
506 | 225 | $this->enable_jquery(); |
|
507 | 225 | $this->add_jsfile(MIDCOM_JQUERY_UI_URL . '/core.min.js'); |
|
508 | |||
509 | 225 | foreach ($components as $component) { |
|
510 | 222 | $path = $component; |
|
511 | 222 | if (str_starts_with($component, 'effect')) { |
|
512 | if ($component !== 'effect') { |
||
513 | $path = 'effects/' . $component; |
||
514 | } |
||
515 | } else { |
||
516 | 222 | $path = 'widgets/' . $component; |
|
517 | } |
||
518 | |||
519 | 222 | $this->add_jsfile(MIDCOM_JQUERY_UI_URL . '/' . $path . '.min.js'); |
|
520 | |||
521 | 222 | if ($component == 'datepicker') { |
|
522 | /* |
||
523 | * The calendar doesn't have all lang files and some are named differently |
||
524 | * Since a missing lang file causes the calendar to break, let's make extra sure |
||
525 | * that this won't happen |
||
526 | */ |
||
527 | 36 | foreach ([midcom::get()->i18n->get_current_language(), midcom::get()->i18n->get_fallback_language()] as $lang) { |
|
528 | 36 | if (file_exists(MIDCOM_STATIC_ROOT . "/jQuery/jquery-ui-" . midcom::get()->config->get('jquery_ui_version') . "/i18n/datepicker-{$lang}.min.js")) { |
|
529 | $this->add_jsfile(MIDCOM_JQUERY_UI_URL . "/i18n/datepicker-{$lang}.min.js"); |
||
530 | break; |
||
531 | } |
||
532 | } |
||
533 | } |
||
534 | } |
||
535 | |||
536 | 225 | $this->add_link_head([ |
|
537 | 225 | 'rel' => 'stylesheet', |
|
538 | 225 | 'type' => 'text/css', |
|
539 | 225 | 'href' => MIDCOM_STATIC_URL . '/jQuery/jquery-ui-1.12.icon-font.min.css', |
|
540 | 225 | ], true); |
|
541 | 225 | $this->add_link_head([ |
|
542 | 225 | 'rel' => 'stylesheet', |
|
543 | 225 | 'type' => 'text/css', |
|
544 | 225 | 'href' => midcom::get()->config->get('jquery_ui_theme', MIDCOM_JQUERY_UI_URL . '/themes/base/jquery-ui.min.css'), |
|
545 | 225 | ], true); |
|
546 | } |
||
547 | } |
||
548 |