ILIAS  release_8 Revision v8.24
class.ilObjStyleSheet.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
27{
28 protected \ILIAS\Style\Content\InternalRepoService $repo;
29 protected bool $is_3_10_skin = false;
30 protected string $export_sub_dir = "";
31 protected array $chars_by_type = [];
32 protected array $end_styles = [];
33 protected array $chars = [];
34 protected bool $up_to_date = false;
35 public array $style = [];
36 protected array $hidden_chars = [];
37 protected array $style_class = [];
38
39 protected int $scope = 0;
40
41 public static array $num_unit = array("px", "em", "ex", "%", "pt", "pc", "in", "mm", "cm");
42 public static array $num_unit_no_perc = array("px", "em", "ex", "pt", "pc", "in", "mm", "cm");
43
44 // css parameters and their attribute values, input type and group
45 public static array $parameter = array(
46 "font-size" => array(
47 "values" => array("xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "smaller", "larger"),
48 "input" => "fontsize",
49 "group" => "text"),
50 "font-family" => array(
51 "values" => array(),
52 "input" => "text",
53 "group" => "text"),
54 "font-style" => array(
55 "values" => array("italic", "oblique", "normal"),
56 "input" => "select",
57 "group" => "text"),
58 "font-weight" => array(
59 "values" => array("bold", "normal", "bolder", "lighter"),
60 "input" => "select",
61 "group" => "text"),
62 "font-variant" => array(
63 "values" => array("small-caps", "normal"),
64 "input" => "select",
65 "group" => "text"),
66 "word-spacing" => array(
67 "values" => array(),
68 "input" => "numeric_no_perc",
69 "group" => "text"),
70 "letter-spacing" => array(
71 "values" => array(),
72 "input" => "numeric_no_perc",
73 "group" => "text"),
74 "text-decoration" => array(
75 "values" => array("underline", "overline", "line-through", "blink", "none"),
76 "input" => "select",
77 "group" => "text"),
78 "text-transform" => array(
79 "values" => array("capitalize", "uppercase", "lowercase", "none"),
80 "input" => "select",
81 "group" => "text"),
82 "color" => array(
83 "values" => array(),
84 "input" => "color",
85 "group" => "text"),
86 "text-indent" => array(
87 "values" => array(),
88 "input" => "numeric",
89 "group" => "text"),
90 "line-height" => array(
91 "values" => array(),
92 "input" => "numeric",
93 "group" => "text"),
94 "vertical-align" => array(
95 "values" => array("top", "middle", "bottom", "baseline", "sub", "super",
96 "text-top", "text-bottom"),
97 "input" => "select",
98 "group" => "text"),
99 "text-align" => array(
100 "values" => array("left", "center", "right", "justify"),
101 "input" => "select",
102 "group" => "text"),
103 "white-space" => array(
104 "values" => array("normal", "pre", "nowrap"),
105 "input" => "select",
106 "group" => "text"),
107 "margin" => array(
108 "values" => array(),
109 "input" => "trbl_numeric",
110 "subpar" => array("margin", "margin-top", "margin-right",
111 "margin-bottom", "margin-left"),
112 "group" => "margin_and_padding"),
113 "padding" => array(
114 "values" => array(),
115 "input" => "trbl_numeric",
116 "subpar" => array("padding", "padding-top", "padding-right",
117 "padding-bottom", "padding-left"),
118 "group" => "margin_and_padding"),
119 "border-width" => array(
120 "values" => array("thin", "medium", "thick"),
121 "input" => "border_width",
122 "subpar" => array("border-width", "border-top-width", "border-right-width",
123 "border-bottom-width", "border-left-width"),
124 "group" => "border"),
125 "border-color" => array(
126 "values" => array(),
127 "input" => "trbl_color",
128 "subpar" => array("border-color", "border-top-color", "border-right-color",
129 "border-bottom-color", "border-left-color"),
130 "group" => "border"),
131 "border-style" => array(
132 "values" => array("none", "hidden", "dotted", "dashed", "solid", "double",
133 "groove", "ridge", "inset", "outset"),
134 "input" => "border_style",
135 "subpar" => array("border-style", "border-top-style", "border-right-style",
136 "border-bottom-style", "border-left-style"),
137 "group" => "border"),
138
139 "background-color" => array(
140 "values" => array(),
141 "input" => "color",
142 "group" => "background"),
143 "background-image" => array(
144 "values" => array(),
145 "input" => "background_image",
146 "group" => "background"),
147 "background-repeat" => array(
148 "values" => array("repeat", "repeat-x", "repeat-y", "no-repeat"),
149 "input" => "select",
150 "group" => "background"),
151 "background-attachment" => array(
152 "values" => array("fixed", "scroll"),
153 "input" => "select",
154 "group" => "background"),
155 "background-position" => array(
156 "values" => array("horizontal" => array("left", "center", "right"),
157 "vertical" => array("top", "center", "bottom")),
158 "input" => "background_position",
159 "group" => "background"),
160
161 "position" => array(
162 "values" => array("absolute", "fixed", "relative", "static"),
163 "input" => "select",
164 "group" => "positioning"),
165 "top" => array(
166 "values" => array(),
167 "input" => "numeric",
168 "group" => "positioning"),
169 "bottom" => array(
170 "values" => array(),
171 "input" => "numeric",
172 "group" => "positioning"),
173 "left" => array(
174 "values" => array(),
175 "input" => "numeric",
176 "group" => "positioning"),
177 "right" => array(
178 "values" => array(),
179 "input" => "numeric",
180 "group" => "positioning"),
181 "width" => array(
182 "values" => array(),
183 "input" => "numeric",
184 "group" => "positioning"),
185 "height" => array(
186 "values" => array(),
187 "input" => "numeric",
188 "group" => "positioning"),
189 "min-height" => array(
190 "values" => array(),
191 "input" => "numeric",
192 "group" => "positioning"),
193 "float" => array(
194 "values" => array("left", "right", "none"),
195 "input" => "select",
196 "group" => "positioning"),
197 "overflow" => array(
198 "values" => array("visible", "hidden", "scroll", "auto"),
199 "input" => "select",
200 "group" => "positioning"),
201 "opacity" => array(
202 "values" => array(),
203 "input" => "percentage",
204 "group" => "special"),
205 "transform" => array(
206 "values" => array("rotate(90deg)", "rotate(180deg)", "rotate(270deg)"),
207 "input" => "select",
208 "group" => "special"),
209 "transform-origin" => array(
210 "values" => array( "horizontal" => array("left", "center", "right"),
211 "vertical" => array("top", "center", "bottom")),
212 "input" => "background_position",
213 "group" => "special"),
214 "cursor" => array(
215 "values" => array("auto", "default", "crosshair", "pointer", "move",
216 "n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize",
217 "w-resize", "nw-resize", "text", "wait", "help"),
218 "input" => "select",
219 "group" => "special"),
220 "clear" => array(
221 "values" => array("both","left","right","none"),
222 "input" => "select",
223 "group" => "special"),
224
225 "list-style-type.ol" => array(
226 "values" => array("decimal","lower-roman","upper-roman",
227 "lower-alpha", "upper-alpha", "lower-greek", "hebrew",
228 "decimal-leading-zero", "cjk-ideographic", "hiragana",
229 "katakana", "hiragana-iroha", "katakana-iroha", "none"),
230 "input" => "select",
231 "group" => "ol"),
232 "list-style-type.ul" => array(
233 "values" => array("disc","circle","square",
234 "none"),
235 "input" => "select",
236 "group" => "ul"),
237 "list-style-image.ul" => array(
238 "values" => array(),
239 "input" => "background_image",
240 "group" => "ul"),
241 "list-style-position.ol" => array(
242 "values" => array("inside","outside"),
243 "input" => "select",
244 "group" => "ol"),
245 "list-style-position.ul" => array(
246 "values" => array("inside","outside"),
247 "input" => "select",
248 "group" => "ul"
249 ),
250 "border-collapse" => array(
251 "values" => array("collapse","separate"),
252 "input" => "select",
253 "group" => "table"
254 ),
255 "caption-side" => array(
256 "values" => array("top","bottom","left","right"),
257 "input" => "select",
258 "group" => "table"
259 )
260 );
261
262 // filter groups of properties that should only be
263 // displayed with matching tag (group -> tags)
264 public static array $filtered_groups =
265 array("ol" => array("ol"), "ul" => array("ul"),
266 "table" => array("table"), "positioning" => array("h1", "h2", "h3", "div", "img", "table", "a", "figure"));
267
268 // style types and their super type
269 public static array $style_super_types = array(
270 "text_block" => array("text_block", "heading1", "heading2", "heading3", "code_block"),
271 "text_inline" => array("text_inline", "sub", "sup", "code_inline"),
272 "section" => array("section"),
273 "link" => array("link"),
274 "table" => array("table", "table_cell", "table_caption"),
275 "list" => array("list_o", "list_u", "list_item"),
276 "flist" => array("flist_cont", "flist_head", "flist", "flist_li", "flist_a"),
277 "media" => array("media_cont", "media_caption", "iim", "marker"),
278 "tabs" => array("va_cntr", "va_icntr", "va_ihead", "va_iheada", "va_ihcap", "va_icont",
279 "ha_cntr", "ha_icntr", "ha_ihead", "ha_iheada", "ha_ihcap", "ha_icont", "ca_cntr", "ca_icntr", "ca_ihead", "ca_icont"),
280 "question" => array("question", "qtitle", "qanswer", "qinput", "qlinput", "qsubmit", "qfeedr", "qfeedw",
281 "qimg", "qordul", "qordli", "qimgd", "qetitem", "qetcorr", "qover"),
282 "page" => array("page_frame", "page_cont", "page_title", "page_fn",
283 "page_tnav", "page_bnav", "page_lnav", "page_rnav", "page_lnavlink", "page_rnavlink",
284 "page_lnavimage", "page_rnavimage")
285 );
286
287 // these types are expandable, i.e. the user can define new style classes
288 public static array $expandable_types = array(
289 "text_block",
290 "text_inline", "section", "media_cont", "media_caption", "table", "table_cell", "flist_li", "table_caption",
291 "list_o", "list_u",
292 "va_cntr", "va_icntr", "va_ihead", "va_iheada", "va_ihcap", "va_icont",
293 "ha_cntr", "ha_icntr", "ha_ihead", "ha_iheada", "ha_ihcap", "ha_icont",
294 "ca_cntr", "ca_icntr", "ca_ihead", "ca_icont"
295 );
296
297 // these types can be hidden in the content editor
298 public static array $hideable_types = array(
299 "table", "table_cell"
300 );
301
302 // tag that are used by style types
303 public static array $assigned_tags = array(
304 "text_block" => "div",
305 "heading1" => "h1",
306 "heading2" => "h2",
307 "heading3" => "h3",
308 "code_block" => "pre",
309 "text_inline" => "span",
310 "code_inline" => "code",
311 "sup" => "sup",
312 "sub" => "sub",
313 "section" => "div",
314 "link" => "a",
315 "table" => "table",
316 "table_cell" => "td",
317 "table_caption" => "caption",
318 "media_cont" => "figure",
319 "media_caption" => "div",
320 "iim" => "div",
321 "marker" => "a",
322 "list_o" => "ol",
323 "list_u" => "ul",
324 "list_item" => "li",
325 "flist_cont" => "div",
326 "flist_head" => "div",
327 "flist" => "ul",
328 "flist_li" => "li",
329 "flist_a" => "a",
330 "question" => "div",
331 "qtitle" => "div",
332 "qanswer" => "div",
333 "qimg" => "img",
334 "qimgd" => "a",
335 "qordul" => "ul",
336 "qordli" => "li",
337 "qetitem" => "a",
338 "qetcorr" => "span",
339 "qinput" => "input",
340 "qlinput" => "textarea",
341 "qsubmit" => "input",
342 "qfeedr" => "div",
343 "qfeedw" => "div",
344 "qover" => "div",
345 "page_frame" => "div",
346 "page_cont" => "div",
347 "page_fn" => "div",
348 "page" => "div",
349 "page_tnav" => "div",
350 "page_bnav" => "div",
351 "page_lnav" => "div",
352 "page_rnav" => "div",
353 "page_lnavlink" => "a",
354 "page_rnavlink" => "a",
355 "page_lnavimage" => "img",
356 "page_rnavimage" => "img",
357 "page_title" => "h1",
358 "va_cntr" => "div",
359 "va_icntr" => "div",
360 "va_icont" => "div",
361 "va_ihead" => "div",
362 "va_iheada" => "div",
363 "va_ihcap" => "div",
364 "ha_cntr" => "div",
365 "ha_icntr" => "div",
366 "ha_icont" => "div",
367 "ha_iheada" => "div",
368 "ha_ihcap" => "div",
369 "ha_ihead" => "div",
370 "ca_cntr" => "div",
371 "ca_icntr" => "div",
372 "ca_ihead" => "div",
373 "ca_icont" => "div"
374 );
375
376 // pseudo classes
377 public static array $pseudo_classes =
378 array("a" => array("hover"), "div" => array("hover"), "img" => array("hover"));
379
380 // core styles these styles MUST exists -> see also basic_style/style.xml
381 public static array $core_styles = array(
382 array("type" => "text_block", "class" => "Standard"),
383 array("type" => "text_block", "class" => "List"),
384 array("type" => "text_block", "class" => "TableContent"),
385 array("type" => "code_block", "class" => "Code"),
386 array("type" => "heading1", "class" => "Headline1"),
387 array("type" => "heading2", "class" => "Headline2"),
388 array("type" => "heading3", "class" => "Headline3"),
389 array("type" => "text_inline", "class" => "Comment"),
390 array("type" => "text_inline", "class" => "Emph"),
391 array("type" => "text_inline", "class" => "Quotation"),
392 array("type" => "text_inline", "class" => "Strong"),
393 array("type" => "text_inline", "class" => "Accent"),
394 array("type" => "text_inline", "class" => "Important"),
395 array("type" => "code_inline", "class" => "CodeInline"),
396 array("type" => "sup", "class" => "Sup"),
397 array("type" => "sub", "class" => "Sub"),
398 array("type" => "link", "class" => "IntLink"),
399 array("type" => "link", "class" => "ExtLink"),
400 array("type" => "link", "class" => "FootnoteLink"),
401 array("type" => "link", "class" => "FileLink"),
402 array("type" => "link", "class" => "GlossaryLink"),
403 array("type" => "media_cont", "class" => "MediaContainer"),
404 array("type" => "media_cont", "class" => "MediaContainerMax50"),
405 array("type" => "media_cont", "class" => "MediaContainerFull100"),
406 array("type" => "table", "class" => "StandardTable"),
407 array("type" => "media_caption", "class" => "MediaCaption"),
408 array("type" => "iim", "class" => "ContentPopup"),
409 array("type" => "marker", "class" => "Marker"),
410 array("type" => "page_frame", "class" => "PageFrame"),
411 array("type" => "page_cont", "class" => "PageContainer"),
412 array("type" => "page", "class" => "Page"),
413 array("type" => "page_tnav", "class" => "TopNavigation"),
414 array("type" => "page_bnav", "class" => "BottomNavigation"),
415 array("type" => "page_lnav", "class" => "LeftNavigation"),
416 array("type" => "page_rnav", "class" => "RightNavigation"),
417 array("type" => "page_lnavlink", "class" => "LeftNavigationLink"),
418 array("type" => "page_rnavlink", "class" => "RightNavigationLink"),
419 array("type" => "page_lnavimage", "class" => "LeftNavigationImage"),
420 array("type" => "page_rnavimage", "class" => "RightNavigationImage"),
421 array("type" => "page_fn", "class" => "Footnote"),
422 array("type" => "page_title", "class" => "PageTitle"),
423 array("type" => "list_o", "class" => "NumberedList"),
424 array("type" => "list_u", "class" => "BulletedList"),
425 array("type" => "list_item", "class" => "StandardListItem"),
426 array("type" => "question", "class" => "Standard"),
427 array("type" => "question", "class" => "SingleChoice"),
428 array("type" => "question", "class" => "MultipleChoice"),
429 array("type" => "question", "class" => "TextQuestion"),
430 array("type" => "question", "class" => "OrderingQuestion"),
431 array("type" => "question", "class" => "MatchingQuestion"),
432 array("type" => "question", "class" => "ImagemapQuestion"),
433 array("type" => "question", "class" => "ErrorText"),
434 array("type" => "question", "class" => "TextSubset"),
435 array("type" => "question", "class" => "ClozeTest"),
436 array("type" => "qtitle", "class" => "Title"),
437 array("type" => "qanswer", "class" => "Answer"),
438 array("type" => "qimg", "class" => "QuestionImage"),
439 array("type" => "qimgd", "class" => "ImageDetailsLink"),
440 array("type" => "qordul", "class" => "OrderList"),
441 array("type" => "qordli", "class" => "OrderListItem"),
442 array("type" => "qordul", "class" => "OrderListHorizontal"),
443 array("type" => "qordli", "class" => "OrderListItemHorizontal"),
444 array("type" => "qetitem", "class" => "ErrorTextItem"),
445 array("type" => "qetitem", "class" => "ErrorTextSelected"),
446 array("type" => "qetcorr", "class" => "ErrorTextCorrected"),
447 array("type" => "qinput", "class" => "TextInput"),
448 array("type" => "qlinput", "class" => "LongTextInput"),
449 array("type" => "qsubmit", "class" => "Submit"),
450 array("type" => "qfeedr", "class" => "FeedbackRight"),
451 array("type" => "qfeedw", "class" => "FeedbackWrong"),
452 array("type" => "qover", "class" => "Correct"),
453 array("type" => "qover", "class" => "Inorrect"),
454 array("type" => "qover", "class" => "StatusMessage"),
455 array("type" => "qover", "class" => "WrongAnswersMessage"),
456 array("type" => "flist_cont", "class" => "FileListContainer"),
457 array("type" => "flist_head", "class" => "FileListHeading"),
458 array("type" => "flist", "class" => "FileList"),
459 array("type" => "flist_li", "class" => "FileListItem"),
460 array("type" => "flist_a", "class" => "FileListItemLink")
461 );
462
463 public static array $templates = array(
464 "table" => array(
465 "table" => "table",
466 "caption" => "table_caption",
467 "row_head" => "table_cell",
468 "row_foot" => "table_cell",
469 "col_head" => "table_cell",
470 "col_foot" => "table_cell",
471 "odd_row" => "table_cell",
472 "even_row" => "table_cell",
473 "odd_col" => "table_cell",
474 "even_col" => "table_cell"),
475 "vaccordion" => array(
476 "va_cntr" => "va_cntr",
477 "va_icntr" => "va_icntr",
478 "va_ihead" => "va_ihead",
479 "va_iheada" => "va_iheada",
480 "va_ihcap" => "va_ihcap",
481 "va_icont" => "va_icont"
482 ),
483 "haccordion" => array(
484 "ha_cntr" => "ha_cntr",
485 "ha_icntr" => "ha_icntr",
486 "ha_ihead" => "ha_ihead",
487 "ha_iheada" => "ha_iheada",
488 "ha_ihcap" => "ha_ihcap",
489 "ha_icont" => "ha_icont"
490 ),
491 "carousel" => array(
492 "ca_cntr" => "ca_cntr",
493 "ca_icntr" => "ca_icntr",
494 "ca_ihead" => "ca_ihead",
495 "ca_icont" => "ca_icont"
496 )
497 );
498
499 // basic style xml file, image directory and dom
500 protected static string $basic_style_file = "./libs/ilias/Style/basic_style/style.xml";
501 protected static string $basic_style_zip = "./libs/ilias/Style/basic_style/style.zip";
502 protected static string $basic_style_image_dir = "./libs/ilias/Style/basic_style/images";
503 protected static ?DOMDocument $basic_style_dom = null;
504
505 public function __construct(
506 int $a_id = 0,
507 bool $a_call_by_reference = false
508 ) {
509 global $DIC;
510
511 $this->db = $DIC->database();
512 $this->lng = $DIC->language();
513 $this->type = "sty";
514 $this->style = array();
515 $this->ilias = $DIC["ilias"];
516
517 if ($a_call_by_reference) {
518 $this->ilias->raiseError("Can't instantiate style object via reference id.", $this->ilias->error_obj->FATAL);
519 }
520 parent::__construct($a_id, false);
521 $this->repo = $DIC->contentStyle()->internal()->repo();
522 }
523
524 public static function getBasicZipPath(): string
525 {
527 }
528
532 public function setUpToDate(bool $a_up_to_date = true): void
533 {
534 $this->up_to_date = $a_up_to_date;
535 }
536
537 public function getUpToDate(): bool
538 {
539 return $this->up_to_date;
540 }
541
542 public function setScope(int $a_scope): void
543 {
544 $this->scope = $a_scope;
545 }
546
547 public function getScope(): int
548 {
549 return $this->scope;
550 }
551
552 public static function _writeUpToDate(
553 int $a_id,
554 bool $a_up_to_date
555 ): void {
556 global $DIC;
557
558 $ilDB = $DIC->database();
559
560 $q = "UPDATE style_data SET uptodate = " .
561 $ilDB->quote((int) $a_up_to_date, "integer") .
562 " WHERE id = " . $ilDB->quote($a_id, "integer");
563 $ilDB->manipulate($q);
564 }
565
566 public static function writeOwner($obj_id, $style_id)
567 {
568 global $DIC;
569 $ilDB = $DIC->database();
570
571 $q = "UPDATE style_data SET owner_obj = " .
572 $ilDB->quote((int) $obj_id, "integer") .
573 " WHERE id = " . $ilDB->quote($style_id, "integer");
574 $ilDB->manipulate($q);
575 }
576
577 public static function _lookupUpToDate(int $a_id): bool
578 {
579 global $DIC;
580
581 $ilDB = $DIC->database();
582
583 $q = "SELECT uptodate FROM style_data " .
584 " WHERE id = " . $ilDB->quote($a_id, "integer");
585 $res = $ilDB->query($q);
586 $sty = $ilDB->fetchAssoc($res);
587
588 return (bool) $sty["uptodate"];
589 }
590
594 public static function _writeStandard(
595 int $a_id,
596 bool $a_std
597 ): void {
598 global $DIC;
599
600 $ilDB = $DIC->database();
601
602 $q = "UPDATE style_data SET standard = " .
603 $ilDB->quote((int) $a_std, "integer") .
604 " WHERE id = " . $ilDB->quote($a_id, "integer");
605 $ilDB->manipulate($q);
606 }
607
608 public static function _writeScope(int $a_id, int $a_scope): void
609 {
610 global $DIC;
611
612 $ilDB = $DIC->database();
613
614 $q = "UPDATE style_data SET category = " .
615 $ilDB->quote($a_scope, "integer") .
616 " WHERE id = " . $ilDB->quote($a_id, "integer");
617 $ilDB->manipulate($q);
618 }
619
623 public static function _lookupStandard(int $a_id): bool
624 {
625 global $DIC;
626
627 $ilDB = $DIC->database();
628
629 $q = "SELECT * FROM style_data " .
630 " WHERE id = " . $ilDB->quote($a_id, "integer");
631 $res = $ilDB->query($q);
632 $sty = $ilDB->fetchAssoc($res);
633
634 return (bool) ($sty["standard"] ?? false);
635 }
636
637 public static function _writeActive(int $a_id, bool $a_active): void
638 {
639 global $DIC;
640
641 $ilDB = $DIC->database();
642
643 $q = "UPDATE style_data SET active = " .
644 $ilDB->quote((int) $a_active, "integer") .
645 " WHERE id = " . $ilDB->quote($a_id, "integer");
646 $ilDB->manipulate($q);
647 }
648
652 public static function _lookupActive(int $a_id): bool
653 {
654 global $DIC;
655
656 $ilDB = $DIC->database();
657
658 $q = "SELECT * FROM style_data " .
659 " WHERE id = " . $ilDB->quote($a_id, "integer");
660 $res = $ilDB->query($q);
661 $sty = $ilDB->fetchAssoc($res);
662
663 return (bool) $sty["active"];
664 }
665
670 public static function _getStandardStyles(
671 bool $a_exclude_default_style = false,
672 bool $a_include_deactivated = false,
673 int $a_scope = 0
674 ): array {
675 global $DIC;
676
677 $ilDB = $DIC->database();
678 $ilSetting = $DIC->settings();
679 $tree = $DIC->repositoryTree();
680
681 $default_style = $ilSetting->get("default_content_style_id");
682
683 $and_str = "";
684 if (!$a_include_deactivated) {
685 $and_str = " AND active = 1";
686 }
687
688 $q = "SELECT * FROM style_data " .
689 " WHERE standard = 1" . $and_str;
690 $res = $ilDB->query($q);
691 $styles = array();
692 while ($sty = $ilDB->fetchAssoc($res)) {
693 if (!$a_exclude_default_style || $default_style != $sty["id"]) {
694 // check scope
695 if ($a_scope > 0 && $sty["category"] > 0) {
696 if ($tree->isInTree((int) $sty["category"]) &&
697 $tree->isInTree($a_scope)) {
698 $path = $tree->getPathId($a_scope);
699 if (!in_array((int) $sty["category"], $path)) {
700 continue;
701 }
702 }
703 }
704 $styles[(int) $sty["id"]] = ilObject::_lookupTitle((int) $sty["id"]);
705 }
706 }
707
708 return $styles;
709 }
710
711
717 public static function _getClonableContentStyles(): array
718 {
719 global $DIC;
720
721 $ilAccess = $DIC->access();
722 $ilDB = $DIC->database();
723
724 $clonable_styles = array();
725
726 $q = "SELECT * FROM style_data";
727 $style_set = $ilDB->query($q);
728 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
729 $clonable = false;
730 if ($style_rec["standard"] == 1) {
731 if ($style_rec["active"] == 1) {
732 $clonable = true;
733 }
734 } else {
735 $obj_ids = ilObjContentObject::_lookupContObjIdByStyleId((int) $style_rec["id"]);
736 if (count($obj_ids) == 0) {
737 $obj_ids = self::lookupObjectForStyle((int) $style_rec["id"]);
738 }
739 foreach ($obj_ids as $id) {
740 $ref = ilObject::_getAllReferences((int) $id);
741 foreach ($ref as $ref_id) {
742 if ($ilAccess->checkAccess("write", "", $ref_id)) {
743 $clonable = true;
744 }
745 }
746 }
747 }
748 if ($clonable) {
749 $clonable_styles[(int) $style_rec["id"]] =
750 ilObject::_lookupTitle((int) $style_rec["id"]);
751 }
752 }
753
754 asort($clonable_styles);
755
756 return $clonable_styles;
757 }
758
759 public static function _getBasicStyleDom(): DOMDocument
760 {
761 if (!is_object(self::$basic_style_dom)) {
762 self::$basic_style_dom = new DOMDocument();
763 self::$basic_style_dom->load(self::$basic_style_file);
764 }
765
766 return self::$basic_style_dom;
767 }
768
769 public static function getBasicImageDir(): string
770 {
771 return self::$basic_style_image_dir;
772 }
773
774
778 public function create(
779 int $a_from_style = 0,
780 bool $a_import_mode = false
781 ): int {
782 global $DIC;
783
784 $ilDB = $this->db;
785
786 $id = parent::create();
787
788 $service = $DIC->contentStyle()
789 ->internal();
790 $access_manager = $service->domain()->access(
791 0,
792 $DIC->user()->getId()
793 );
794 $access_manager->enableWrite(true);
795 $color_manager = $service->domain()->color($this->getId(), $access_manager);
796
797 if ($a_from_style == 0) {
798 if (!$a_import_mode) {
799 // copy styles from basic style
800 $this->createFromXMLFile(self::$basic_style_file, true);
801
802 // copy images from basic style
803 $this->createImagesDirectory();
804
805 // cross filesystem (lib -> web) rCopy
807 self::$basic_style_image_dir,
808 $this->getImagesDirectory()
809 );
810 } else {
811 // add style_data record
812 $q = "INSERT INTO style_data (id, uptodate, category) VALUES " .
813 "(" . $ilDB->quote($this->getId(), "integer") . ", 0," .
814 $ilDB->quote($this->getScope(), "integer") . ")";
815 $ilDB->manipulate($q);
817 }
818 } else {
819 // get style parameter records
820 $def = array();
821 $q = "SELECT * FROM style_parameter WHERE style_id = " .
822 $ilDB->quote($a_from_style, "integer");
823 $par_set = $ilDB->query($q);
824 while ($par_rec = $ilDB->fetchAssoc($par_set)) {
825 $def[] = array("tag" => $par_rec["tag"], "class" => $par_rec["class"],
826 "parameter" => $par_rec["parameter"], "value" => $par_rec["value"],
827 "type" => $par_rec["type"], "mq_id" => $par_rec["mq_id"], "custom" => $par_rec["custom"]);
828 }
829
830 $char_repo = $this->repo->characteristic();
831 $char_repo->cloneAllFromStyle($a_from_style, $this->getId());
832
833
834 // copy media queries
835 $from_style = new ilObjStyleSheet($a_from_style);
836 $mqs = $from_style->getMediaQueries();
837 $mq_mapping = array();
838 foreach ($mqs as $mq) {
839 $nid = $this->addMediaQuery($mq["mquery"]);
840 $mq_mapping[$mq["id"]] = $nid;
841 }
842
843 // default style settings
844 foreach ($def as $sty) {
845 $id = $ilDB->nextId("style_parameter");
846 $q = "INSERT INTO style_parameter (id, style_id, tag, class, parameter, value, type, mq_id, custom) VALUES " .
847 "(" .
848 $ilDB->quote($id, "integer") . "," .
849 $ilDB->quote($this->getId(), "integer") . "," .
850 $ilDB->quote($sty["tag"], "text") . "," .
851 $ilDB->quote($sty["class"], "text") . "," .
852 $ilDB->quote($sty["parameter"], "text") . "," .
853 $ilDB->quote($sty["value"], "text") . "," .
854 $ilDB->quote($sty["type"], "text") . "," .
855 $ilDB->quote((int) ($mq_mapping[$sty["mq_id"]] ?? 0), "integer") . "," .
856 $ilDB->quote($sty["custom"], "integer") .
857 ")";
858 $ilDB->manipulate($q);
859 }
860
861 // add style_data record
862 $q = "INSERT INTO style_data (id, uptodate, category) VALUES " .
863 "(" . $ilDB->quote($this->getId(), "integer") . ", 0," .
864 $ilDB->quote($this->getScope(), "integer") . ")";
865 $ilDB->manipulate($q);
866
867 // copy images
868 $this->createImagesDirectory();
870 $from_style->getImagesDirectory(),
871 $this->getImagesDirectory()
872 );
873
874 // copy colors
875 $colors = $from_style->getColors();
876 foreach ($colors as $c) {
877 $color_manager->addColor($c["name"], $c["code"]);
878 }
879
880 // copy templates
882 foreach ($tcts as $tct => $v) {
883 $templates = $from_style->getTemplates($tct);
884 foreach ($templates as $t) {
885 $this->addTemplate($tct, $t["name"], $t["classes"]);
886 }
887 }
888 }
889
890 $this->read();
891 if (!$a_import_mode) {
892 $this->writeCSSFile();
893 }
894
895 return $id;
896 }
897
901 public function characteristicExists(
902 string $a_char,
903 string $a_style_type
904 ): bool {
905 $ilDB = $this->db;
906
907 $set = $ilDB->queryF(
908 "SELECT style_id FROM style_char WHERE style_id = %s AND characteristic = %s AND type = %s",
909 array("integer", "text", "text"),
910 array($this->getId(), $a_char, $a_style_type)
911 );
912 if ($ilDB->fetchAssoc($set)) {
913 return true;
914 }
915 return false;
916 }
917
918 public function addCharacteristic(
919 string $a_type,
920 string $a_char,
921 bool $a_hidden = false,
922 int $order_nr = 0,
923 bool $outdated = false
924 ): void {
925 $ilDB = $this->db;
926
927 // delete characteristic record
928 $ilDB->insert("style_char", [
929 "style_id" => ["integer", $this->getId()],
930 "type" => ["text", $a_type],
931 "characteristic" => ["text", $a_char],
932 "hide" => ["integer", (int) $a_hidden],
933 "outdated" => ["integer", (int) $outdated],
934 "order_nr" => ["integer", $order_nr]
935 ]);
936
937 $this->setUpToDate(false);
938 $this->_writeUpToDate($this->getId(), false);
939 }
940
944 public function getCharacteristics(
945 string $a_type = "",
946 bool $a_no_hidden = false,
947 bool $a_include_core = true
948 ): array {
949 $chars = array();
950
951 if ($a_type == "") {
952 $chars = $this->chars;
953 }
954 if (isset($this->chars_by_type[$a_type])) {
955 foreach ($this->chars_by_type[$a_type] as $c) {
956 if ($a_include_core || !self::isCoreStyle($a_type, $c)) {
957 $chars[] = $c;
958 }
959 }
960 }
961
962 if ($a_no_hidden) {
963 foreach ($chars as $k => $char) {
964 if ($a_type == "" && $this->hidden_chars[$char["type"] . ":" . $char["class"]]) {
965 unset($chars[$k]);
966 } elseif ($this->hidden_chars[$a_type . ":" . $char] ?? false) {
967 unset($chars[$k]);
968 }
969 }
970 }
971
972 return $chars;
973 }
974
975 public function setCharacteristics(array $a_chars): void
976 {
977 $this->chars = $a_chars;
978 }
979
983 public function saveHideStatus(
984 string $a_type,
985 string $a_char,
986 bool $a_hide
987 ): void {
988 $ilDB = $this->db;
989
990 $ilDB->manipulate(
991 "UPDATE style_char SET " .
992 " hide = " . $ilDB->quote((int) $a_hide, "integer") .
993 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
994 " type = " . $ilDB->quote($a_type, "text") . " AND " .
995 " characteristic = " . $ilDB->quote($a_char, "text")
996 );
997 }
998
1002 public function getHideStatus(
1003 string $a_type,
1004 string $a_char
1005 ): bool {
1006 $ilDB = $this->db;
1007
1008 $set = $ilDB->query(
1009 "SELECT hide FROM style_char " .
1010 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
1011 " type = " . $ilDB->quote($a_type, "text") . " AND " .
1012 " characteristic = " . $ilDB->quote($a_char, "text")
1013 );
1014 $rec = $ilDB->fetchAssoc($set);
1015
1016 return (bool) ($rec["hide"] ?? false);
1017 }
1018
1022 public function ilClone(): int
1023 {
1024 $lng = $this->lng;
1025
1026 $lng->loadLanguageModule("style");
1027
1028 $new_obj = new ilObjStyleSheet();
1029 $new_obj->setTitle($this->getTitle() . " (" . $lng->txt("sty_acopy") . ")");
1030 $new_obj->setType($this->getType());
1031 $new_obj->setDescription($this->getDescription());
1032 $new_obj->create($this->getId());
1033
1034 $new_obj->writeStyleSetting(
1035 "disable_auto_margins",
1036 $this->lookupStyleSetting("disable_auto_margins")
1037 );
1038
1039 return $new_obj->getId();
1040 }
1041
1045 public function copyImagesToDir(string $a_target): void
1046 {
1047 ilFileUtils::rCopy($this->getImagesDirectory(), $a_target);
1048 }
1049
1059 public function addParameter(
1060 string $a_tag,
1061 string $a_par,
1062 string $a_type,
1063 int $a_mq_id = 0,
1064 bool $a_custom = false
1065 ): void {
1066 $ilDB = $this->db;
1067
1068 $avail_params = $this->getAvailableParameters();
1069 $tag = explode(".", $a_tag);
1070 $value = $avail_params[$a_par][0];
1071 $id = $ilDB->nextId("style_parameter");
1072 $q = "INSERT INTO style_parameter (id,style_id, type, tag, class, parameter, value, mq_id, custom) VALUES " .
1073 "(" .
1074 $ilDB->quote($id, "integer") . "," .
1075 $ilDB->quote($this->getId(), "integer") . "," .
1076 $ilDB->quote($a_type, "text") . "," .
1077 $ilDB->quote($tag[0], "text") . "," .
1078 $ilDB->quote($tag[1], "text") . "," .
1079 $ilDB->quote($a_par, "text") . "," .
1080 $ilDB->quote($value, "text") . "," .
1081 $ilDB->quote($a_mq_id, "integer") . "," .
1082 $ilDB->quote($a_custom, "integer") .
1083 ")";
1084 $ilDB->manipulate($q);
1085 $this->read();
1086 $this->writeCSSFile();
1087 }
1088
1093 public function createImagesDirectory(): void
1094 {
1096 }
1097
1102 public static function _createImagesDirectory(
1103 int $a_style_id
1104 ): void {
1105 global $DIC;
1106
1107 $ilErr = $DIC["ilErr"];
1108
1109 $sty_data_dir = ilFileUtils::getWebspaceDir() . "/sty";
1110 if (!is_dir($sty_data_dir)) {
1111 ilFileUtils::makeDir($sty_data_dir);
1112 }
1113 if (!is_writable($sty_data_dir)) {
1114 $ilErr->raiseError("Style data directory (" . $sty_data_dir
1115 . ") not writeable.", $ilErr->FATAL);
1116 }
1117
1118 $style_dir = $sty_data_dir . "/sty_" . $a_style_id;
1119 if (!is_dir($style_dir)) {
1120 ilFileUtils::makeDir($style_dir);
1121 }
1122 if (!is_dir($style_dir)) {
1123 $ilErr->raiseError("Creation of style directory failed (" .
1124 $style_dir . ").", $ilErr->FATAL);
1125 }
1126
1127 // create images subdirectory
1128 $im_dir = $style_dir . "/images";
1129 if (!is_dir($im_dir)) {
1130 ilFileUtils::makeDir($im_dir);
1131 }
1132 if (!is_dir($im_dir)) {
1133 $ilErr->raiseError("Creation of Import Directory failed (" .
1134 $im_dir . ").", $ilErr->FATAL);
1135 }
1136
1137 // create thumbnails directory
1138 $thumb_dir = $style_dir . "/images/thumbnails";
1139 ilFileUtils::makeDir($thumb_dir);
1140 if (!is_dir($thumb_dir)) {
1141 $ilErr->raiseError("Creation of Import Directory failed (" .
1142 $thumb_dir . ").", $ilErr->FATAL);
1143 }
1144 }
1145
1146 public function getImagesDirectory(): string
1147 {
1149 }
1150
1151 public static function _getImagesDirectory(int $a_style_id): string
1152 {
1153 return ilFileUtils::getWebspaceDir() . "/sty/sty_" . $a_style_id .
1154 "/images";
1155 }
1156
1157 public function getThumbnailsDirectory(): string
1158 {
1159 return $this->getImagesDirectory() .
1160 "/thumbnails";
1161 }
1162
1166 public function deleteParameter(int $a_id): void
1167 {
1168 $ilDB = $this->db;
1169
1170 $q = "DELETE FROM style_parameter WHERE id = " .
1171 $ilDB->quote($a_id, "integer");
1172 $ilDB->query($q);
1173 }
1174
1175
1183 public function deleteCustomStylePars(
1184 string $a_tag,
1185 string $a_class,
1186 string $a_type,
1187 int $a_mq_id = 0
1188 ): void {
1189 $ilDB = $this->db;
1190
1191 $q = "DELETE FROM style_parameter WHERE " .
1192 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
1193 " tag = " . $ilDB->quote($a_tag, "text") . " AND " .
1194 " class = " . $ilDB->quote($a_class, "text") . " AND " .
1195 " mq_id = " . $ilDB->quote($a_mq_id, "integer") . " AND " .
1196 " custom = " . $ilDB->quote(1, "integer") . " AND " .
1197 " " . $ilDB->equals("type", $a_type, "text", true);
1198
1199 $ilDB->manipulate($q);
1200 }
1201
1205 public function deleteStyleParOfChar(
1206 string $a_type,
1207 string $a_class
1208 ): void {
1209 $ilDB = $this->db;
1210
1211 $q = "DELETE FROM style_parameter WHERE " .
1212 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
1213 " class = " . $ilDB->quote($a_class, "text") . " AND " .
1214 " " . $ilDB->equals("type", $a_type, "text", true);
1215
1216 $ilDB->manipulate($q);
1217 }
1218
1219
1220 public function delete(): bool
1221 {
1222 $ilDB = $this->db;
1223
1224 // delete object
1225 parent::delete();
1226
1227 // check whether this style is global default
1228 $def_style = $this->ilias->getSetting("default_content_style_id");
1229 if ($def_style == $this->getId()) {
1230 $this->ilias->deleteSetting("default_content_style_id");
1231 }
1232
1233 // check whether this style is global fixed
1234 $fixed_style = $this->ilias->getSetting("fixed_content_style_id");
1235 if ($fixed_style == $this->getId()) {
1236 $this->ilias->deleteSetting("fixed_content_style_id");
1237 }
1238
1239 // delete style parameter
1240 $q = "DELETE FROM style_parameter WHERE style_id = " .
1241 $ilDB->quote($this->getId(), "integer");
1242 $ilDB->manipulate($q);
1243
1244 // delete style file
1245 $css_file_name = ilFileUtils::getWebspaceDir() . "/css/style_" . $this->getId() . ".css";
1246 if (is_file($css_file_name)) {
1247 unlink($css_file_name);
1248 }
1249
1250 // delete media queries
1251 $ilDB->manipulate(
1252 "DELETE FROM sty_media_query WHERE " .
1253 " style_id = " . $ilDB->quote($this->getId(), "integer")
1254 );
1255
1256 // delete entries in learning modules
1258
1259 // delete style data record
1260 $q = "DELETE FROM style_data WHERE id = " .
1261 $ilDB->quote($this->getId(), "integer");
1262 $ilDB->manipulate($q);
1263
1264 return true;
1265 }
1266
1267
1271 public function read(): void
1272 {
1273 $ilDB = $this->db;
1274
1275 parent::read();
1276
1277 $q = "SELECT * FROM style_parameter WHERE style_id = " .
1278 $ilDB->quote($this->getId(), "integer") . " ORDER BY tag, class, type, mq_id ";
1279 $style_set = $ilDB->query($q);
1280 $ctag = "";
1281 $cclass = "";
1282 $ctype = "";
1283 $cmq_id = 0;
1284 $this->style = array();
1285 // workaround for bug #17586, see also http://stackoverflow.com/questions/3066356/multiple-css-classes-properties-overlapping-based-on-the-order-defined
1286 // e.g. ha_iheada must be written after ha_ihead, since they are acting on the same dom node
1287 // styles that must be added at the end
1288 $this->end_styles = array();
1289 $tag = null;
1290 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
1291 if ($style_rec["tag"] != $ctag || $style_rec["class"] != $cclass
1292 || $style_rec["type"] != $ctype || $style_rec["mq_id"] != $cmq_id) {
1293 // add current tag array to style array
1294 if (is_array($tag)) {
1295 if (in_array($ctype, array("ha_iheada", "va_iheada"))) {
1296 $this->end_styles[] = $tag;
1297 } else {
1298 $this->style[] = $tag;
1299 }
1300 }
1301 $tag = array();
1302 }
1303 $ctag = $style_rec["tag"];
1304 $cclass = $style_rec["class"];
1305 $ctype = $style_rec["type"];
1306 $cmq_id = $style_rec["mq_id"];
1307 $tag[] = $style_rec;
1308 // added $cmq_id
1309 $this->style_class[$ctype][$cclass][$cmq_id][$style_rec["parameter"]] = $style_rec["value"];
1310 }
1311 if (is_array($tag)) {
1312 $this->style[] = $tag;
1313 }
1314 foreach ($this->end_styles as $s) {
1315 $this->style[] = $s;
1316 }
1317 //var_dump($this->style_class);
1318 $q = "SELECT * FROM style_data WHERE id = " .
1319 $ilDB->quote($this->getId(), "integer");
1320 $res = $ilDB->query($q);
1321 $sty = $ilDB->fetchAssoc($res);
1322 $this->setUpToDate((bool) $sty["uptodate"]);
1323 $this->setScope((int) $sty["category"]);
1324
1325 // get style characteristics records
1326 $this->chars = array();
1327 $this->chars_by_type = array();
1328 $q = "SELECT * FROM style_char WHERE style_id = " .
1329 $ilDB->quote($this->getId(), "integer") .
1330 " ORDER BY type ASC, characteristic ASC";
1331 $par_set = $ilDB->query($q);
1332 while ($par_rec = $ilDB->fetchAssoc($par_set)) {
1333 $this->chars[] = array("type" => $par_rec["type"], "class" => $par_rec["characteristic"], "hide" => $par_rec["hide"]);
1334 $this->chars_by_type[$par_rec["type"]][] = $par_rec["characteristic"];
1335 if ($par_rec["hide"]) {
1336 $this->hidden_chars[$par_rec["type"] . ":" . $par_rec["characteristic"]] = true;
1337 }
1338 }
1339 // var_dump($this->style); exit;
1340 }
1341
1345 public function writeCSSFile(
1346 string $a_target_file = "",
1347 string $a_image_dir = ""
1348 ): void {
1349 $style = $this->getStyle();
1350
1351 if (!is_dir(ilFileUtils::getWebspaceDir() . "/css")) {
1353 }
1354
1355 if ($a_target_file == "") {
1356 $css_file_name = ilFileUtils::getWebspaceDir() . "/css/style_" . $this->getId() . ".css";
1357 } else {
1358 $css_file_name = $a_target_file;
1359 }
1360 $css_file = fopen($css_file_name, 'wb');
1361
1362 $page_background = "";
1363
1364 $mqs = array(array("mquery" => "", "id" => 0));
1365 foreach ($this->getMediaQueries() as $mq) {
1366 $mqs[] = $mq;
1367 }
1368
1369 // iterate all media queries
1370 foreach ($mqs as $mq) {
1371 if ($mq["id"] > 0) {
1372 fwrite($css_file, "@media " . $mq["mquery"] . " {\n");
1373 }
1374 reset($style);
1375 foreach ($style as $tag) {
1376 if ($tag[0]["mq_id"] != $mq["id"]) {
1377 continue;
1378 }
1379 fwrite($css_file, $tag[0]["tag"] . ".ilc_" . $tag[0]["type"] . "_" . $tag[0]["class"] . "\n");
1380 // echo "<br>";
1381 // var_dump($tag[0]["type"]);
1382 if ($tag[0]["tag"] == "td") {
1383 fwrite($css_file, ",th" . ".ilc_" . $tag[0]["type"] . "_" . $tag[0]["class"] . "\n");
1384 }
1385 if (in_array($tag[0]["tag"], array("h1", "h2", "h3"))) {
1386 fwrite($css_file, ",div.ilc_text_block_" . $tag[0]["class"] . "\n");
1387 fwrite($css_file, ",html.il-no-tiny-bg body#tinymce.ilc_text_block_" . $tag[0]["class"] . "\n");
1388 }
1389 if ($tag[0]["type"] == "section") { // sections can use a tags, if links are used
1390 fwrite($css_file, ",div a.ilc_" . $tag[0]["type"] . "_" . $tag[0]["class"] . "\n");
1391 }
1392 if ($tag[0]["type"] == "text_block") {
1393 fwrite($css_file, ",html.il-no-tiny-bg body#tinymce.ilc_text_block_" . $tag[0]["class"] . "\n");
1394 }
1395 fwrite($css_file, "{\n");
1396
1397 // collect table border attributes
1398 $t_border = array();
1399
1400 foreach ($tag as $par) {
1401 $cur_par = $par["parameter"];
1402 $cur_val = $par["value"];
1403
1404 // replace named colors
1405 if (is_int(strpos($cur_par, "color")) && substr(trim($cur_val), 0, 1) == "!") {
1406 $cur_val = $this->getColorCodeForName(substr($cur_val, 1));
1407 }
1408
1409 if ($tag[0]["type"] == "table" && is_int(strpos($par["parameter"], "border"))) {
1410 $t_border[$cur_par] = $cur_val;
1411 }
1412
1413 if (in_array($cur_par, array("background-image", "list-style-image"))) {
1414 if (is_int(strpos($cur_val, "/"))) { // external
1415 $cur_val = "url('" . $cur_val . "')";
1416 } else { // internal
1417 if ($a_image_dir == "") {
1418 $cur_val = "url('../sty/sty_" . $this->getId() . "/images/" . $cur_val . "')";
1419 } else {
1420 $cur_val = "url('" . $a_image_dir . "/" . $cur_val . "')";
1421 }
1422 }
1423 }
1424
1425 if ($cur_par == "opacity") {
1426 $cur_val = ((int) $cur_val) / 100;
1427 }
1428
1429 fwrite($css_file, "\t" . $cur_par . ": " . $cur_val . ";\n");
1430
1431 // IE6 fix for minimum height
1432 /*
1433 if ($cur_par == "min-height") {
1434 fwrite($css_file, "\t" . "height" . ": " . "auto !important" . ";\n");
1435 fwrite($css_file, "\t" . "height" . ": " . $cur_val . ";\n");
1436 }*/
1437
1438 // opacity fix
1439 if ($cur_par == "opacity") {
1440 fwrite($css_file, "\t" . '-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=' . ($cur_val * 100) . ')"' . ";\n");
1441 fwrite($css_file, "\t" . 'filter: alpha(opacity=' . ($cur_val * 100) . ')' . ";\n");
1442 fwrite($css_file, "\t" . '-moz-opacity: ' . $cur_val . ";\n");
1443 }
1444
1445 // transform fix
1446 if ($cur_par == "transform") {
1447 fwrite($css_file, "\t" . '-webkit-transform: ' . $cur_val . ";\n");
1448 fwrite($css_file, "\t" . '-moz-transform: ' . $cur_val . ";\n");
1449 fwrite($css_file, "\t" . '-ms-transform: ' . $cur_val . ";\n");
1450 }
1451
1452 // transform-origin fix
1453 if ($cur_par == "transform-origin") {
1454 fwrite($css_file, "\t" . '-webkit-transform-origin: ' . $cur_val . ";\n");
1455 fwrite($css_file, "\t" . '-moz-transform-origin: ' . $cur_val . ";\n");
1456 fwrite($css_file, "\t" . '-ms-transform-origin: ' . $cur_val . ";\n");
1457 }
1458
1459 // save page background
1460 if ($tag[0]["tag"] == "div" && $tag[0]["class"] == "Page"
1461 && $cur_par == "background-color") {
1462 $page_background = $cur_val;
1463 }
1464 }
1465 fwrite($css_file, "}\n");
1466 fwrite($css_file, "\n");
1467
1468 // use table border attributes for th td as well
1469 /* if ($tag[0]["type"] == "table")
1470 {
1471 if (count($t_border) > 0)
1472 {
1473 fwrite ($css_file, $tag[0]["tag"].".ilc_".$tag[0]["type"]."_".$tag[0]["class"]." th,".
1474 $tag[0]["tag"].".ilc_".$tag[0]["type"]."_".$tag[0]["class"]." td\n");
1475 fwrite ($css_file, "{\n");
1476 foreach ($t_border as $p => $v)
1477 {
1478 // fwrite ($css_file, "\t".$p.": ".$v.";\n");
1479 }
1480 fwrite ($css_file, "}\n");
1481 fwrite ($css_file, "\n");
1482 }
1483 }*/
1484 }
1485
1486 if ($page_background != "") {
1487 fwrite($css_file, "td.ilc_Page\n");
1488 fwrite($css_file, "{\n");
1489 fwrite($css_file, "\t" . "background-color: " . $page_background . ";\n");
1490 fwrite($css_file, "}\n");
1491 }
1492 if ($mq["id"] > 0) {
1493 fwrite($css_file, "}\n");
1494 }
1495 }
1496 fclose($css_file);
1497 // exit;
1498 $this->setUpToDate();
1499 $this->_writeUpToDate($this->getId(), true);
1500 }
1501
1508 public static function getEffectiveContentStyleId(
1509 int $a_style_id
1510 ): int {
1511 global $DIC;
1512
1513 $ilSetting = $DIC->settings();
1514
1515 // check global fixed content style
1516 $fixed_style = $ilSetting->get("fixed_content_style_id");
1517 if ($fixed_style > 0) {
1518 $a_style_id = (int) $fixed_style;
1519 }
1520
1521 // check global default style
1522 if ($a_style_id <= 0) {
1523 $a_style_id = (int) $ilSetting->get("default_content_style_id");
1524 }
1525
1526 if ($a_style_id > 0 && ilObject::_lookupType($a_style_id) === "sty") {
1527 return $a_style_id;
1528 }
1529
1530 return 0;
1531 }
1532
1533 public function getParametersOfClass(
1534 string $a_type,
1535 string $a_class,
1536 int $a_mq_id = 0
1537 ): array {
1538 if (is_array($this->style_class[$a_type][$a_class][$a_mq_id])) {
1539 return $this->style_class[$a_type][$a_class][$a_mq_id];
1540 }
1541 return array();
1542 }
1543
1548 public static function getContentStylePath(
1549 int $a_style_id,
1550 bool $add_random = true,
1551 bool $add_token = true
1552 ): string {
1553 global $DIC;
1554
1555 $ilSetting = $DIC->settings();
1556
1557 $random = new \ilRandom();
1558 $rand = $random->int(1, 999999);
1559
1560
1561 // check global fixed content style
1562 $fixed_style = $ilSetting->get("fixed_content_style_id");
1563 if ($fixed_style > 0) {
1564 $a_style_id = (int) $fixed_style;
1565 }
1566
1567 // check global default style
1568 if ($a_style_id <= 0) {
1569 $a_style_id = (int) $ilSetting->get("default_content_style_id");
1570 }
1571
1572 if ($a_style_id > 0 && ilObject::_exists($a_style_id)) {
1573 // check whether file is up to date
1574 if (!ilObjStyleSheet::_lookupUpToDate($a_style_id)) {
1575 $style = new ilObjStyleSheet($a_style_id);
1576 $style->writeCSSFile();
1577 }
1578
1579 $path = ilFileUtils::getWebspaceDir("output") . "/css/style_" . $a_style_id . ".css";
1580 if ($add_random) {
1581 $path .= "?dummy=$rand";
1582 }
1583 if ($add_token) {
1585 }
1586
1587 return $path;
1588 } else { // todo: work this out
1589 return "./Services/COPage/css/content.css";
1590 }
1591 }
1592
1593 public static function getContentPrintStyle(): string
1594 {
1595 return "./Services/COPage/css/print_content.css";
1596 }
1597
1598 public static function getSyntaxStylePath(): string
1599 {
1600 return "./Services/COPage/css/syntaxhighlight.css";
1601 }
1602
1603 public static function getPlaceHolderStylePath(): string
1604 {
1605 return "./Services/COPage/css/placeholder.css";
1606 }
1607
1608 public function update(): bool
1609 {
1610 $ilDB = $this->db;
1611
1612 parent::update();
1613 $this->read(); // this could be done better
1614 $this->writeCSSFile();
1615
1616 $q = "UPDATE style_data " .
1617 "SET category = " . $ilDB->quote($this->getScope(), "integer") .
1618 " WHERE id = " . $ilDB->quote($this->getId(), "integer");
1619 $ilDB->manipulate($q);
1620
1621 return true;
1622 }
1623
1627 public function updateStyleParameter(
1628 int $a_id,
1629 string $a_value
1630 ): void {
1631 $ilDB = $this->db;
1632
1633 $q = "UPDATE style_parameter SET VALUE = " .
1634 $ilDB->quote($a_value, "text") . " WHERE id = " .
1635 $ilDB->quote($a_id, "integer");
1636 $style_set = $ilDB->manipulate($q);
1637 }
1638
1639 public function getStyle(): array
1640 {
1641 return $this->style;
1642 }
1643
1644 public function setStyle(array $a_style): void
1645 {
1646 $this->style = $a_style;
1647 }
1648
1649 public function handleXmlString(string $a_str): string
1650 {
1651 return str_replace("&", "&amp;", $a_str);
1652 }
1653
1658 public function getXML(): string
1659 {
1660 $xml = "<StyleSheet>\n";
1661
1662 // title and description
1663 $xml .= "<Title>" . $this->handleXmlString($this->getTitle()) . "</Title>";
1664 $xml .= "<Description>" . $this->handleXmlString($this->getDescription()) . "</Description>\n";
1665
1666 // style classes
1667 foreach ($this->chars as $char) {
1668 $xml .= "<Style Tag=\"" . ilObjStyleSheet::_determineTag($char["type"]) .
1669 "\" Type=\"" . $char["type"] . "\" Class=\"" . $char["class"] . "\">\n";
1670 foreach ($this->style as $style) {
1671 if ($style[0]["type"] == $char["type"] && $style[0]["class"] == $char["class"]) {
1672 foreach ($style as $tag) {
1673 $xml .= "<StyleParameter Name=\"" . $tag["parameter"] . "\" Value=\"" . $tag["value"] . "\" Custom=\"" . $tag["custom"] . "\" />\n";
1674 }
1675 }
1676 }
1677 $xml .= "</Style>\n";
1678 }
1679
1680 // colors
1681 foreach ($this->getColors() as $color) {
1682 $xml .= "<StyleColor Name=\"" . $color["name"] . "\" Code=\"" . $color["code"] . "\"/>\n";
1683 }
1684
1685 // templates
1687 foreach ($tcts as $tct => $v) {
1688 $ts = $this->getTemplates($tct);
1689
1690 foreach ($ts as $t) {
1691 $xml .= "<StyleTemplate Type=\"" . $tct . "\" Name=\"" . $t["name"] . "\">\n";
1692 foreach ($t["classes"] as $ct => $c) {
1693 if ($c != "") {
1694 $xml .= "<StyleTemplateClass ClassType=\"" . $ct . "\" Class=\"" . $c . "\"/>\n";
1695 }
1696 }
1697 $xml .= "</StyleTemplate>\n";
1698 }
1699 }
1700
1701
1702 $xml .= "</StyleSheet>";
1703 //echo "<pre>".htmlentities($xml)."</pre>"; exit;
1704 return $xml;
1705 }
1706
1707 public function createExportDirectory(): string
1708 {
1709 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1710 ilFileUtils::makeDir($sty_data_dir);
1711 if (!is_writable($sty_data_dir)) {
1712 $this->ilias->raiseError("Style data directory (" . $sty_data_dir
1713 . ") not writeable.", $this->ilias->error_obj->FATAL);
1714 }
1715
1716 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1717 ilFileUtils::makeDir($style_dir);
1718 if (!is_dir($style_dir)) {
1719 $this->ilias->raiseError("Creation of style directory failed (" .
1720 $style_dir . ").", $this->ilias->error_obj->FATAL);
1721 }
1722
1723 // create export subdirectory
1724 $ex_dir = $style_dir . "/export";
1725 ilFileUtils::makeDir($ex_dir);
1726 if (!is_dir($ex_dir)) {
1727 $this->ilias->raiseError("Creation of Import Directory failed (" .
1728 $ex_dir . ").", $this->ilias->error_obj->FATAL);
1729 }
1730
1731 return $ex_dir;
1732 }
1733
1734 public function cleanExportDirectory(): void
1735 {
1736 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1737 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1738 // create export subdirectory
1739 $ex_dir = $style_dir . "/export";
1740
1741 if (is_dir($ex_dir)) {
1742 ilFileUtils::delDir($ex_dir, true);
1743 }
1744 }
1745
1747 {
1748 $ex_dir = $this->createExportDirectory();
1749 $ex_sub_dir = $ex_dir . "/" . $this->getExportSubDir();
1750 ilFileUtils::makeDir($ex_sub_dir);
1751 if (!is_writable($ex_sub_dir)) {
1752 $this->ilias->raiseError("Style data directory (" . $ex_sub_dir
1753 . ") not writeable.", $this->ilias->error_obj->FATAL);
1754 }
1755 $ex_sub_images_dir = $ex_sub_dir . "/images";
1756 ilFileUtils::makeDir($ex_sub_images_dir);
1757 if (!is_writable($ex_sub_images_dir)) {
1758 $this->ilias->raiseError("Style data directory (" . $ex_sub_images_dir
1759 . ") not writeable.", $this->ilias->error_obj->FATAL);
1760 }
1761 }
1762
1766 public function setExportSubDir(string $a_dir): void
1767 {
1768 $this->export_sub_dir = $a_dir;
1769 }
1770
1774 public function getExportSubDir(): string
1775 {
1776 if ($this->export_sub_dir == "") {
1777 return "sty_" . $this->getId();
1778 } else {
1779 return $this->export_sub_dir;
1780 }
1781 }
1782
1789 public function export(): string
1790 {
1791 $this->cleanExportDirectory();
1792 $ex_dir = $this->createExportDirectory();
1793 $this->createExportSubDirectory();
1794 $this->exportXML($ex_dir . "/" . $this->getExportSubDir());
1795 //echo "-".$this->getImagesDirectory()."-".$ex_dir."/".$this->getExportSubDir()."/images"."-";
1797 $this->getImagesDirectory(),
1798 $ex_dir . "/" . $this->getExportSubDir() . "/images"
1799 );
1800 if (is_file($ex_dir . "/" . $this->getExportSubDir() . ".zip")) {
1801 unlink($ex_dir . "/" . $this->getExportSubDir() . ".zip");
1802 }
1804 $ex_dir . "/" . $this->getExportSubDir(),
1805 $ex_dir . "/" . $this->getExportSubDir() . ".zip"
1806 );
1807
1808 return $ex_dir . "/" . $this->getExportSubDir() . ".zip";
1809 }
1810
1814 public function exportXML(string $a_dir): void
1815 {
1816 $file = $a_dir . "/style.xml";
1817
1818 // open file
1819 if (!($fp = fopen($file, 'wb'))) {
1820 die("<b>Error</b>: Could not open \"" . $file . "\" for writing" .
1821 " in <b>" . __FILE__ . "</b> on line <b>" . __LINE__ . "</b><br />");
1822 }
1823
1824 // set file permissions
1825 chmod($file, 0770);
1826
1827 // write xml data into the file
1828 fwrite($fp, $this->getXML());
1829
1830 // close file
1831 fclose($fp);
1832 }
1833
1834 public function createImportDirectory(): string
1835 {
1836 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1837 ilFileUtils::makeDir($sty_data_dir);
1838 if (!is_writable($sty_data_dir)) {
1839 $this->ilias->raiseError("Style data directory (" . $sty_data_dir
1840 . ") not writeable.", $this->ilias->error_obj->FATAL);
1841 }
1842
1843 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1844 ilFileUtils::makeDir($style_dir);
1845 if (!is_dir($style_dir)) {
1846 $this->ilias->raiseError("Creation of style directory failed (" .
1847 $style_dir . ").", $this->ilias->error_obj->FATAL);
1848 }
1849
1850 // create import subdirectory
1851 $im_dir = $style_dir . "/import";
1852 ilFileUtils::makeDir($im_dir);
1853 if (!is_dir($im_dir)) {
1854 $this->ilias->raiseError("Creation of Import Directory failed (" .
1855 $im_dir . ").", $this->ilias->error_obj->FATAL);
1856 }
1857
1858 return $im_dir;
1859 }
1860
1868 public function import($a_file): void
1869 {
1870 parent::create();
1871
1872 $subdir = "";
1873 $im_dir = $this->createImportDirectory();
1874
1875 // handle uploaded files
1876 if (is_array($a_file)) {
1878 $a_file["tmp_name"],
1879 $a_file["name"],
1880 $im_dir . "/" . $a_file["name"]
1881 );
1882 $file_name = $a_file["name"];
1883 } else { // handle not directly uploaded files
1884 $pi = pathinfo($a_file);
1885 $file_name = $pi["basename"];
1886 copy($a_file, $im_dir . "/" . $file_name);
1887 }
1888 $file = pathinfo($file_name);
1889
1890 // unzip file
1891 if (strtolower($file["extension"]) == "zip") {
1892 ilFileUtils::unzip($im_dir . "/" . $file_name);
1893 $subdir = basename($file["basename"], "." . $file["extension"]);
1894 if (!is_dir($im_dir . "/" . $subdir)) {
1895 $subdir = "style"; // check style subdir
1896 }
1897 $xml_file = $im_dir . "/" . $subdir . "/style.xml";
1898 } else { // handle xml file directly (old style)
1899 $xml_file = $im_dir . "/" . $file_name;
1900 }
1901
1902 // load information from xml file
1903 //echo "-$xml_file-";
1904 $this->createFromXMLFile($xml_file, true);
1905
1906 // copy images
1907 $this->createImagesDirectory();
1908 if (is_dir($im_dir . "/" . $subdir . "/images")) {
1910 $im_dir . "/" . $subdir . "/images",
1911 $this->getImagesDirectory()
1912 );
1913 }
1914
1916 $this->read();
1917 $this->writeCSSFile();
1918 }
1919
1924 public function createFromXMLFile(
1925 string $a_file,
1926 bool $a_skip_parent_create = false
1927 ): void {
1928 $ilDB = $this->db;
1929
1930 $this->is_3_10_skin = false;
1931
1932 if (!$a_skip_parent_create) {
1933 parent::create();
1934 }
1935 $importParser = new ilStyleImportParser($a_file, $this);
1936 $importParser->startParsing();
1937
1938 // store style parameter
1939 foreach ($this->style as $style) {
1940 foreach ($style as $tag) {
1941 $id = $ilDB->nextId("style_parameter");
1942
1943 // migrate old table PageFrame/PageContainer to div
1944 if (in_array($tag["class"], array("PageFrame", "PageContainer")) &&
1945 $tag["tag"] == "table") {
1946 $tag["tag"] = "div";
1947 if ($tag["parameter"] == "width" && $tag["value"] == "100%") {
1948 continue;
1949 }
1950 }
1951
1952 $q = "INSERT INTO style_parameter (id,style_id, tag, class, parameter, type, value, custom) VALUES " .
1953 "(" .
1954 $ilDB->quote($id, "integer") . "," .
1955 $ilDB->quote($this->getId(), "integer") . "," .
1956 $ilDB->quote($tag["tag"], "text") . "," .
1957 $ilDB->quote($tag["class"], "text") . "," .
1958 $ilDB->quote($tag["parameter"], "text") . "," .
1959 $ilDB->quote($tag["type"], "text") . "," .
1960 $ilDB->quote($tag["value"], "text") . "," .
1961 $ilDB->quote((bool) $tag["custom"], "integer") .
1962 ")";
1963 $ilDB->manipulate($q);
1964 }
1965 }
1966
1967 // store characteristics
1968 $this->is_3_10_skin = true;
1969 foreach ($this->chars as $char) {
1970 if ($char["type"] != "") {
1971 $s = substr($char["class"], strlen($char["class"]) - 6);
1972 if ($s != ":hover") {
1973 $ilDB->replace(
1974 "style_char",
1975 array(
1976 "style_id" => array("integer", $this->getId()),
1977 "type" => array("text", $char["type"]),
1978 "characteristic" => array("text", ilStr::subStr($char["class"], 0, 30))),
1979 array("hide" => array("integer", 0))
1980 );
1981 $this->is_3_10_skin = false;
1982 }
1983 }
1984 }
1985
1986 // add style_data record
1987 $q = "INSERT INTO style_data (id, uptodate) VALUES " .
1988 "(" . $ilDB->quote($this->getId(), "integer") . ", 0)";
1989 $ilDB->manipulate($q);
1990
1991 $this->update();
1992 $this->read();
1993
1994 if ($this->is_3_10_skin) {
1995 $this->do_3_10_Migration();
1996 }
1997 //$this->writeCSSFile();
1998 }
1999
2003 public function getStyleParameterGroups(): array
2004 {
2005 $groups = array();
2006
2007 foreach (self::$parameter as $parameter => $props) {
2008 $groups[$props["group"]][] = $parameter;
2009 }
2010 return $groups;
2011 }
2012
2013 public static function _getStyleParameterInputType(string $par): string
2014 {
2015 $input = self::$parameter[$par]["input"];
2016 return $input;
2017 }
2018
2019 public static function _getStyleParameterSubPar(string $par): string
2020 {
2021 $subpar = self::$parameter[$par]["subpar"];
2022 return $subpar;
2023 }
2024
2025 public static function _getStyleParameters(
2026 string $a_tag = ""
2027 ): array {
2028 if ($a_tag == "") {
2029 return self::$parameter;
2030 }
2031 $par = array();
2032 foreach (self::$parameter as $k => $v) {
2033 if (isset(self::$filtered_groups[$v["group"]]) &&
2034 !in_array($a_tag, self::$filtered_groups[$v["group"]])) {
2035 continue;
2036 }
2037 $par[$k] = $v;
2038 }
2039 return $par;
2040 }
2041
2042 public static function _getFilteredGroups(): array
2043 {
2044 return self::$filtered_groups;
2045 }
2046
2047 public static function _getStyleParameterNumericUnits(
2048 bool $a_no_percentage = false
2049 ): array {
2050 if ($a_no_percentage) {
2051 return self::$num_unit_no_perc;
2052 }
2053 return self::$num_unit;
2054 }
2055
2056 public static function _getStyleParameterValues(
2057 string $par
2058 ): array {
2059 return self::$parameter[$par]["values"];
2060 }
2061
2062 public static function _getStyleSuperTypes(): array
2063 {
2064 return self::$style_super_types;
2065 }
2066
2067 public static function _isExpandable(string $a_type): bool
2068 {
2069 return in_array($a_type, self::$expandable_types);
2070 }
2071
2072 public static function _isHideable(string $a_type): bool
2073 {
2074 return in_array($a_type, self::$hideable_types);
2075 }
2076
2077 public static function _getStyleSuperTypeForType(
2078 string $a_type
2079 ): string {
2080 foreach (self::$style_super_types as $s => $t) {
2081 if (in_array($a_type, $t)) {
2082 return $s;
2083 }
2084 if ($a_type == $s) {
2085 return $s;
2086 }
2087 }
2088 return "";
2089 }
2090
2091 public static function _getCoreStyles(): array
2092 {
2093 $c_styles = array();
2094 foreach (self::$core_styles as $cstyle) {
2095 $c_styles[$cstyle["type"] . "." . ilObjStyleSheet::_determineTag($cstyle["type"]) . "." . $cstyle["class"]]
2096 = array("type" => $cstyle["type"],
2097 "tag" => ilObjStyleSheet::_determineTag($cstyle["type"]),
2098 "class" => $cstyle["class"]);
2099 }
2100 return $c_styles;
2101 }
2102
2103 public static function isCoreStyle(
2104 string $a_type,
2105 string $a_class
2106 ): bool {
2107 foreach (self::$core_styles as $s) {
2108 if ($s["type"] == $a_type && $s["class"] == $a_class) {
2109 return true;
2110 }
2111 }
2112 return false;
2113 }
2114
2118 public static function _getTemplateClassTypes(
2119 string $a_template_type = ""
2120 ): array {
2121 if ($a_template_type == "") {
2122 return self::$templates;
2123 }
2124
2125 return self::$templates[$a_template_type];
2126 }
2127
2128 public static function _getPseudoClasses(string $tag): array
2129 {
2130 return self::$pseudo_classes[$tag] ?? [];
2131 }
2132
2133 // e.g. table, row_head > table_cell
2135 string $t,
2136 string $k
2137 ): string {
2138 return self::$templates[$t][$k];
2139 }
2140
2141 public static function _determineTag(string $a_type): string
2142 {
2143 return self::$assigned_tags[$a_type];
2144 }
2145
2146 public static function getAvailableParameters(): array
2147 {
2148 $pars = array();
2149 foreach (self::$parameter as $p => $v) {
2150 $pars[$p] = $v["values"];
2151 }
2152
2153 return $pars;
2154 }
2155
2159 public static function _addMissingStyleClassesToStyle(
2160 int $a_id
2161 ): void {
2162 $styles = array(array("id" => $a_id));
2164 }
2165
2171 ?array $a_styles = null
2172 ): void {
2173 global $DIC;
2174
2175 $ilDB = $DIC->database();
2176
2177 if (is_null($a_styles)) {
2178 $styles = ilObject::_getObjectsDataForType("sty");
2179 } else {
2180 $styles = $a_styles;
2181 }
2182 $core_styles = ilObjStyleSheet::_getCoreStyles();
2184
2185 // get all core image files
2186 $core_images = array();
2187 $core_dir = self::$basic_style_image_dir;
2188 if (is_dir($core_dir)) {
2189 $dir = opendir($core_dir);
2190 while ($file = readdir($dir)) {
2191 if (substr($file, 0, 1) != "." && is_file($core_dir . "/" . $file)) {
2192 $core_images[] = $file;
2193 }
2194 }
2195 }
2196
2197 foreach ($styles as $style) {
2198 $id = $style["id"];
2199
2200 foreach ($core_styles as $cs) {
2201 // check, whether core style class exists
2202 $set = $ilDB->queryF(
2203 "SELECT * FROM style_char WHERE style_id = %s " .
2204 "AND type = %s AND characteristic = %s",
2205 array("integer", "text", "text"),
2206 array($id, $cs["type"], $cs["class"])
2207 );
2208
2209 // if not, add core style class
2210 if (!($rec = $ilDB->fetchAssoc($set))) {
2211 $ilDB->manipulateF(
2212 "INSERT INTO style_char (style_id, type, characteristic) " .
2213 " VALUES (%s,%s,%s) ",
2214 array("integer", "text", "text"),
2215 array($id, $cs["type"], $cs["class"])
2216 );
2217
2218 $xpath = new DOMXPath($bdom);
2219 $par_nodes = $xpath->query("/StyleSheet/Style[@Tag = '" . $cs["tag"] . "' and @Type='" .
2220 $cs["type"] . "' and @Class='" . $cs["class"] . "']/StyleParameter");
2221 foreach ($par_nodes as $par_node) {
2222 // check whether style parameter exists
2223 $set = $ilDB->queryF(
2224 "SELECT * FROM style_parameter WHERE style_id = %s " .
2225 "AND type = %s AND class = %s AND tag = %s AND parameter = %s",
2226 array("integer", "text", "text", "text", "text"),
2227 array($id, $cs["type"], $cs["class"],
2228 $cs["tag"], $par_node->getAttribute("Name"))
2229 );
2230
2231 // if not, create style parameter
2232 if (!($ilDB->fetchAssoc($set))) {
2233 $spid = $ilDB->nextId("style_parameter");
2234 $st = $ilDB->manipulateF(
2235 "INSERT INTO style_parameter (id, style_id, type, class, tag, parameter, value) " .
2236 " VALUES (%s,%s,%s,%s,%s,%s,%s)",
2237 array("integer", "integer", "text", "text", "text", "text", "text"),
2238 array($spid, $id, $cs["type"], $cs["class"], $cs["tag"],
2239 $par_node->getAttribute("Name"), $par_node->getAttribute("Value"))
2240 );
2241 }
2242 }
2243 }
2244 }
2245
2246 // now check, whether some core image files are missing
2249 foreach ($core_images as $cim) {
2250 if (!is_file($imdir . "/" . $cim)) {
2251 copy($core_dir . "/" . $cim, $imdir . "/" . $cim);
2252 }
2253 }
2254 }
2255 }
2256
2257 //
2258 // Color management
2259 //
2260
2264 public function do_3_10_Migration(): void
2265 {
2266 $ilDB = $this->db;
2267
2268 $this->do_3_9_Migration($this->getId());
2269
2270 $this->do_3_10_CharMigration($this->getId());
2271
2272 // style_char: type for characteristic
2273 $st = $ilDB->prepareManip("UPDATE style_char SET type = ? WHERE characteristic = ?" .
2274 " AND style_id = ? ", array("text", "text", "integer"));
2275 $ilDB->execute($st, array("media_cont", "Media", $this->getId()));
2276 $ilDB->execute($st, array("media_caption", "MediaCaption", $this->getId()));
2277 $ilDB->execute($st, array("page_fn", "Footnote", $this->getId()));
2278 $ilDB->execute($st, array("page_nav", "LMNavigation", $this->getId()));
2279 $ilDB->execute($st, array("page_title", "PageTitle", $this->getId()));
2280 $ilDB->execute($st, array("page_cont", "Page", $this->getId()));
2281
2282 // style_parameter: type for class
2283 $st = $ilDB->prepareManip("UPDATE style_parameter SET type = ? WHERE class = ?" .
2284 " AND style_id = ? ", array("text", "text", "integer"));
2285 $ilDB->execute($st, array("media_cont", "Media", $this->getId()));
2286 $ilDB->execute($st, array("media_caption", "MediaCaption", $this->getId()));
2287 $ilDB->execute($st, array("page_fn", "Footnote", $this->getId()));
2288 $ilDB->execute($st, array("page_nav", "LMNavigation", $this->getId()));
2289 $ilDB->execute($st, array("page_title", "PageTitle", $this->getId()));
2290 $ilDB->execute($st, array("table", "Page", $this->getId()));
2291
2292 $st = $ilDB->prepareManip("UPDATE style_parameter SET tag = ? WHERE class = ?" .
2293 " AND style_id = ? ", array("text", "text", "integer"));
2294 $ilDB->execute($st, array("div", "MediaCaption", $this->getId()));
2295
2296 // style_char: characteristic for characteristic
2297 $st = $ilDB->prepareManip("UPDATE style_char SET characteristic = ? WHERE characteristic = ?" .
2298 " AND style_id = ? ", array("text", "text", "integer"));
2299 $ilDB->execute($st, array("MediaContainer", "Media", $this->getId()));
2300 $ilDB->execute($st, array("PageContainer", "Page", $this->getId()));
2301
2302 // style_parameter: class for class
2303 $st = $ilDB->prepareManip("UPDATE style_parameter SET class = ? WHERE class = ?" .
2304 " AND style_id = ? ", array("text", "text", "integer"));
2305 $ilDB->execute($st, array("MediaContainer", "Media", $this->getId()));
2306 $ilDB->execute($st, array("PageContainer", "Page", $this->getId()));
2307
2308 // force rewriting of container style
2309 $st = $ilDB->prepareManip("DELETE FROM style_char WHERE type = ?" .
2310 " AND style_id = ? ", array("text", "integer"));
2311 $ilDB->execute($st, array("page_cont", $this->getId()));
2312 $st = $ilDB->prepareManip("DELETE FROM style_parameter WHERE type = ?" .
2313 " AND style_id = ? ", array("text", "integer"));
2314 $ilDB->execute($st, array("page_cont", $this->getId()));
2315 }
2316
2322 public function do_3_10_CharMigration(int $a_id = 0): void
2323 {
2324 $ilDB = $this->db;
2325
2326 $add_str = "";
2327 if ($a_id > 0) {
2328 $add_str = " AND style_id = " . $ilDB->quote($a_id, "integer");
2329 }
2330
2331 $set = $ilDB->query($q = "SELECT DISTINCT style_id, tag, class FROM style_parameter WHERE " .
2332 $ilDB->equals("type", "", "text", true) . " " . $add_str);
2333
2334 while ($rec = $ilDB->fetchAssoc($set)) {
2335 // derive types from tag
2336 $types = array();
2337 switch ($rec["tag"]) {
2338 case "div":
2339 case "p":
2340 if (in_array($rec["class"], array("Headline3", "Headline1",
2341 "Headline2", "TableContent", "List", "Standard", "Remark",
2342 "Additional", "Mnemonic", "Citation", "Example"))) {
2343 $types[] = "text_block";
2344 }
2345 if (in_array($rec["class"], array("Block", "Remark",
2346 "Additional", "Mnemonic", "Example", "Excursus", "Special"))) {
2347 $types[] = "section";
2348 }
2349 if (in_array($rec["class"], array("Page", "Footnote", "PageTitle", "LMNavigation"))) {
2350 $types[] = "page";
2351 }
2352 break;
2353
2354 case "td":
2355 $types[] = "table_cell";
2356 break;
2357
2358 case "a":
2359 if (in_array($rec["class"], array("ExtLink", "IntLink", "FootnoteLink"))) {
2360 $types[] = "link";
2361 }
2362 break;
2363
2364 case "span":
2365 $types[] = "text_inline";
2366 break;
2367
2368 case "table":
2369 $types[] = "table";
2370 break;
2371 }
2372
2373 // check if style_char set exists
2374 foreach ($types as $t) {
2375 // check if second type already exists
2376 $set4 = $ilDB->queryF(
2377 "SELECT * FROM style_char " .
2378 " WHERE style_id = %s AND type = %s AND characteristic = %s",
2379 array("integer", "text", "text"),
2380 array($rec["style_id"], $t, $rec["class"])
2381 );
2382 if ($rec4 = $ilDB->fetchAssoc($set4)) {
2383 // ok
2384 } else {
2385 //echo "<br>1-".$rec["style_id"]."-".$t."-".$rec["class"]."-";
2386 $ilDB->manipulateF(
2387 "INSERT INTO style_char " .
2388 " (style_id, type, characteristic) VALUES " .
2389 " (%s,%s,%s) ",
2390 array("integer", "text", "text"),
2391 array($rec["style_id"], $t, $rec["class"])
2392 );
2393 }
2394 }
2395
2396 // update types
2397 if ($rec["type"] == "") {
2398 if (count($types) > 0) {
2399 $ilDB->manipulateF(
2400 "UPDATE style_parameter SET type = %s " .
2401 " WHERE style_id = %s AND class = %s AND " . $ilDB->equals("type", "", "text", true),
2402 array("text", "integer", "text"),
2403 array($types[0], $rec["style_id"], $rec["class"])
2404 );
2405 //echo "<br>3-".$types[0]."-".$rec["style_id"]."-".$rec["class"]."-";
2406
2407 // links extra handling
2408 if ($types[0] == "link") {
2409 $ilDB->manipulateF(
2410 "UPDATE style_parameter SET type = %s " .
2411 " WHERE style_id = %s AND (class = %s OR class = %s) AND " . $ilDB->equals("type", "", "text", true),
2412 array("text", "integer", "text", "text"),
2413 array($types[0], $rec["style_id"], $rec["class"] . ":visited",
2414 $rec["class"] . ":hover")
2415 );
2416 }
2417 }
2418
2419 if (count($types) == 2) {
2420 // select all records of first type and add second type
2421 // records if necessary.
2422 $set2 = $ilDB->queryF(
2423 "SELECT * FROM style_parameter " .
2424 " WHERE style_id = %s AND class = %s AND type = %s",
2425 array("integer", "text", "text"),
2426 array($rec["style_id"], $rec["class"], $types[0])
2427 );
2428 while ($rec2 = $ilDB->fetchAssoc($set2)) {
2429 // check if second type already exists
2430 $set3 = $ilDB->queryF(
2431 "SELECT * FROM style_parameter " .
2432 " WHERE style_id = %s AND tag = %s AND class = %s AND type = %s AND parameter = %s",
2433 array("integer", "text", "text", "text", "text"),
2434 array($rec["style_id"], $rec["tag"], $rec["class"], $types[1], $rec["parameter"])
2435 );
2436 if ($rec3 = $ilDB->fetchAssoc($set3)) {
2437 // ok
2438 } else {
2439 $nid = $ilDB->nextId("style_parameter");
2440 $ilDB->manipulateF(
2441 "INSERT INTO style_parameter " .
2442 " (id, style_id, tag, class, parameter, value, type) VALUES " .
2443 " (%s, %s,%s,%s,%s,%s,%s) ",
2444 array("integer", "integer", "text", "text", "text", "text", "text"),
2445 array($nid, $rec2["style_id"], $rec2["tag"], $rec2["class"],
2446 $rec2["parameter"], $rec2["value"], $types[1])
2447 );
2448 }
2449 }
2450 }
2451 }
2452 }
2453 }
2454
2458 public function do_3_9_Migration(int $a_id): void
2459 {
2460 $ilDB = $this->db;
2461
2462 $classes = array("Example", "Additional", "Citation", "Mnemonic", "Remark");
2463 $pars = array("margin-top", "margin-bottom");
2464
2465 foreach ($classes as $curr_class) {
2466 foreach ($pars as $curr_par) {
2467 $res2 = $ilDB->queryF(
2468 "SELECT id FROM style_parameter WHERE style_id = %s" .
2469 " AND tag = %s AND class= %s AND parameter = %s",
2470 array("integer", "text", "text", "text"),
2471 array($a_id, "p", $curr_class, $curr_par)
2472 );
2473 if ($row2 = $ilDB->fetchAssoc($res2)) {
2474 $ilDB->manipulateF(
2475 "UPDATE style_parameter SET value= %s WHERE id = %s",
2476 array("text", "integer"),
2477 array("10px", $row2["id"])
2478 );
2479 } else {
2480 $nid = $ilDB->nextId("style_parameter");
2481 $ilDB->manipulateF(
2482 "INSERT INTO style_parameter " .
2483 "(id, style_id, tag, class, parameter,value) VALUES (%s,%s,%s,%s,%s,%s)",
2484 array("integer", "integer", "text", "text", "text", "text"),
2485 array($nid, $a_id, "div", $curr_class, $curr_par, "10px")
2486 );
2487 }
2488 }
2489 }
2490
2491 $ilDB->manipulateF(
2492 "UPDATE style_parameter SET tag = %s WHERE tag = %s and style_id = %s",
2493 array("text", "text", "integer"),
2494 array("div", "p", $a_id)
2495 );
2496 }
2497
2501
2505 public function getColors(): array
2506 {
2507 $ilDB = $this->db;
2508
2509 $set = $ilDB->query("SELECT * FROM style_color WHERE " .
2510 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
2511 "ORDER BY color_name");
2512
2513 $colors = array();
2514 while ($rec = $ilDB->fetchAssoc($set)) {
2515 $colors[] = array(
2516 "name" => $rec["color_name"],
2517 "code" => $rec["color_code"]
2518 );
2519 }
2520
2521 return $colors;
2522 }
2523
2527 public function removeColor(string $a_name): void
2528 {
2529 $ilDB = $this->db;
2530
2531 $ilDB->manipulate("DELETE FROM style_color WHERE " .
2532 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2533 " color_name = " . $ilDB->quote($a_name, "text"));
2534 }
2535
2536 public function getColorCodeForName(string $a_name): string
2537 {
2538 $ilDB = $this->db;
2539 $a_i = "";
2540 $pos = strpos($a_name, "(");
2541 if ($pos > 0) {
2542 $a_i = substr($a_name, $pos + 1);
2543 $a_i = str_replace(")", "", $a_i);
2544 $a_name = substr($a_name, 0, $pos);
2545 }
2546
2547 $set = $ilDB->query("SELECT color_code FROM style_color WHERE " .
2548 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2549 " color_name = " . $ilDB->quote($a_name, "text"));
2550 if ($rec = $ilDB->fetchAssoc($set)) {
2551 if ($a_i == "") {
2552 return "#" . $rec["color_code"];
2553 } else {
2555 $rec["color_code"],
2556 (int) $a_i
2557 );
2558 }
2559 }
2560 return "";
2561 }
2562
2566 public static function _getColorFlavor(
2567 string $a_rgb,
2568 int $a_i
2569 ): string {
2570 $rgb = ilObjStyleSheet::_explodeRGB($a_rgb, true);
2571 $hls = ilObjStyleSheet::_RGBToHLS($rgb);
2572
2573 if ($a_i > 0) {
2574 $hls["l"] = $hls["l"] + ((255 - $hls["l"]) * ($a_i / 100));
2575 }
2576 if ($a_i < 0) {
2577 $hls["l"] = $hls["l"] - (($hls["l"]) * (-$a_i / 100));
2578 }
2579
2580 $rgb = ilObjStyleSheet::_HLSToRGB($hls);
2581
2582 foreach ($rgb as $k => $v) {
2583 $rgb[$k] = str_pad(dechex((int) $v), 2, "0", STR_PAD_LEFT);
2584 }
2585
2586 return $rgb["r"] . $rgb["g"] . $rgb["b"];
2587 }
2588
2592 public static function _explodeRGB(
2593 string $a_rgb,
2594 bool $as_dec = false
2595 ): array {
2596 $r["r"] = (string) substr($a_rgb, 0, 2);
2597 $r["g"] = (string) substr($a_rgb, 2, 2);
2598 $r["b"] = (string) substr($a_rgb, 4, 2);
2599 if ($as_dec) {
2600 $r["r"] = self::hexdec($r["r"]);
2601 $r["g"] = self::hexdec($r["g"]);
2602 $r["b"] = self::hexdec($r["b"]);
2603 }
2604
2605 return $r;
2606 }
2607
2608 protected static function hexdec(string $hex): int
2609 {
2610 $hex = preg_replace("/[^a-fA-F0-9]+/", "", $hex);
2611 if ($hex === "") {
2612 $hex = "0";
2613 }
2614 return (int) hexdec($hex);
2615 }
2616
2620 public static function _RGBToHLS(array $a_rgb): array
2621 {
2622 $r = $a_rgb["r"] / 255;
2623 $g = $a_rgb["g"] / 255;
2624 $b = $a_rgb["b"] / 255;
2625 $h = 0;
2626
2627 // max / min
2628 $max = max($r, $g, $b);
2629 $min = min($r, $g, $b);
2630
2631 //lightness
2632 $l = ($max + $min) / 2;
2633
2634 if ($max == $min) {
2635 $s = 0;
2636 } else {
2637 if ($l < 0.5) {
2638 $s = ($max - $min) / ($max + $min);
2639 } else {
2640 $s = ($max - $min) / (2.0 - $max - $min);
2641 }
2642
2643 if ($r == $max) {
2644 $h = ($g - $b) / ($max - $min);
2645 } elseif ($g == $max) {
2646 $h = 2.0 + ($b - $r) / ($max - $min);
2647 } elseif ($b == $max) {
2648 $h = 4.0 + ($r - $g) / ($max - $min);
2649 }
2650 }
2651
2652 $hls["h"] = round(($h / 6) * 255);
2653 $hls["l"] = round($l * 255);
2654 $hls["s"] = round($s * 255);
2655
2656 return $hls;
2657 }
2658
2662 public static function _HLSToRGB(array $a_hls): array
2663 {
2664 $h = $a_hls["h"] / 255;
2665 $l = $a_hls["l"] / 255;
2666 $s = $a_hls["s"] / 255;
2667 $temp3 = 0;
2668
2669 $rgb["r"] = $rgb["g"] = $rgb["b"] = 0;
2670
2671 // If S=0, define R, G, and B all to L
2672 if ($s == 0) {
2673 $rgb["r"] = $rgb["g"] = $rgb["b"] = $l;
2674 } else {
2675 if ($l < 0.5) {
2676 $temp2 = $l * (1.0 + $s);
2677 } else {
2678 $temp2 = $l + $s - $l * $s;
2679 }
2680
2681 $temp1 = 2.0 * $l - $temp2;
2682
2683
2684 # For each of R, G, B, compute another temporary value, temp3, as follows:
2685 foreach ($rgb as $k => $v) {
2686 switch ($k) {
2687 case "r":
2688 $temp3 = $h + 1.0 / 3.0;
2689 break;
2690
2691 case "g":
2692 $temp3 = $h;
2693 break;
2694
2695 case "b":
2696 $temp3 = $h - 1.0 / 3.0;
2697 break;
2698 }
2699 if ($temp3 < 0) {
2700 $temp3 = $temp3 + 1.0;
2701 }
2702 if ($temp3 > 1) {
2703 $temp3 = $temp3 - 1.0;
2704 }
2705
2706 if (6.0 * $temp3 < 1) {
2707 $rgb[$k] = $temp1 + ($temp2 - $temp1) * 6.0 * $temp3;
2708 } elseif (2.0 * $temp3 < 1) {
2709 $rgb[$k] = $temp2;
2710 } elseif (3.0 * $temp3 < 2) {
2711 $rgb[$k] = $temp1 + ($temp2 - $temp1) * ((2.0 / 3.0) - $temp3) * 6.0;
2712 } else {
2713 $rgb[$k] = $temp1;
2714 }
2715 }
2716 }
2717
2718 $rgb["r"] = round($rgb["r"] * 255);
2719 $rgb["g"] = round($rgb["g"] * 255);
2720 $rgb["b"] = round($rgb["b"] * 255);
2721
2722 return $rgb;
2723 }
2724
2725 //
2726 // Media queries
2727 //
2728
2732
2733 public function getMediaQueries(): array
2734 {
2735 $ilDB = $this->db;
2736
2737 $set = $ilDB->query("SELECT * FROM sty_media_query WHERE " .
2738 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
2739 "ORDER BY order_nr");
2740
2741 $mq = array();
2742 while ($rec = $ilDB->fetchAssoc($set)) {
2743 $mq[] = $rec;
2744 }
2745
2746 return $mq;
2747 }
2748
2749 public function addMediaQuery(
2750 string $a_mquery,
2751 int $order_nr = 0
2752 ): int {
2753 $ilDB = $this->db;
2754
2755 $id = $ilDB->nextId("sty_media_query");
2756 if ($order_nr == 0) {
2757 $order_nr = $this->getMaxMQueryOrderNr() + 10;
2758 }
2759
2760 $ilDB->manipulate("INSERT INTO sty_media_query (id, style_id, mquery, order_nr)" .
2761 " VALUES (" .
2762 $ilDB->quote($id, "integer") . "," .
2763 $ilDB->quote($this->getId(), "integer") . "," .
2764 $ilDB->quote($a_mquery, "text") . "," .
2765 $ilDB->quote($order_nr, "integer") .
2766 ")");
2767
2768 return $id;
2769 }
2770
2774 public function getMaxMQueryOrderNr(): int
2775 {
2776 $ilDB = $this->db;
2777
2778 $set = $ilDB->query(
2779 "SELECT max(order_nr) mnr FROM sty_media_query " .
2780 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer")
2781 );
2782 $rec = $ilDB->fetchAssoc($set);
2783
2784 return (int) $rec["mnr"];
2785 }
2786
2787 public function updateMediaQuery(
2788 int $a_id,
2789 string $a_mquery
2790 ): void {
2791 $ilDB = $this->db;
2792
2793 $ilDB->manipulate(
2794 "UPDATE sty_media_query SET " .
2795 " mquery = " . $ilDB->quote($a_mquery, "text") .
2796 " WHERE id = " . $ilDB->quote($a_id, "integer")
2797 );
2798 }
2799
2806 public function getMediaQueryForId(
2807 int $a_id
2808 ): array {
2809 $ilDB = $this->db;
2810
2811 $set = $ilDB->query(
2812 "SELECT * FROM sty_media_query " .
2813 " WHERE id = " . $ilDB->quote($a_id, "integer")
2814 );
2815 return $ilDB->fetchAssoc($set);
2816 }
2817
2823 public function deleteMediaQuery(
2824 int $a_id
2825 ): void {
2826 $ilDB = $this->db;
2827
2828 $ilDB->manipulate(
2829 "DELETE FROM sty_media_query WHERE " .
2830 " style_id = " . $ilDB->quote($this->getId(), "integer") .
2831 " AND id = " . $ilDB->quote($a_id, "integer")
2832 );
2833 $this->saveMediaQueryOrder();
2834 }
2835
2839 public function saveMediaQueryOrder(
2840 array $a_order_nr = null
2841 ): void {
2842 $ilDB = $this->db;
2843
2844 $mqueries = $this->getMediaQueries();
2845 if (is_array($a_order_nr)) {
2846 foreach ($mqueries as $k => $mq) {
2847 $mqueries[$k]["order_nr"] = $a_order_nr[$mq["id"]];
2848 }
2849 $mqueries = ilArrayUtil::sortArray($mqueries, "order_nr", "", true);
2850 }
2851 $cnt = 10;
2852 foreach ($mqueries as $mq) {
2853 $ilDB->manipulate(
2854 "UPDATE sty_media_query SET " .
2855 " order_nr = " . $ilDB->quote($cnt, "integer") .
2856 " WHERE id = " . $ilDB->quote($mq["id"], "integer")
2857 );
2858 $cnt += 10;
2859 }
2860 }
2861
2862
2863 //
2864 // Table template management
2865 //
2866
2870 public function getTemplates(
2871 string $a_type
2872 ): array {
2873 $ilDB = $this->db;
2874
2875 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
2876 "style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2877 "temp_type = " . $ilDB->quote($a_type, "text") . " " .
2878 "ORDER BY name");
2879
2880 $templates = array();
2881 while ($rec = $ilDB->fetchAssoc($set)) {
2882 $rec["classes"] = $this->getTemplateClasses((int) $rec["id"]);
2883 $templates[] = $rec;
2884 }
2885
2886 return $templates;
2887 }
2888
2892 public function getTemplateClasses(
2893 int $a_tid
2894 ): array {
2895 $ilDB = $this->db;
2896 $set = $ilDB->query("SELECT * FROM style_template_class WHERE " .
2897 "template_id = " . $ilDB->quote($a_tid, "integer"));
2898
2899 $class = array();
2900 while ($rec = $ilDB->fetchAssoc($set)) {
2901 $key = $rec["class_type"];
2902 $class[$key] = $rec["class"];
2903 }
2904
2905 return $class;
2906 }
2907
2908
2912 public function addTemplate(
2913 string $a_type,
2914 string $a_name,
2915 array $a_classes
2916 ): int {
2917 $ilDB = $this->db;
2918
2919 $tid = $ilDB->nextId("style_template");
2920 $ilDB->manipulate("INSERT INTO style_template " .
2921 "(id, style_id, name, temp_type)" .
2922 " VALUES (" .
2923 $ilDB->quote($tid, "integer") . "," .
2924 $ilDB->quote($this->getId(), "integer") . "," .
2925 $ilDB->quote($a_name, "text") . "," .
2926 $ilDB->quote($a_type, "text") .
2927 ")");
2928
2929 foreach ($a_classes as $t => $c) {
2930 $ilDB->manipulate("INSERT INTO style_template_class " .
2931 "(template_id, class_type, class)" .
2932 " VALUES (" .
2933 $ilDB->quote($tid, "integer") . "," .
2934 $ilDB->quote($t, "text") . "," .
2935 $ilDB->quote($c, "text") .
2936 ")");
2937 }
2938
2939 $this->writeTemplatePreview(
2940 $tid,
2941 ilObjStyleSheetGUI::_getTemplatePreview($this, $a_type, $tid, true)
2942 );
2943
2944 return $tid;
2945 }
2946
2950 public function updateTemplate(
2951 int $a_t_id,
2952 string $a_name,
2953 array $a_classes
2954 ): void {
2955 $ilDB = $this->db;
2956
2957 $ilDB->manipulate("UPDATE style_template SET " .
2958 "name = " . $ilDB->quote($a_name, "text") .
2959 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
2960
2961 $ilDB->manipulate(
2962 "DELETE FROM style_template_class WHERE " .
2963 "template_id = " . $ilDB->quote($a_t_id, "integer")
2964 );
2965 foreach ($a_classes as $t => $c) {
2966 $ilDB->manipulate("INSERT INTO style_template_class " .
2967 "(template_id, class_type, class)" .
2968 " VALUES (" .
2969 $ilDB->quote($a_t_id, "integer") . "," .
2970 $ilDB->quote($t, "text") . "," .
2971 $ilDB->quote($c, "text") .
2972 ")");
2973 }
2974 }
2975
2976 public function addTemplateClass(
2977 int $a_t_id,
2978 string $a_type,
2979 string $a_class
2980 ): void {
2981 $ilDB = $this->db;
2982
2983 $ilDB->manipulate("INSERT INTO style_template_class " .
2984 "(template_id, class_type, class)" .
2985 " VALUES (" .
2986 $ilDB->quote($a_t_id, "integer") . "," .
2987 $ilDB->quote($a_type, "text") . "," .
2988 $ilDB->quote($a_class, "text") .
2989 ")");
2990 }
2991
2995 public function templateExists(
2996 string $a_template_name
2997 ): bool {
2998 $ilDB = $this->db;
2999
3000 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
3001 "style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
3002 "name = " . $ilDB->quote($a_template_name, "text"));
3003 if ($ilDB->fetchAssoc($set)) {
3004 return true;
3005 }
3006 return false;
3007 }
3008
3012 public function getTemplate(int $a_t_id): array
3013 {
3014 $ilDB = $this->db;
3015
3016 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
3017 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
3018 " AND id = " . $ilDB->quote($a_t_id, "integer"));
3019
3020 if ($rec = $ilDB->fetchAssoc($set)) {
3021 $rec["classes"] = $this->getTemplateClasses((int) $rec["id"]);
3022
3023 $template = $rec;
3024 return $template;
3025 }
3026 return array();
3027 }
3028
3032 public function lookupTemplateName(int $a_t_id): string
3033 {
3034 return self::_lookupTemplateName($a_t_id);
3035 }
3036
3040 public static function _lookupTemplateName(int $a_t_id): ?string
3041 {
3042 global $DIC;
3043
3044 $ilDB = $DIC->database();
3045
3046 $set = $ilDB->query("SELECT name FROM style_template WHERE " .
3047 " id = " . $ilDB->quote($a_t_id, "integer"));
3048
3049 if ($rec = $ilDB->fetchAssoc($set)) {
3050 return $rec["name"];
3051 }
3052
3053 return null;
3054 }
3055
3059 public function getTemplateXML(): string
3060 {
3061 $ilDB = $this->db;
3062
3063 $tag = "<StyleTemplates>";
3064
3065 $ttypes = array("table", "vaccordion", "haccordion", "carousel");
3066
3067 foreach ($ttypes as $ttype) {
3068 $ts = $this->getTemplates($ttype);
3069
3070 foreach ($ts as $t) {
3072 /*$atts = array("table" => "TableClass",
3073 "caption" => "CaptionClass",
3074 "row_head" => "RowHeadClass",
3075 "row_foot" => "RowFootClass",
3076 "col_head" => "ColHeadClass",
3077 "col_foot" => "ColFootClass",
3078 "odd_row" => "OddRowClass",
3079 "even_row" => "EvenRowClass",
3080 "odd_col" => "OddColClass",
3081 "even_col" => "EvenColClass");*/
3082 $c = $t["classes"];
3083
3084 $tag .= '<StyleTemplate Name="' . $t["name"] . '">';
3085
3086 foreach ($atts as $type => $t2) {
3087 if (($c[$type] ?? "") != "") {
3088 $tag .= '<StyleClass Type="' . $type . '" Value="' . $c[$type] . '" />';
3089 }
3090 }
3091
3092 $tag .= "</StyleTemplate>";
3093 }
3094 }
3095
3096 $tag .= "</StyleTemplates>";
3097
3098 //echo htmlentities($tag);
3099 return $tag;
3100 }
3101
3105 public function writeTemplatePreview(
3106 int $a_t_id,
3107 string $a_preview_html
3108 ): void {
3109 $ilDB = $this->db;
3110 $a_preview_html = str_replace(' width=""', "", $a_preview_html);
3111 $a_preview_html = str_replace(' valign="top"', "", $a_preview_html);
3112 $a_preview_html = str_replace('<div class="ilc_text_block_TableContent">', "<div>", $a_preview_html);
3113 //echo "1-".strlen($a_preview_html)."-";
3114 //echo htmlentities($a_preview_html);
3115 if (strlen($a_preview_html) > 4000) {
3116 //echo "2";
3117 $a_preview_html = "";
3118 }
3119 $ilDB->manipulate("UPDATE style_template SET " .
3120 "preview = " . $ilDB->quote($a_preview_html, "text") .
3121 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
3122 }
3123
3127 public function lookupTemplatePreview(int $a_t_id): string
3128 {
3129 $ilDB = $this->db;
3130
3131 $set = $ilDB->query("SELECT preview FROM style_template " .
3132 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
3133 if ($rec = $ilDB->fetchAssoc($set)) {
3134 return $rec["preview"] ?? "";
3135 }
3136
3137 return "";
3138 }
3139
3143 public static function _lookupTemplateIdByName(
3144 int $a_style_id,
3145 string $a_name
3146 ): ?int {
3147 global $DIC;
3148
3149 $ilDB = $DIC->database();
3150
3151 $set = $ilDB->query("SELECT id FROM style_template " .
3152 " WHERE style_id = " . $ilDB->quote($a_style_id, "integer") .
3153 " AND name = " . $ilDB->quote($a_name, "text"));
3154 if ($rec = $ilDB->fetchAssoc($set)) {
3155 return (int) $rec["id"];
3156 }
3157
3158 return null;
3159 }
3160
3164 public function removeTemplate(int $a_t_id): void
3165 {
3166 $ilDB = $this->db;
3167
3168 $ilDB->manipulate("DELETE FROM style_template WHERE " .
3169 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
3170 " id = " . $ilDB->quote($a_t_id, "integer"));
3171
3172 $ilDB->manipulate(
3173 "DELETE FROM style_template_class WHERE " .
3174 "template_id = " . $ilDB->quote($a_t_id, "integer")
3175 );
3176 }
3177
3178 public function writeStyleSetting(
3179 string $a_name,
3180 string $a_value
3181 ): void {
3182 $ilDB = $this->db;
3183
3184 $ilDB->manipulate(
3185 "DELETE FROM style_setting WHERE " .
3186 " style_id = " . $ilDB->quote($this->getId(), "integer") .
3187 " AND name = " . $ilDB->quote($a_name, "text")
3188 );
3189
3190 $ilDB->manipulate("INSERT INTO style_setting " .
3191 "(style_id, name, value) VALUES (" .
3192 $ilDB->quote($this->getId(), "integer") . "," .
3193 $ilDB->quote($a_name, "text") . "," .
3194 $ilDB->quote($a_value, "text") .
3195 ")");
3196 }
3197
3201 public function lookupStyleSetting(string $a_name): string
3202 {
3203 $ilDB = $this->db;
3204
3205 $set = $ilDB->query(
3206 "SELECT value FROM style_setting " .
3207 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") .
3208 " AND name = " . $ilDB->quote($a_name, "text")
3209 );
3210 $rec = $ilDB->fetchAssoc($set);
3211
3212 return $rec["value"] ?? '';
3213 }
3214
3218 public static function writeStyleUsage(
3219 int $a_obj_id,
3220 int $a_style_id
3221 ): void {
3222 global $DIC;
3223
3224 $ilDB = $DIC->database();
3225
3226 $ilDB->replace(
3227 "style_usage",
3228 array(
3229 "obj_id" => array("integer", $a_obj_id)),
3230 array(
3231 "style_id" => array("integer", $a_style_id))
3232 );
3233 }
3234
3238 public static function lookupObjectStyle(
3239 int $a_obj_id
3240 ): int {
3241 global $DIC;
3242
3243 $ilDB = $DIC->database();
3244
3245 $set = $ilDB->query(
3246 "SELECT style_id FROM style_usage " .
3247 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
3248 );
3249 $rec = $ilDB->fetchAssoc($set);
3250 if (!is_array($rec)) {
3251 return 0;
3252 }
3253
3254 if (ilObject::_lookupType((int) $rec["style_id"]) == "sty") {
3255 return (int) $rec["style_id"];
3256 }
3257
3258 return 0;
3259 }
3260
3265 public static function lookupObjectForStyle(
3266 int $a_style_id
3267 ): array {
3268 global $DIC;
3269
3270 $ilDB = $DIC->database();
3271
3272 $obj_ids = array();
3273 if (ilObject::_lookupType($a_style_id) == "sty") {
3274 $set = $ilDB->query(
3275 "SELECT DISTINCT obj_id FROM style_usage " .
3276 " WHERE style_id = " . $ilDB->quote($a_style_id, "integer")
3277 );
3278
3279 while ($rec = $ilDB->fetchAssoc($set)) {
3280 $obj_ids[] = (int) $rec["obj_id"];
3281 }
3282 }
3283 return $obj_ids;
3284 }
3285}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
return true
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getDataDir()
get data directory (outside webspace)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static rCopy(string $a_sdir, string $a_tdir, bool $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static _deleteStyleAssignments(int $a_style_id)
delete all style references to style
static _lookupContObjIdByStyleId(int $a_style_id)
static _getTemplatePreview(ilObjStyleSheet $a_style, string $a_type, int $a_t_id, bool $a_small_mode=false)
Get table template preview.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
handleXmlString(string $a_str)
getMediaQueryForId(int $a_id)
Get media query for id.
getHideStatus(string $a_type, string $a_char)
Get characteristic hidden status.
setStyle(array $a_style)
getMaxMQueryOrderNr()
Get maximum media query order nr.
static _explodeRGB(string $a_rgb, bool $as_dec=false)
Explode an RGB string into an array.
static _addMissingStyleClassesToAllStyles(?array $a_styles=null)
Add missing style classes to all styles todo: add mq_id and custom handling.
do_3_10_CharMigration(int $a_id=0)
This is more or less a copy of Services/Migration/DBUpdate_1385/classes ilStyleMigration->addMissingS...
static _lookupStandard(int $a_id)
Lookup standard flag.
static array $filtered_groups
static _writeActive(int $a_id, bool $a_active)
static _lookupTemplateIdByName(int $a_style_id, string $a_name)
Lookup table template preview.
addTemplateClass(int $a_t_id, string $a_type, string $a_class)
read()
read style properties
updateStyleParameter(int $a_id, string $a_value)
update style parameter per id
saveMediaQueryOrder(array $a_order_nr=null)
Save media query order.
static _getClonableContentStyles()
Get all clonable styles (active standard styles and individual learning module styles with write perm...
updateMediaQuery(int $a_id, string $a_mquery)
static _lookupActive(int $a_id)
Lookup active flag.
static string $basic_style_file
setUpToDate(bool $a_up_to_date=true)
Set style up to date (false + update will trigger css generation next time)
setExportSubDir(string $a_dir)
Set local directory, that will be included within the zip file.
writeCSSFile(string $a_target_file="", string $a_image_dir="")
write css file to webspace directory
static array $pseudo_classes
getColorCodeForName(string $a_name)
static array $expandable_types
setCharacteristics(array $a_chars)
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
create(int $a_from_style=0, bool $a_import_mode=false)
Create a new style.
createFromXMLFile(string $a_file, bool $a_skip_parent_create=false)
create style from xml file todo: add mq_id and custom
getCharacteristics(string $a_type="", bool $a_no_hidden=false, bool $a_include_core=true)
Get characteristics.
static _getPseudoClasses(string $tag)
static _writeScope(int $a_id, int $a_scope)
__construct(int $a_id=0, bool $a_call_by_reference=false)
characteristicExists(string $a_char, string $a_style_type)
Check whether characteristic exists.
static string $basic_style_zip
ilClone()
clone style sheet (note: styles have no ref ids and return an object id)
static _createImagesDirectory(int $a_style_id)
Create images directory <data_dir>/sty/sty_<id>/images.
static hexdec(string $hex)
addTemplate(string $a_type, string $a_name, array $a_classes)
Add table template.
static _getStandardStyles(bool $a_exclude_default_style=false, bool $a_include_deactivated=false, int $a_scope=0)
Get standard styles.
static writeStyleUsage(int $a_obj_id, int $a_style_id)
Write style usage.
copyImagesToDir(string $a_target)
Copy images to directory.
static _getStyleParameterNumericUnits(bool $a_no_percentage=false)
static _getStyleParameterSubPar(string $par)
static _lookupUpToDate(int $a_id)
static isCoreStyle(string $a_type, string $a_class)
static _getImagesDirectory(int $a_style_id)
getTemplateXML()
Get table template xml.
static _getStyleParameterInputType(string $par)
static _HLSToRGB(array $a_hls)
HLS to RGB (both arrays, 0..255)
writeTemplatePreview(int $a_t_id, string $a_preview_html)
Write table template preview.
addMediaQuery(string $a_mquery, int $order_nr=0)
exportXML(string $a_dir)
export style xml file to directory
getStyleParameterGroups()
Get grouped parameter.
lookupTemplateName(int $a_t_id)
Lookup table template name for template ID.
static getEffectiveContentStyleId(int $a_style_id)
Get effective Style Id.
updateTemplate(int $a_t_id, string $a_name, array $a_classes)
Update table template.
getTemplateClasses(int $a_tid)
Get template classes.
getTemplates(string $a_type)
Get table templates of style.
deleteCustomStylePars(string $a_tag, string $a_class, string $a_type, int $a_mq_id=0)
Delete style parameter by tag/class/parameter.
lookupStyleSetting(string $a_name)
Lookup style setting.
static lookupObjectForStyle(int $a_style_id)
Lookup objects for style.
getExportSubDir()
The local directory, that will be included within the zip file.
ILIAS Style Content InternalRepoService $repo
removeTemplate(int $a_t_id)
Remove table template.
addCharacteristic(string $a_type, string $a_char, bool $a_hidden=false, int $order_nr=0, bool $outdated=false)
static _addMissingStyleClassesToStyle(int $a_id)
Add missing style classes to all styles.
saveHideStatus(string $a_type, string $a_char, bool $a_hide)
Save characteristic hidden status.
static _getColorFlavor(string $a_rgb, int $a_i)
Get color flavor.
static _RGBToHLS(array $a_rgb)
RGB to HLS (both arrays, 0..255)
deleteStyleParOfChar(string $a_type, string $a_class)
Delete style parameters of characteristic.
static _writeStandard(int $a_id, bool $a_std)
Write standard flag.
getParametersOfClass(string $a_type, string $a_class, int $a_mq_id=0)
static array $num_unit_no_perc
static writeOwner($obj_id, $style_id)
static DOMDocument $basic_style_dom
do_3_10_Migration()
Migrates 3.10 style to 3.11 style.
static _determineTag(string $a_type)
templateExists(string $a_template_name)
Check whether template exists.
static string $basic_style_image_dir
deleteMediaQuery(int $a_id)
Delete media query.
deleteParameter(int $a_id)
delete style parameter
getColors()
Get colors of style.
static _isHideable(string $a_type)
createImagesDirectory()
Create images directory <data_dir>/sty/sty_<id>/images.
static _writeUpToDate(int $a_id, bool $a_up_to_date)
static array $hideable_types
removeColor(string $a_name)
Remove a color.
lookupTemplatePreview(int $a_t_id)
Lookup table template preview.
writeStyleSetting(string $a_name, string $a_value)
static lookupObjectStyle(int $a_obj_id)
Lookup object style.
addParameter(string $a_tag, string $a_par, string $a_type, int $a_mq_id=0, bool $a_custom=false)
write style parameter to db
static _getTemplateClassTypes(string $a_template_type="")
Get template class types.
static array $style_super_types
determineTemplateStyleClassType(string $t, string $k)
static _getStyleSuperTypeForType(string $a_type)
getXML()
get xml representation of style object todo: add mq_id
static _getStyleParameters(string $a_tag="")
static _isExpandable(string $a_type)
static _lookupTemplateName(int $a_t_id)
Lookup table template name for template ID.
do_3_9_Migration(int $a_id)
Migrate old 3.9 styles.
static _getStyleParameterValues(string $par)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
static _getAllReferences(int $id)
get all reference ids for object ID
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
static _getObjectsDataForType(string $type, bool $omit_trash=false)
get all objects of a certain type
static _lookupTitle(int $obj_id)
static subStr(string $a_str, int $a_start, ?int $a_length=null)
Definition: class.ilStr.php:24
static signFile(string $path_to_file)
$c
Definition: cli.php:38
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
return['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
global $DIC
Definition: feed.php:28
$ref_id
Definition: ltiauth.php:67
$path
Definition: ltiservices.php:32
$res
Definition: ltiservices.php:69
$service
Definition: ltiservices.php:43
$xml
Definition: metadata.php:351
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
header include for all ilias files.
global $ilSetting
Definition: privfeed.php:17
$type
$ilErr
Definition: raiseError.php:17
$lng