ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
class.ilObjStyleSheet.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
29{
31 protected \ILIAS\Style\Content\InternalRepoService $repo;
32 protected bool $is_3_10_skin = false;
33 protected string $export_sub_dir = "";
34 protected array $chars_by_type = [];
35 protected array $end_styles = [];
36 protected array $chars = [];
37 protected bool $up_to_date = false;
38 public array $style = [];
39 protected array $hidden_chars = [];
40 protected array $style_class = [];
41
42 protected int $scope = 0;
43
44 public static array $num_unit = array("px", "em", "rem", "ex", "%", "pt", "pc", "in", "mm", "cm");
45 public static array $num_unit_no_perc = array("px", "em", "rem", "ex", "pt", "pc", "in", "mm", "cm");
46
47 // css parameters and their attribute values, input type and group
48 public static array $parameter = array(
49 "font-size" => array(
50 "values" => array("xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "smaller", "larger"),
51 "input" => "fontsize",
52 "group" => "text"),
53 "font-family" => array(
54 "values" => array(),
55 "input" => "text",
56 "group" => "text"),
57 "font-style" => array(
58 "values" => array("italic", "oblique", "normal"),
59 "input" => "select",
60 "group" => "text"),
61 "font-weight" => array(
62 "values" => array("bold", "normal", "bolder", "lighter"),
63 "input" => "select",
64 "group" => "text"),
65 "font-variant" => array(
66 "values" => array("small-caps", "normal"),
67 "input" => "select",
68 "group" => "text"),
69 "word-spacing" => array(
70 "values" => array(),
71 "input" => "numeric_no_perc",
72 "group" => "text"),
73 "letter-spacing" => array(
74 "values" => array(),
75 "input" => "numeric_no_perc",
76 "group" => "text"),
77 "text-decoration" => array(
78 "values" => array("underline", "overline", "line-through", "blink", "none"),
79 "input" => "select",
80 "group" => "text"),
81 "text-transform" => array(
82 "values" => array("capitalize", "uppercase", "lowercase", "none"),
83 "input" => "select",
84 "group" => "text"),
85 "color" => array(
86 "values" => array(),
87 "input" => "color",
88 "group" => "text"),
89 "text-indent" => array(
90 "values" => array(),
91 "input" => "numeric",
92 "group" => "text"),
93 "line-height" => array(
94 "values" => array(),
95 "input" => "numeric",
96 "group" => "text"),
97 "vertical-align" => array(
98 "values" => array("top", "middle", "bottom", "baseline", "sub", "super",
99 "text-top", "text-bottom"),
100 "input" => "select",
101 "group" => "text"),
102 "text-align" => array(
103 "values" => array("left", "center", "right", "justify"),
104 "input" => "select",
105 "group" => "text"),
106 "white-space" => array(
107 "values" => array("normal", "pre", "nowrap"),
108 "input" => "select",
109 "group" => "text"),
110 "margin" => array(
111 "values" => array(),
112 "input" => "trbl_numeric",
113 "subpar" => array("margin", "margin-top", "margin-right",
114 "margin-bottom", "margin-left"),
115 "group" => "margin_and_padding"),
116 "padding" => array(
117 "values" => array(),
118 "input" => "trbl_numeric",
119 "subpar" => array("padding", "padding-top", "padding-right",
120 "padding-bottom", "padding-left"),
121 "group" => "margin_and_padding"),
122 "border-width" => array(
123 "values" => array("thin", "medium", "thick"),
124 "input" => "border_width",
125 "subpar" => array("border-width", "border-top-width", "border-right-width",
126 "border-bottom-width", "border-left-width"),
127 "group" => "border"),
128 "border-color" => array(
129 "values" => array(),
130 "input" => "trbl_color",
131 "subpar" => array("border-color", "border-top-color", "border-right-color",
132 "border-bottom-color", "border-left-color"),
133 "group" => "border"),
134 "border-style" => array(
135 "values" => array("none", "hidden", "dotted", "dashed", "solid", "double",
136 "groove", "ridge", "inset", "outset"),
137 "input" => "border_style",
138 "subpar" => array("border-style", "border-top-style", "border-right-style",
139 "border-bottom-style", "border-left-style"),
140 "group" => "border"),
141
142 "background-color" => array(
143 "values" => array(),
144 "input" => "color",
145 "group" => "background"),
146 "background-image" => array(
147 "values" => array(),
148 "input" => "background_image",
149 "group" => "background"),
150 "background-repeat" => array(
151 "values" => array("repeat", "repeat-x", "repeat-y", "no-repeat"),
152 "input" => "select",
153 "group" => "background"),
154 "background-attachment" => array(
155 "values" => array("fixed", "scroll"),
156 "input" => "select",
157 "group" => "background"),
158 "background-position" => array(
159 "values" => array("horizontal" => array("left", "center", "right"),
160 "vertical" => array("top", "center", "bottom")),
161 "input" => "background_position",
162 "group" => "background"),
163
164 "position" => array(
165 "values" => array("absolute", "fixed", "relative", "static"),
166 "input" => "select",
167 "group" => "positioning"),
168 "top" => array(
169 "values" => array(),
170 "input" => "numeric",
171 "group" => "positioning"),
172 "bottom" => array(
173 "values" => array(),
174 "input" => "numeric",
175 "group" => "positioning"),
176 "left" => array(
177 "values" => array(),
178 "input" => "numeric",
179 "group" => "positioning"),
180 "right" => array(
181 "values" => array(),
182 "input" => "numeric",
183 "group" => "positioning"),
184 "width" => array(
185 "values" => array(),
186 "input" => "numeric",
187 "group" => "positioning"),
188 "height" => array(
189 "values" => array(),
190 "input" => "numeric",
191 "group" => "positioning"),
192 "min-height" => array(
193 "values" => array(),
194 "input" => "numeric",
195 "group" => "positioning"),
196 "float" => array(
197 "values" => array("left", "right", "none"),
198 "input" => "select",
199 "group" => "positioning"),
200 "overflow" => array(
201 "values" => array("visible", "hidden", "scroll", "auto"),
202 "input" => "select",
203 "group" => "positioning"),
204 "opacity" => array(
205 "values" => array(),
206 "input" => "percentage",
207 "group" => "special"),
208 "transform" => array(
209 "values" => array("rotate(90deg)", "rotate(180deg)", "rotate(270deg)"),
210 "input" => "select",
211 "group" => "special"),
212 "transform-origin" => array(
213 "values" => array( "horizontal" => array("left", "center", "right"),
214 "vertical" => array("top", "center", "bottom")),
215 "input" => "background_position",
216 "group" => "special"),
217 "cursor" => array(
218 "values" => array("auto", "default", "crosshair", "pointer", "move",
219 "n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize",
220 "w-resize", "nw-resize", "text", "wait", "help"),
221 "input" => "select",
222 "group" => "special"),
223 "clear" => array(
224 "values" => array("both","left","right","none"),
225 "input" => "select",
226 "group" => "special"),
227
228 "list-style-type.ol" => array(
229 "values" => array("decimal","lower-roman","upper-roman",
230 "lower-alpha", "upper-alpha", "lower-greek", "hebrew",
231 "decimal-leading-zero", "cjk-ideographic", "hiragana",
232 "katakana", "hiragana-iroha", "katakana-iroha", "none"),
233 "input" => "select",
234 "group" => "ol"),
235 "list-style-type.ul" => array(
236 "values" => array("disc","circle","square",
237 "none"),
238 "input" => "select",
239 "group" => "ul"),
240 "list-style-image.ul" => array(
241 "values" => array(),
242 "input" => "background_image",
243 "group" => "ul"),
244 "list-style-position.ol" => array(
245 "values" => array("inside","outside"),
246 "input" => "select",
247 "group" => "ol"),
248 "list-style-position.ul" => array(
249 "values" => array("inside","outside"),
250 "input" => "select",
251 "group" => "ul"
252 ),
253 "border-collapse" => array(
254 "values" => array("collapse","separate"),
255 "input" => "select",
256 "group" => "table"
257 ),
258 "caption-side" => array(
259 "values" => array("top","bottom","left","right"),
260 "input" => "select",
261 "group" => "table"
262 )
263 );
264
265 // filter groups of properties that should only be
266 // displayed with matching tag (group -> tags)
267 public static array $filtered_groups =
268 array("ol" => array("ol"), "ul" => array("ul"),
269 "table" => array("table"), "positioning" => array("h1", "h2", "h3", "div", "img", "table", "a", "figure", "li", "p"));
270
271 // style types and their super type
272 public static array $style_super_types = array(
273 "text_block" => array("text_block", "heading1", "heading2", "heading3", "code_block"),
274 "text_inline" => array("text_inline", "sub", "sup", "code_inline", "strong", "em"),
275 "section" => array("section"),
276 "link" => array("link"),
277 "table" => array("table", "table_cell", "table_caption"),
278 "list" => array("list_o", "list_u", "list_item"),
279 "flist" => array("flist_cont", "flist_head", "flist", "flist_li", "flist_a"),
280 "media" => array("media_cont", "media_caption", "iim", "marker"),
281 "tabs" => array("va_cntr", "va_icntr", "va_ihead", "va_iheada", "va_ihcap", "va_icont",
282 "ha_cntr", "ha_icntr", "ha_ihead", "ha_iheada", "ha_ihcap", "ha_icont", "ca_cntr", "ca_icntr", "ca_ihead", "ca_icont"),
283 "question" => array("question", "qtitle", "qanswer", "qinput", "qlinput", "qsubmit", "qfeedr", "qfeedw",
284 "qimg", "qordul", "qordli", "qimgd", "qetitem", "qetcorr", "qover"),
285 "page" => array("page_cont", "page_title", "page_fn")
286 );
287
288 // these types are expandable, i.e. the user can define new style classes
289 public static array $expandable_types = array(
290 "text_block",
291 "text_inline", "section", "media_cont", "media_caption", "table", "table_cell", "flist_li", "table_caption",
292 "list_o", "list_u", "list_item",
293 "va_cntr", "va_icntr", "va_ihead", "va_iheada", "va_ihcap", "va_icont",
294 "ha_cntr", "ha_icntr", "ha_ihead", "ha_iheada", "ha_ihcap", "ha_icont",
295 "ca_cntr", "ca_icntr", "ca_ihead", "ca_icont"
296 );
297
298 // these types can be hidden in the content editor
299 public static array $hideable_types = array(
300 "table", "table_cell"
301 );
302
303 // tag that are used by style types
304 public static array $assigned_tags = array(
305 "text_block" => "p",
306 "heading1" => "h1",
307 "heading2" => "h2",
308 "heading3" => "h3",
309 "code_block" => "pre",
310 "em" => "em",
311 "text_inline" => "span",
312 "code_inline" => "code",
313 "sup" => "sup",
314 "sub" => "sub",
315 "strong" => "strong",
316 "section" => "div",
317 "link" => "a",
318 "table" => "table",
319 "table_cell" => "td",
320 "table_caption" => "caption",
321 "media_cont" => "figure",
322 "media_caption" => "div",
323 "iim" => "div",
324 "marker" => "a",
325 "list_o" => "ol",
326 "list_u" => "ul",
327 "list_item" => "li",
328 "flist_cont" => "div",
329 "flist_head" => "div",
330 "flist" => "ul",
331 "flist_li" => "li",
332 "flist_a" => "a",
333 "question" => "div",
334 "qtitle" => "div",
335 "qanswer" => "div",
336 "qimg" => "img",
337 "qimgd" => "a",
338 "qordul" => "ul",
339 "qordli" => "li",
340 "qetitem" => "a",
341 "qetcorr" => "span",
342 "qinput" => "input",
343 "qlinput" => "textarea",
344 "qsubmit" => "input",
345 "qfeedr" => "div",
346 "qfeedw" => "div",
347 "qover" => "div",
348 "page_cont" => "div",
349 "page_fn" => "div",
350 "page" => "div",
351 "page_title" => "h1",
352 "va_cntr" => "div",
353 "va_icntr" => "div",
354 "va_icont" => "div",
355 "va_ihead" => "div",
356 "va_iheada" => "div",
357 "va_ihcap" => "div",
358 "ha_cntr" => "div",
359 "ha_icntr" => "div",
360 "ha_icont" => "div",
361 "ha_iheada" => "div",
362 "ha_ihcap" => "div",
363 "ha_ihead" => "div",
364 "ca_cntr" => "div",
365 "ca_icntr" => "div",
366 "ca_ihead" => "div",
367 "ca_icont" => "div"
368 );
369
370 // pseudo classes
371 public static array $pseudo_classes =
372 [
373 "a" => ["hover"],
374 "div" => ["hover", "before"],
375 "img" => ["hover"],
376 "li" => ["before"],
377 "input" => ["hover"],
378 ];
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" => "em", "class" => "Emph"),
391 array("type" => "text_inline", "class" => "Quotation"),
392 array("type" => "strong", "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_cont", "class" => "PageContainer"),
411 array("type" => "page", "class" => "Page"),
412 array("type" => "page_fn", "class" => "Footnote"),
413 array("type" => "page_title", "class" => "PageTitle"),
414 array("type" => "list_o", "class" => "NumberedList"),
415 array("type" => "list_u", "class" => "BulletedList"),
416 array("type" => "list_item", "class" => "StandardListItem"),
417 array("type" => "question", "class" => "Standard"),
418 array("type" => "question", "class" => "SingleChoice"),
419 array("type" => "question", "class" => "MultipleChoice"),
420 array("type" => "question", "class" => "TextQuestion"),
421 array("type" => "question", "class" => "OrderingQuestion"),
422 array("type" => "question", "class" => "MatchingQuestion"),
423 array("type" => "question", "class" => "ImagemapQuestion"),
424 array("type" => "question", "class" => "ErrorText"),
425 array("type" => "question", "class" => "TextSubset"),
426 array("type" => "question", "class" => "ClozeTest"),
427 array("type" => "qtitle", "class" => "Title"),
428 array("type" => "qanswer", "class" => "Answer"),
429 array("type" => "qimg", "class" => "QuestionImage"),
430 array("type" => "qimgd", "class" => "ImageDetailsLink"),
431 array("type" => "qordul", "class" => "OrderList"),
432 array("type" => "qordli", "class" => "OrderListItem"),
433 array("type" => "qordul", "class" => "OrderListHorizontal"),
434 array("type" => "qordli", "class" => "OrderListItemHorizontal"),
435 array("type" => "qetitem", "class" => "ErrorTextItem"),
436 array("type" => "qetitem", "class" => "ErrorTextSelected"),
437 array("type" => "qetcorr", "class" => "ErrorTextCorrected"),
438 array("type" => "qinput", "class" => "TextInput"),
439 array("type" => "qlinput", "class" => "LongTextInput"),
440 array("type" => "qsubmit", "class" => "Submit"),
441 array("type" => "qfeedr", "class" => "FeedbackRight"),
442 array("type" => "qfeedw", "class" => "FeedbackWrong"),
443 array("type" => "qover", "class" => "Correct"),
444 array("type" => "qover", "class" => "Inorrect"),
445 array("type" => "qover", "class" => "StatusMessage"),
446 array("type" => "qover", "class" => "WrongAnswersMessage"),
447 array("type" => "flist_cont", "class" => "FileListContainer"),
448 array("type" => "flist_head", "class" => "FileListHeading"),
449 array("type" => "flist", "class" => "FileList"),
450 array("type" => "flist_li", "class" => "FileListItem"),
451 array("type" => "flist_a", "class" => "FileListItemLink")
452 );
453
454 public static array $templates = array(
455 "table" => array(
456 "table" => "table",
457 "caption" => "table_caption",
458 "row_head" => "table_cell",
459 "row_foot" => "table_cell",
460 "col_head" => "table_cell",
461 "col_foot" => "table_cell",
462 "odd_row" => "table_cell",
463 "even_row" => "table_cell",
464 "odd_col" => "table_cell",
465 "even_col" => "table_cell"),
466 "vaccordion" => array(
467 "va_cntr" => "va_cntr",
468 "va_icntr" => "va_icntr",
469 "va_ihead" => "va_ihead",
470 "va_iheada" => "va_iheada",
471 "va_ihcap" => "va_ihcap",
472 "va_icont" => "va_icont"
473 ),
474 "haccordion" => array(
475 "ha_cntr" => "ha_cntr",
476 "ha_icntr" => "ha_icntr",
477 "ha_ihead" => "ha_ihead",
478 "ha_iheada" => "ha_iheada",
479 "ha_ihcap" => "ha_ihcap",
480 "ha_icont" => "ha_icont"
481 ),
482 "carousel" => array(
483 "ca_cntr" => "ca_cntr",
484 "ca_icntr" => "ca_icntr",
485 "ca_ihead" => "ca_ihead",
486 "ca_icont" => "ca_icont"
487 )
488 );
489
490 // basic style xml file, image directory and dom
491 protected static string $basic_style_file = "../vendor/ilias/Style/basic_style/style.xml";
492 protected static string $basic_style_zip = "../vendor/ilias/Style/basic_style/style.zip";
493 protected static string $basic_style_image_dir = "./components/ILIAS/COPage/basic_style/images";
494 protected static ?DOMDocument $basic_style_dom = null;
495
496 public function __construct(
497 int $a_id = 0,
498 bool $a_call_by_reference = false
499 ) {
500 global $DIC;
501
502 $this->db = $DIC->database();
503 $this->lng = $DIC->language();
504 $this->type = "sty";
505 $this->style = array();
506 $this->ilias = $DIC["ilias"];
507 $this->domain = $DIC->contentStyle()->internal()->domain();
508
509 if ($a_call_by_reference) {
510 $this->ilias->raiseError("Can't instantiate style object via reference id.", $this->ilias->error_obj->FATAL);
511 }
512 parent::__construct($a_id, false);
513 $this->repo = $DIC->contentStyle()->internal()->repo();
514 }
515
516 public static function getBasicZipPath(): string
517 {
519 }
520
524 public function setUpToDate(bool $a_up_to_date = true): void
525 {
526 $this->up_to_date = $a_up_to_date;
527 }
528
529 public function getUpToDate(): bool
530 {
531 return $this->up_to_date;
532 }
533
534 public function setScope(int $a_scope): void
535 {
536 $this->scope = $a_scope;
537 }
538
539 public function getScope(): int
540 {
541 return $this->scope;
542 }
543
544 public static function _writeUpToDate(
545 int $a_id,
546 bool $a_up_to_date
547 ): void {
548 global $DIC;
549
550 $ilDB = $DIC->database();
551
552 $q = "UPDATE style_data SET uptodate = " .
553 $ilDB->quote((int) $a_up_to_date, "integer") .
554 " WHERE id = " . $ilDB->quote($a_id, "integer");
555 $ilDB->manipulate($q);
556 }
557
558 public static function writeOwner($obj_id, $style_id): void
559 {
560 global $DIC;
561 $ilDB = $DIC->database();
562
563 $q = "UPDATE style_data SET owner_obj = " .
564 $ilDB->quote((int) $obj_id, "integer") .
565 " WHERE id = " . $ilDB->quote($style_id, "integer");
566 $ilDB->manipulate($q);
567 }
568
569 public static function _lookupUpToDate(int $a_id): bool
570 {
571 global $DIC;
572
573 $ilDB = $DIC->database();
574
575 $q = "SELECT uptodate FROM style_data " .
576 " WHERE id = " . $ilDB->quote($a_id, "integer");
577 $res = $ilDB->query($q);
578 $sty = $ilDB->fetchAssoc($res);
579
580 return (bool) $sty["uptodate"];
581 }
582
586 public static function _writeStandard(
587 int $a_id,
588 bool $a_std
589 ): void {
590 global $DIC;
591
592 $ilDB = $DIC->database();
593
594 $q = "UPDATE style_data SET standard = " .
595 $ilDB->quote((int) $a_std, "integer") .
596 " WHERE id = " . $ilDB->quote($a_id, "integer");
597 $ilDB->manipulate($q);
598 }
599
600 public static function _writeScope(int $a_id, int $a_scope): void
601 {
602 global $DIC;
603
604 $ilDB = $DIC->database();
605
606 $q = "UPDATE style_data SET category = " .
607 $ilDB->quote($a_scope, "integer") .
608 " WHERE id = " . $ilDB->quote($a_id, "integer");
609 $ilDB->manipulate($q);
610 }
611
615 public static function _lookupStandard(int $a_id): bool
616 {
617 global $DIC;
618
619 $ilDB = $DIC->database();
620
621 $q = "SELECT * FROM style_data " .
622 " WHERE id = " . $ilDB->quote($a_id, "integer");
623 $res = $ilDB->query($q);
624 $sty = $ilDB->fetchAssoc($res);
625
626 return (bool) ($sty["standard"] ?? false);
627 }
628
629 public static function _writeActive(int $a_id, bool $a_active): void
630 {
631 global $DIC;
632
633 $ilDB = $DIC->database();
634
635 $q = "UPDATE style_data SET active = " .
636 $ilDB->quote((int) $a_active, "integer") .
637 " WHERE id = " . $ilDB->quote($a_id, "integer");
638 $ilDB->manipulate($q);
639 }
640
644 public static function _lookupActive(int $a_id): bool
645 {
646 global $DIC;
647
648 $ilDB = $DIC->database();
649
650 $q = "SELECT * FROM style_data " .
651 " WHERE id = " . $ilDB->quote($a_id, "integer");
652 $res = $ilDB->query($q);
653 $sty = $ilDB->fetchAssoc($res);
654
655 return (bool) $sty["active"];
656 }
657
662 public static function _getStandardStyles(
663 bool $a_exclude_default_style = false,
664 bool $a_include_deactivated = false,
665 int $a_scope = 0
666 ): array {
667 global $DIC;
668
669 $ilDB = $DIC->database();
670 $ilSetting = $DIC->settings();
671 $tree = $DIC->repositoryTree();
672
673 $default_style = $ilSetting->get("default_content_style_id");
674
675 $and_str = "";
676 if (!$a_include_deactivated) {
677 $and_str = " AND active = 1";
678 }
679
680 $q = "SELECT * FROM style_data " .
681 " WHERE standard = 1" . $and_str;
682 $res = $ilDB->query($q);
683 $styles = array();
684 while ($sty = $ilDB->fetchAssoc($res)) {
685 if (!$a_exclude_default_style || $default_style != $sty["id"]) {
686 // check scope
687 if ($a_scope > 0 && $sty["category"] > 0) {
688 if ($tree->isInTree((int) $sty["category"]) &&
689 $tree->isInTree($a_scope)) {
690 $path = $tree->getPathId($a_scope);
691 if (!in_array((int) $sty["category"], $path)) {
692 continue;
693 }
694 }
695 }
696 $styles[(int) $sty["id"]] = ilObject::_lookupTitle((int) $sty["id"]);
697 }
698 }
699
700 return $styles;
701 }
702
703
709 public static function _getClonableContentStyles(): array
710 {
711 global $DIC;
712
713 $ilAccess = $DIC->access();
714 $ilDB = $DIC->database();
715
716 $clonable_styles = array();
717
718 $q = "SELECT * FROM style_data";
719 $style_set = $ilDB->query($q);
720 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
721 $clonable = false;
722 if ($style_rec["standard"] == 1) {
723 if ($style_rec["active"] == 1) {
724 $clonable = true;
725 }
726 } else {
727 $obj_ids = ilObjContentObject::_lookupContObjIdByStyleId((int) $style_rec["id"]);
728 if (count($obj_ids) == 0) {
729 $obj_ids = self::lookupObjectForStyle((int) $style_rec["id"]);
730 }
731 foreach ($obj_ids as $id) {
732 $ref = ilObject::_getAllReferences((int) $id);
733 foreach ($ref as $ref_id) {
734 if ($ilAccess->checkAccess("write", "", $ref_id)) {
735 $clonable = true;
736 }
737 }
738 }
739 }
740 if ($clonable) {
741 $clonable_styles[(int) $style_rec["id"]] =
742 ilObject::_lookupTitle((int) $style_rec["id"]);
743 }
744 }
745
746 asort($clonable_styles);
747
748 return $clonable_styles;
749 }
750
751 public static function _getBasicStyleDom(): DOMDocument
752 {
753 if (!is_object(self::$basic_style_dom)) {
754 self::$basic_style_dom = new DOMDocument();
755 self::$basic_style_dom->load(self::$basic_style_file);
756 }
757
758 return self::$basic_style_dom;
759 }
760
761 public static function getBasicImageDir(): string
762 {
763 return self::$basic_style_image_dir;
764 }
765
766
770 public function create(
771 int $a_from_style = 0,
772 bool $a_import_mode = false
773 ): int {
774 global $DIC;
775
776 $ilDB = $this->db;
777
778 $id = parent::create();
779
780 $service = $DIC->contentStyle()
781 ->internal();
782 $access_manager = $service->domain()->access(
783 0,
784 $DIC->user()->getId()
785 );
786 $access_manager->enableWrite(true);
787 $color_manager = $service->domain()->color($this->getId(), $access_manager);
788
789 if ($a_from_style == 0) {
790 if (!$a_import_mode) {
791 throw new Exception("Can't create style without a from style in non-import mode.");
792 } else {
793 // add style_data record
794 $q = "INSERT INTO style_data (id, uptodate, category) VALUES " .
795 "(" . $ilDB->quote($this->getId(), "integer") . ", 0," .
796 $ilDB->quote($this->getScope(), "integer") . ")";
797 $ilDB->manipulate($q);
798 $service->domain()->style($this->getId())->createRid();
799 }
800 } else {
801 // get style parameter records
802 $def = array();
803 $q = "SELECT * FROM style_parameter WHERE style_id = " .
804 $ilDB->quote($a_from_style, "integer");
805 $par_set = $ilDB->query($q);
806 while ($par_rec = $ilDB->fetchAssoc($par_set)) {
807 $def[] = array("tag" => $par_rec["tag"], "class" => $par_rec["class"],
808 "parameter" => $par_rec["parameter"], "value" => $par_rec["value"],
809 "type" => $par_rec["type"], "mq_id" => $par_rec["mq_id"], "custom" => $par_rec["custom"]);
810 }
811
812 $char_repo = $this->repo->characteristic();
813 $char_repo->cloneAllFromStyle($a_from_style, $this->getId());
814
815
816 // copy media queries
817 $from_style = new ilObjStyleSheet($a_from_style);
818 $mqs = $from_style->getMediaQueries();
819 $mq_mapping = array();
820 foreach ($mqs as $mq) {
821 $nid = $this->addMediaQuery($mq["mquery"]);
822 $mq_mapping[$mq["id"]] = $nid;
823 }
824
825 // default style settings
826 foreach ($def as $sty) {
827 $id = $ilDB->nextId("style_parameter");
828 $q = "INSERT INTO style_parameter (id, style_id, tag, class, parameter, value, type, mq_id, custom) VALUES " .
829 "(" .
830 $ilDB->quote($id, "integer") . "," .
831 $ilDB->quote($this->getId(), "integer") . "," .
832 $ilDB->quote($sty["tag"], "text") . "," .
833 $ilDB->quote($sty["class"], "text") . "," .
834 $ilDB->quote($sty["parameter"], "text") . "," .
835 $ilDB->quote($sty["value"], "text") . "," .
836 $ilDB->quote($sty["type"], "text") . "," .
837 $ilDB->quote((int) ($mq_mapping[$sty["mq_id"]] ?? 0), "integer") . "," .
838 $ilDB->quote($sty["custom"], "integer") .
839 ")";
840 $ilDB->manipulate($q);
841 }
842
843 // add style_data record
844 $q = "INSERT INTO style_data (id, uptodate, category) VALUES " .
845 "(" . $ilDB->quote($this->getId(), "integer") . ", 0," .
846 $ilDB->quote($this->getScope(), "integer") . ")";
847 $ilDB->manipulate($q);
848 $service->domain()->style($this->getId())->createRid();
849
850 // copy images
851 $this->domain->style($this->getId())->cloneResourceContainer($from_style->getId());
852 // copy colors
853 $colors = $from_style->getColors();
854 foreach ($colors as $c) {
855 $color_manager->addColor($c["name"], $c["code"]);
856 }
857
858 // copy templates
860 foreach ($tcts as $tct => $v) {
861 $templates = $from_style->getTemplates($tct);
862 foreach ($templates as $t) {
863 $this->addTemplate($tct, $t["name"], $t["classes"]);
864 }
865 }
866 }
867
868 $this->read();
869 if (!$a_import_mode) {
870 $this->writeCSSFile();
871 }
872
873 return $id;
874 }
875
879 public function characteristicExists(
880 string $a_char,
881 string $a_style_type
882 ): bool {
883 $ilDB = $this->db;
884
885 $set = $ilDB->queryF(
886 "SELECT style_id FROM style_char WHERE style_id = %s AND characteristic = %s AND type = %s",
887 array("integer", "text", "text"),
888 array($this->getId(), $a_char, $a_style_type)
889 );
890 if ($ilDB->fetchAssoc($set)) {
891 return true;
892 }
893 return false;
894 }
895
896 public function addCharacteristic(
897 string $a_type,
898 string $a_char,
899 bool $a_hidden = false,
900 int $order_nr = 0,
901 bool $outdated = false
902 ): void {
903 $ilDB = $this->db;
904
905 // delete characteristic record
906 $ilDB->insert("style_char", [
907 "style_id" => ["integer", $this->getId()],
908 "type" => ["text", $a_type],
909 "characteristic" => ["text", $a_char],
910 "hide" => ["integer", (int) $a_hidden],
911 "outdated" => ["integer", (int) $outdated],
912 "order_nr" => ["integer", $order_nr]
913 ]);
914
915 $this->setUpToDate(false);
916 $this->_writeUpToDate($this->getId(), false);
917 }
918
922 public function getCharacteristics(
923 string $a_type = "",
924 bool $a_no_hidden = false,
925 bool $a_include_core = true
926 ): array {
927 $chars = array();
928
929 if ($a_type == "") {
930 $chars = $this->chars;
931 }
932 if (isset($this->chars_by_type[$a_type])) {
933 foreach ($this->chars_by_type[$a_type] as $c) {
934 if ($a_include_core || !self::isCoreStyle($a_type, $c)) {
935 $chars[] = $c;
936 }
937 }
938 }
939
940 if ($a_no_hidden) {
941 foreach ($chars as $k => $char) {
942 if ($a_type == "" && $this->hidden_chars[$char["type"] . ":" . $char["class"]]) {
943 unset($chars[$k]);
944 } elseif ($this->hidden_chars[$a_type . ":" . $char] ?? false) {
945 unset($chars[$k]);
946 }
947 }
948 }
949
950 return $chars;
951 }
952
953 public function hasCharacteristic(string $type, string $char): bool
954 {
955 $chars = $this->getCharacteristics($type);
956 return in_array($char, $chars);
957 }
958
959 public function setCharacteristics(array $a_chars): void
960 {
961 $this->chars = $a_chars;
962 }
963
967 public function saveHideStatus(
968 string $a_type,
969 string $a_char,
970 bool $a_hide
971 ): void {
972 $ilDB = $this->db;
973
974 $ilDB->manipulate(
975 "UPDATE style_char SET " .
976 " hide = " . $ilDB->quote((int) $a_hide, "integer") .
977 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
978 " type = " . $ilDB->quote($a_type, "text") . " AND " .
979 " characteristic = " . $ilDB->quote($a_char, "text")
980 );
981 }
982
986 public function getHideStatus(
987 string $a_type,
988 string $a_char
989 ): bool {
990 $ilDB = $this->db;
991
992 $set = $ilDB->query(
993 "SELECT hide FROM style_char " .
994 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
995 " type = " . $ilDB->quote($a_type, "text") . " AND " .
996 " characteristic = " . $ilDB->quote($a_char, "text")
997 );
998 $rec = $ilDB->fetchAssoc($set);
999
1000 return (bool) ($rec["hide"] ?? false);
1001 }
1002
1006 public function ilClone(): int
1007 {
1008 $lng = $this->lng;
1009
1010 $lng->loadLanguageModule("style");
1011
1012 $new_obj = new ilObjStyleSheet();
1013 $new_obj->setTitle($this->getTitle() . " (" . $lng->txt("sty_acopy") . ")");
1014 $new_obj->setType($this->getType());
1015 $new_obj->setDescription($this->getDescription());
1016 $new_obj->create($this->getId());
1017
1018 $new_obj->writeStyleSetting(
1019 "disable_auto_margins",
1020 $this->lookupStyleSetting("disable_auto_margins")
1021 );
1022
1023 return $new_obj->getId();
1024 }
1025
1029 public function copyImagesToDir(string $a_target): void
1030 {
1031 ilFileUtils::rCopy($this->getImagesDirectory(), $a_target);
1032 }
1033
1043 public function addParameter(
1044 string $a_tag,
1045 string $a_par,
1046 string $a_type,
1047 int $a_mq_id = 0,
1048 bool $a_custom = false
1049 ): void {
1050 $ilDB = $this->db;
1051
1052 $avail_params = $this->getAvailableParameters();
1053 $tag = explode(".", $a_tag);
1054 $value = $avail_params[$a_par][0];
1055 $id = $ilDB->nextId("style_parameter");
1056 $q = "INSERT INTO style_parameter (id,style_id, type, tag, class, parameter, value, mq_id, custom) VALUES " .
1057 "(" .
1058 $ilDB->quote($id, "integer") . "," .
1059 $ilDB->quote($this->getId(), "integer") . "," .
1060 $ilDB->quote($a_type, "text") . "," .
1061 $ilDB->quote($tag[0], "text") . "," .
1062 $ilDB->quote($tag[1], "text") . "," .
1063 $ilDB->quote($a_par, "text") . "," .
1064 $ilDB->quote($value, "text") . "," .
1065 $ilDB->quote($a_mq_id, "integer") . "," .
1066 $ilDB->quote($a_custom, "integer") .
1067 ")";
1068 $ilDB->manipulate($q);
1069 $this->read();
1070 $this->writeCSSFile();
1071 }
1072
1077 public function createImagesDirectory(): void
1078 {
1080 }
1081
1086 public static function _createImagesDirectory(
1087 int $a_style_id
1088 ): void {
1089 global $DIC;
1090
1091 $ilErr = $DIC["ilErr"];
1092
1093 $sty_data_dir = ilFileUtils::getWebspaceDir() . "/sty";
1094 if (!is_dir($sty_data_dir)) {
1095 ilFileUtils::makeDir($sty_data_dir);
1096 }
1097 if (!is_writable($sty_data_dir)) {
1098 $ilErr->raiseError("Style data directory (" . $sty_data_dir
1099 . ") not writeable.", $ilErr->FATAL);
1100 }
1101
1102 $style_dir = $sty_data_dir . "/sty_" . $a_style_id;
1103 if (!is_dir($style_dir)) {
1104 ilFileUtils::makeDir($style_dir);
1105 }
1106 if (!is_dir($style_dir)) {
1107 $ilErr->raiseError("Creation of style directory failed (" .
1108 $style_dir . ").", $ilErr->FATAL);
1109 }
1110
1111 // create images subdirectory
1112 $im_dir = $style_dir . "/images";
1113 if (!is_dir($im_dir)) {
1114 ilFileUtils::makeDir($im_dir);
1115 }
1116 if (!is_dir($im_dir)) {
1117 $ilErr->raiseError("Creation of Import Directory failed (" .
1118 $im_dir . ").", $ilErr->FATAL);
1119 }
1120
1121 // create thumbnails directory
1122 $thumb_dir = $style_dir . "/images/thumbnails";
1123 ilFileUtils::makeDir($thumb_dir);
1124 if (!is_dir($thumb_dir)) {
1125 $ilErr->raiseError("Creation of Import Directory failed (" .
1126 $thumb_dir . ").", $ilErr->FATAL);
1127 }
1128 }
1129
1130 public function getImagesDirectory(): string
1131 {
1133 }
1134
1135 public static function _getImagesDirectory(int $a_style_id): string
1136 {
1137 return ilFileUtils::getWebspaceDir() . "/sty/sty_" . $a_style_id .
1138 "/images";
1139 }
1140
1141 public function getThumbnailsDirectory(): string
1142 {
1143 return $this->getImagesDirectory() .
1144 "/thumbnails";
1145 }
1146
1150 public function deleteParameter(int $a_id): void
1151 {
1152 $ilDB = $this->db;
1153
1154 $q = "DELETE FROM style_parameter WHERE id = " .
1155 $ilDB->quote($a_id, "integer");
1156 $ilDB->query($q);
1157 }
1158
1159
1167 public function deleteCustomStylePars(
1168 string $a_tag,
1169 string $a_class,
1170 string $a_type,
1171 int $a_mq_id = 0
1172 ): void {
1173 $ilDB = $this->db;
1174
1175 $q = "DELETE FROM style_parameter WHERE " .
1176 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
1177 " tag = " . $ilDB->quote($a_tag, "text") . " AND " .
1178 " class = " . $ilDB->quote($a_class, "text") . " AND " .
1179 " mq_id = " . $ilDB->quote($a_mq_id, "integer") . " AND " .
1180 " custom = " . $ilDB->quote(1, "integer") . " AND " .
1181 " " . $ilDB->equals("type", $a_type, "text", true);
1182
1183 $ilDB->manipulate($q);
1184 }
1185
1189 public function deleteStyleParOfChar(
1190 string $a_type,
1191 string $a_class
1192 ): void {
1193 $ilDB = $this->db;
1194
1195 $q = "DELETE FROM style_parameter WHERE " .
1196 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
1197 " class = " . $ilDB->quote($a_class, "text") . " AND " .
1198 " " . $ilDB->equals("type", $a_type, "text", true);
1199
1200 $ilDB->manipulate($q);
1201 }
1202
1203
1204 public function delete(): bool
1205 {
1206 $ilDB = $this->db;
1207
1208 // delete object
1209 parent::delete();
1210
1211 // check whether this style is global default
1212 $def_style = $this->ilias->getSetting("default_content_style_id");
1213 if ($def_style == $this->getId()) {
1214 $this->ilias->deleteSetting("default_content_style_id");
1215 }
1216
1217 // check whether this style is global fixed
1218 $fixed_style = $this->ilias->getSetting("fixed_content_style_id");
1219 if ($fixed_style == $this->getId()) {
1220 $this->ilias->deleteSetting("fixed_content_style_id");
1221 }
1222
1223 // delete style parameter
1224 $q = "DELETE FROM style_parameter WHERE style_id = " .
1225 $ilDB->quote($this->getId(), "integer");
1226 $ilDB->manipulate($q);
1227
1228 // delete style file
1229 $css_file_name = ilFileUtils::getWebspaceDir() . "/css/style_" . $this->getId() . ".css";
1230 if (is_file($css_file_name)) {
1231 unlink($css_file_name);
1232 }
1233
1234 // delete media queries
1235 $ilDB->manipulate(
1236 "DELETE FROM sty_media_query WHERE " .
1237 " style_id = " . $ilDB->quote($this->getId(), "integer")
1238 );
1239
1240 // delete entries in learning modules
1242
1243 // delete style data record
1244 $q = "DELETE FROM style_data WHERE id = " .
1245 $ilDB->quote($this->getId(), "integer");
1246 $ilDB->manipulate($q);
1247
1248 return true;
1249 }
1250
1251
1255 public function read(): void
1256 {
1257 $ilDB = $this->db;
1258
1259 parent::read();
1260
1261 $q = "SELECT * FROM style_parameter WHERE style_id = " .
1262 $ilDB->quote($this->getId(), "integer") . " ORDER BY tag, class, type, mq_id ";
1263 $style_set = $ilDB->query($q);
1264 $ctag = "";
1265 $cclass = "";
1266 $ctype = "";
1267 $cmq_id = 0;
1268 $this->style = array();
1269 // workaround for bug #17586, see also http://stackoverflow.com/questions/3066356/multiple-css-classes-properties-overlapping-based-on-the-order-defined
1270 // e.g. ha_iheada must be written after ha_ihead, since they are acting on the same dom node
1271 // styles that must be added at the end
1272 $this->end_styles = array();
1273 $tag = null;
1274 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
1275 if ($style_rec["tag"] != $ctag || $style_rec["class"] != $cclass
1276 || $style_rec["type"] != $ctype || $style_rec["mq_id"] != $cmq_id) {
1277 // add current tag array to style array
1278 if (is_array($tag)) {
1279 if (in_array($ctype, array("ha_iheada", "va_iheada"))) {
1280 $this->end_styles[] = $tag;
1281 } else {
1282 $this->style[] = $tag;
1283 }
1284 }
1285 $tag = array();
1286 }
1287 $ctag = $style_rec["tag"];
1288 $cclass = $style_rec["class"];
1289 $ctype = $style_rec["type"];
1290 $cmq_id = $style_rec["mq_id"];
1291 $tag[] = $style_rec;
1292 // added $cmq_id
1293 $this->style_class[$ctype][$cclass][$cmq_id][$style_rec["parameter"]] = $style_rec["value"];
1294 }
1295 if (is_array($tag)) {
1296 $this->style[] = $tag;
1297 }
1298 foreach ($this->end_styles as $s) {
1299 $this->style[] = $s;
1300 }
1301 //var_dump($this->style_class);
1302 $q = "SELECT * FROM style_data WHERE id = " .
1303 $ilDB->quote($this->getId(), "integer");
1304 $res = $ilDB->query($q);
1305 $sty = $ilDB->fetchAssoc($res);
1306 $this->setUpToDate((bool) $sty["uptodate"]);
1307 $this->setScope((int) $sty["category"]);
1308
1309 // get style characteristics records
1310 $this->chars = array();
1311 $this->chars_by_type = array();
1312 $q = "SELECT * FROM style_char WHERE style_id = " .
1313 $ilDB->quote($this->getId(), "integer") .
1314 " ORDER BY type ASC, characteristic ASC";
1315 $par_set = $ilDB->query($q);
1316 while ($par_rec = $ilDB->fetchAssoc($par_set)) {
1317 $this->chars[] = array("type" => $par_rec["type"], "class" => $par_rec["characteristic"], "hide" => $par_rec["hide"]);
1318 $this->chars_by_type[$par_rec["type"]][] = $par_rec["characteristic"];
1319 if ($par_rec["hide"]) {
1320 $this->hidden_chars[$par_rec["type"] . ":" . $par_rec["characteristic"]] = true;
1321 }
1322 }
1323 // var_dump($this->style); exit;
1324 }
1325
1329 public function writeCSSFile(
1330 string $a_target_file = "",
1331 string $a_image_dir = ""
1332 ): void {
1333 $style_manager = $this->domain->style($this->getId());
1334 if ($style_manager->writeCss()) {
1335 $this->setUpToDate();
1336 }
1337 }
1338
1345 public static function getEffectiveContentStyleId(
1346 int $a_style_id
1347 ): int {
1348 global $DIC;
1349
1350 $ilSetting = $DIC->settings();
1351
1352 // check global fixed content style
1353 $fixed_style = $ilSetting->get("fixed_content_style_id");
1354 if ($fixed_style > 0) {
1355 $a_style_id = (int) $fixed_style;
1356 }
1357
1358 // check global default style
1359 if ($a_style_id <= 0) {
1360 $a_style_id = (int) $ilSetting->get("default_content_style_id");
1361 }
1362
1363 if ($a_style_id > 0 && ilObject::_lookupType($a_style_id) === "sty") {
1364 return $a_style_id;
1365 }
1366
1367 return 0;
1368 }
1369
1370 public function getParametersOfClass(
1371 string $a_type,
1372 string $a_class,
1373 int $a_mq_id = 0
1374 ): array {
1375 if (is_array($this->style_class[$a_type][$a_class][$a_mq_id])) {
1376 return $this->style_class[$a_type][$a_class][$a_mq_id];
1377 }
1378 return array();
1379 }
1380
1381 public static function getExportContentStylePath(): string
1382 {
1383 return "assets/content_style/style.css";
1384 }
1385
1390 public static function getContentStylePath(
1391 int $a_style_id,
1392 bool $add_random = true,
1393 bool $add_token = true
1394 ): string {
1395 global $DIC;
1396 $ilSetting = $DIC->settings();
1397
1398 $random = new \Random\Randomizer();
1399 $rand = $random->getInt(1, 999999);
1400
1401 // check global fixed content style
1402 $fixed_style = $ilSetting->get("fixed_content_style_id");
1403 if ($fixed_style > 0) {
1404 $a_style_id = (int) $fixed_style;
1405 }
1406
1407 // check global default style
1408 if ($a_style_id <= 0) {
1409 $a_style_id = (int) $ilSetting->get("default_content_style_id");
1410 }
1411 if ($a_style_id > 0 && ilObject::_exists($a_style_id)) {
1412 // check whether file is up to date
1413 if (!ilObjStyleSheet::_lookupUpToDate($a_style_id)) {
1414 $style = new ilObjStyleSheet($a_style_id);
1415 $style->writeCSSFile();
1416 }
1417
1418 $style_manager = $DIC->contentStyle()->internal()->domain()->style($a_style_id);
1419 $path = $style_manager->getPath();
1420 return $path;
1421 } else { // todo: work this out
1422 return "./components/ILIAS/COPage/css/content.css";
1423 }
1424 }
1425
1426 public static function getContentPrintStyle(): string
1427 {
1428 return "./components/ILIAS/COPage/css/print_content.css";
1429 }
1430
1431 public static function getSyntaxStylePath(): string
1432 {
1433 return "./components/ILIAS/COPage/css/syntaxhighlight.css";
1434 }
1435
1436 public static function getBaseContentStylePath(): string
1437 {
1438 return "./components/ILIAS/COPage/css/content_base.css";
1439 }
1440
1441 public function update(): bool
1442 {
1443 $ilDB = $this->db;
1444
1445 parent::update();
1446 $this->read(); // this could be done better
1447 $this->writeCSSFile();
1448
1449 $q = "UPDATE style_data " .
1450 "SET category = " . $ilDB->quote($this->getScope(), "integer") .
1451 " WHERE id = " . $ilDB->quote($this->getId(), "integer");
1452 $ilDB->manipulate($q);
1453
1454 return true;
1455 }
1456
1460 public function updateStyleParameter(
1461 int $a_id,
1462 string $a_value
1463 ): void {
1464 $ilDB = $this->db;
1465
1466 $q = "UPDATE style_parameter SET VALUE = " .
1467 $ilDB->quote($a_value, "text") . " WHERE id = " .
1468 $ilDB->quote($a_id, "integer");
1469 $style_set = $ilDB->manipulate($q);
1470 }
1471
1472 public function getStyle(): array
1473 {
1474 return $this->style;
1475 }
1476
1477 public function setStyle(array $a_style): void
1478 {
1479 $this->style = $a_style;
1480 }
1481
1482 public function handleXmlString(string $a_str): string
1483 {
1484 return str_replace("&", "&amp;", $a_str);
1485 }
1486
1491 public function getXML(): string
1492 {
1493 $xml = "<StyleSheet>\n";
1494
1495 // title and description
1496 $xml .= "<Title>" . $this->handleXmlString($this->getTitle()) . "</Title>";
1497 $xml .= "<Description>" . $this->handleXmlString($this->getDescription()) . "</Description>\n";
1498
1499 // style classes
1500 foreach ($this->chars as $char) {
1501 $xml .= "<Style Tag=\"" . ilObjStyleSheet::_determineTag($char["type"]) .
1502 "\" Type=\"" . $char["type"] . "\" Class=\"" . $char["class"] . "\">\n";
1503 foreach ($this->style as $style) {
1504 if ($style[0]["type"] == $char["type"] && $style[0]["class"] == $char["class"]) {
1505 foreach ($style as $tag) {
1506 $xml .= "<StyleParameter Name=\"" . $tag["parameter"] . "\" Value=\"" . $tag["value"] . "\" Custom=\"" . $tag["custom"] . "\" />\n";
1507 }
1508 }
1509 }
1510 $xml .= "</Style>\n";
1511 }
1512
1513 // colors
1514 foreach ($this->getColors() as $color) {
1515 $xml .= "<StyleColor Name=\"" . $color["name"] . "\" Code=\"" . $color["code"] . "\"/>\n";
1516 }
1517
1518 // templates
1520 foreach ($tcts as $tct => $v) {
1521 $ts = $this->getTemplates($tct);
1522
1523 foreach ($ts as $t) {
1524 $xml .= "<StyleTemplate Type=\"" . $tct . "\" Name=\"" . $t["name"] . "\">\n";
1525 foreach ($t["classes"] as $ct => $c) {
1526 if ($c != "") {
1527 $xml .= "<StyleTemplateClass ClassType=\"" . $ct . "\" Class=\"" . $c . "\"/>\n";
1528 }
1529 }
1530 $xml .= "</StyleTemplate>\n";
1531 }
1532 }
1533
1534
1535 $xml .= "</StyleSheet>";
1536 //echo "<pre>".htmlentities($xml)."</pre>"; exit;
1537 return $xml;
1538 }
1539
1540 public function createExportDirectory(): string
1541 {
1542 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1543 ilFileUtils::makeDir($sty_data_dir);
1544 if (!is_writable($sty_data_dir)) {
1545 $this->ilias->raiseError("Style data directory (" . $sty_data_dir
1546 . ") not writeable.", $this->ilias->error_obj->FATAL);
1547 }
1548
1549 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1550 ilFileUtils::makeDir($style_dir);
1551 if (!is_dir($style_dir)) {
1552 $this->ilias->raiseError("Creation of style directory failed (" .
1553 $style_dir . ").", $this->ilias->error_obj->FATAL);
1554 }
1555
1556 // create export subdirectory
1557 $ex_dir = $style_dir . "/export";
1558 ilFileUtils::makeDir($ex_dir);
1559 if (!is_dir($ex_dir)) {
1560 $this->ilias->raiseError("Creation of Import Directory failed (" .
1561 $ex_dir . ").", $this->ilias->error_obj->FATAL);
1562 }
1563
1564 return $ex_dir;
1565 }
1566
1567 public function cleanExportDirectory(): void
1568 {
1569 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1570 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1571 // create export subdirectory
1572 $ex_dir = $style_dir . "/export";
1573
1574 if (is_dir($ex_dir)) {
1575 ilFileUtils::delDir($ex_dir, true);
1576 }
1577 }
1578
1579 public function createExportSubDirectory(): void
1580 {
1581 $ex_dir = $this->createExportDirectory();
1582 $ex_sub_dir = $ex_dir . "/" . $this->getExportSubDir();
1583 ilFileUtils::makeDir($ex_sub_dir);
1584 if (!is_writable($ex_sub_dir)) {
1585 $this->ilias->raiseError("Style data directory (" . $ex_sub_dir
1586 . ") not writeable.", $this->ilias->error_obj->FATAL);
1587 }
1588 $ex_sub_images_dir = $ex_sub_dir . "/images";
1589 ilFileUtils::makeDir($ex_sub_images_dir);
1590 if (!is_writable($ex_sub_images_dir)) {
1591 $this->ilias->raiseError("Style data directory (" . $ex_sub_images_dir
1592 . ") not writeable.", $this->ilias->error_obj->FATAL);
1593 }
1594 }
1595
1599 public function setExportSubDir(string $a_dir): void
1600 {
1601 $this->export_sub_dir = $a_dir;
1602 }
1603
1607 public function getExportSubDir(): string
1608 {
1609 if ($this->export_sub_dir == "") {
1610 return "sty_" . $this->getId();
1611 } else {
1612 return $this->export_sub_dir;
1613 }
1614 }
1615
1622 public function export(): string
1623 {
1624 $this->cleanExportDirectory();
1625 $ex_dir = $this->createExportDirectory();
1626 $this->createExportSubDirectory();
1627 $this->exportXML($ex_dir . "/" . $this->getExportSubDir());
1628 //echo "-".$this->getImagesDirectory()."-".$ex_dir."/".$this->getExportSubDir()."/images"."-";
1630 $this->getImagesDirectory(),
1631 $ex_dir . "/" . $this->getExportSubDir() . "/images"
1632 );
1633 if (is_file($ex_dir . "/" . $this->getExportSubDir() . ".zip")) {
1634 unlink($ex_dir . "/" . $this->getExportSubDir() . ".zip");
1635 }
1637 $ex_dir . "/" . $this->getExportSubDir(),
1638 $ex_dir . "/" . $this->getExportSubDir() . ".zip"
1639 );
1640
1641 return $ex_dir . "/" . $this->getExportSubDir() . ".zip";
1642 }
1643
1647 public function exportXML(string $a_dir): void
1648 {
1649 $file = $a_dir . "/style.xml";
1650
1651 // open file
1652 if (!($fp = fopen($file, 'wb'))) {
1653 die("<strong>Error</strong>: Could not open \"" . $file . "\" for writing" .
1654 " in <strong>" . __FILE__ . "</strong> on line <strong>" . __LINE__ . "</strong><br />");
1655 }
1656
1657 // set file permissions
1658 chmod($file, 0770);
1659
1660 // write xml data into the file
1661 fwrite($fp, $this->getXML());
1662
1663 // close file
1664 fclose($fp);
1665 }
1666
1667 public function createImportDirectory(): string
1668 {
1669 $sty_data_dir = ilFileUtils::getDataDir() . "/sty";
1670 ilFileUtils::makeDir($sty_data_dir);
1671 if (!is_writable($sty_data_dir)) {
1672 $this->ilias->raiseError("Style data directory (" . $sty_data_dir
1673 . ") not writeable.", $this->ilias->error_obj->FATAL);
1674 }
1675
1676 $style_dir = $sty_data_dir . "/sty_" . $this->getId();
1677 ilFileUtils::makeDir($style_dir);
1678 if (!is_dir($style_dir)) {
1679 $this->ilias->raiseError("Creation of style directory failed (" .
1680 $style_dir . ").", $this->ilias->error_obj->FATAL);
1681 }
1682
1683 // create import subdirectory
1684 $im_dir = $style_dir . "/import";
1685 ilFileUtils::makeDir($im_dir);
1686 if (!is_dir($im_dir)) {
1687 $this->ilias->raiseError("Creation of Import Directory failed (" .
1688 $im_dir . ").", $this->ilias->error_obj->FATAL);
1689 }
1690
1691 return $im_dir;
1692 }
1693
1701 public function import($a_file): void
1702 {
1703 parent::create();
1704 $subdir = "";
1705 $im_dir = $this->createImportDirectory();
1706
1707 // handle uploaded files
1708 if (is_array($a_file)) {
1710 $a_file["tmp_name"],
1711 $a_file["name"],
1712 $im_dir . "/" . $a_file["name"]
1713 );
1714 $file_name = $a_file["name"];
1715 } else { // handle not directly uploaded files
1716 $pi = pathinfo($a_file);
1717 $file_name = $pi["basename"];
1718 copy($a_file, $im_dir . "/" . $file_name);
1719 }
1720 $file = pathinfo($file_name);
1721
1722 // unzip file
1723 if (strtolower($file["extension"]) == "zip") {
1724 $this->domain->resources()->zip()->unzipFile($im_dir . "/" . $file_name);
1725 $subdir = basename($file["basename"], "." . $file["extension"]);
1726 if (!is_dir($im_dir . "/" . $subdir)) {
1727 $subdir = "style"; // check style subdir
1728 }
1729 $xml_file = $im_dir . "/" . $subdir . "/style.xml";
1730 } else { // handle xml file directly (old style)
1731 $xml_file = $im_dir . "/" . $file_name;
1732 }
1733
1734 // load information from xml file
1735 //echo "-$xml_file-";
1736 $this->createFromXMLFile($xml_file, true);
1737
1739 $this->read();
1740 $this->writeCSSFile();
1741 }
1742
1747 public function createFromXMLFile(
1748 string $a_file,
1749 bool $a_skip_parent_create = false
1750 ): void {
1751 $ilDB = $this->db;
1752
1753 $this->is_3_10_skin = false;
1754
1755 if (!$a_skip_parent_create) {
1756 parent::create();
1757 }
1758 $importParser = new ilStyleImportParser($a_file, $this);
1759 $importParser->startParsing();
1760
1761 // store style parameter
1762 foreach ($this->style as $style) {
1763 foreach ($style as $tag) {
1764 $id = $ilDB->nextId("style_parameter");
1765
1766 // migrate old table PageFrame/PageContainer to div
1767 if (in_array($tag["class"], array("PageFrame", "PageContainer")) &&
1768 $tag["tag"] == "table") {
1769 $tag["tag"] = "div";
1770 if ($tag["parameter"] == "width" && $tag["value"] == "100%") {
1771 continue;
1772 }
1773 }
1774
1775 if ($tag["type"] === "text_block" && $tag["tag"] === "div") {
1776 $tag["tag"] = "p";
1777 }
1778
1779 $q = "INSERT INTO style_parameter (id,style_id, tag, class, parameter, type, value, custom) VALUES " .
1780 "(" .
1781 $ilDB->quote($id, "integer") . "," .
1782 $ilDB->quote($this->getId(), "integer") . "," .
1783 $ilDB->quote($tag["tag"], "text") . "," .
1784 $ilDB->quote($tag["class"], "text") . "," .
1785 $ilDB->quote($tag["parameter"], "text") . "," .
1786 $ilDB->quote($tag["type"], "text") . "," .
1787 $ilDB->quote($tag["value"], "text") . "," .
1788 $ilDB->quote((bool) $tag["custom"], "integer") .
1789 ")";
1790 $ilDB->manipulate($q);
1791 }
1792 }
1793
1794 // store characteristics
1795 $this->is_3_10_skin = true;
1796 foreach ($this->chars as $char) {
1797 if ($char["type"] != "") {
1798 $s = substr($char["class"], strlen($char["class"]) - 6);
1799 if ($s != ":hover") {
1800 $ilDB->replace(
1801 "style_char",
1802 array(
1803 "style_id" => array("integer", $this->getId()),
1804 "type" => array("text", $char["type"]),
1805 "characteristic" => array("text", ilStr::subStr($char["class"], 0, 30))),
1806 array("hide" => array("integer", 0))
1807 );
1808 $this->is_3_10_skin = false;
1809 }
1810 }
1811 }
1812
1813 // add style_data record
1814 $q = "INSERT INTO style_data (id, uptodate) VALUES " .
1815 "(" . $ilDB->quote($this->getId(), "integer") . ", 0)";
1816 $ilDB->manipulate($q);
1817 $this->domain->style($this->getId())->createRid();
1818
1819 $this->update();
1820 $this->read();
1821
1822 if ($this->is_3_10_skin) {
1823 $this->do_3_10_Migration();
1824 }
1825 //$this->writeCSSFile();
1826 }
1827
1831 public function getStyleParameterGroups(): array
1832 {
1833 $groups = array();
1834
1835 foreach (self::$parameter as $parameter => $props) {
1836 $groups[$props["group"]][] = $parameter;
1837 }
1838 return $groups;
1839 }
1840
1841 public static function _getStyleParameterInputType(string $par): string
1842 {
1843 $input = self::$parameter[$par]["input"];
1844 return $input;
1845 }
1846
1847 public static function _getStyleParameterSubPar(string $par): string
1848 {
1849 $subpar = self::$parameter[$par]["subpar"];
1850 return $subpar;
1851 }
1852
1853 public static function _getStyleParameters(
1854 string $a_tag = ""
1855 ): array {
1856 if ($a_tag == "") {
1857 return self::$parameter;
1858 }
1859 $par = array();
1860 foreach (self::$parameter as $k => $v) {
1861 if (isset(self::$filtered_groups[$v["group"]]) &&
1862 !in_array($a_tag, self::$filtered_groups[$v["group"]])) {
1863 continue;
1864 }
1865 $par[$k] = $v;
1866 }
1867 return $par;
1868 }
1869
1870 public static function _getFilteredGroups(): array
1871 {
1872 return self::$filtered_groups;
1873 }
1874
1875 public static function _getStyleParameterNumericUnits(
1876 bool $a_no_percentage = false
1877 ): array {
1878 if ($a_no_percentage) {
1879 return self::$num_unit_no_perc;
1880 }
1881 return self::$num_unit;
1882 }
1883
1884 public static function _getStyleParameterValues(
1885 string $par
1886 ): array {
1887 return self::$parameter[$par]["values"];
1888 }
1889
1890 public static function _getStyleSuperTypes(): array
1891 {
1892 return self::$style_super_types;
1893 }
1894
1895 public static function _isExpandable(string $a_type): bool
1896 {
1897 return in_array($a_type, self::$expandable_types);
1898 }
1899
1900 public static function _isHideable(string $a_type): bool
1901 {
1902 return in_array($a_type, self::$hideable_types);
1903 }
1904
1905 public static function _getStyleSuperTypeForType(
1906 string $a_type
1907 ): string {
1908 foreach (self::$style_super_types as $s => $t) {
1909 if (in_array($a_type, $t)) {
1910 return $s;
1911 }
1912 if ($a_type == $s) {
1913 return $s;
1914 }
1915 }
1916 return "";
1917 }
1918
1919 public static function _getCoreStyles(): array
1920 {
1921 $c_styles = array();
1922 foreach (self::$core_styles as $cstyle) {
1923 $c_styles[$cstyle["type"] . "." . ilObjStyleSheet::_determineTag($cstyle["type"]) . "." . $cstyle["class"]]
1924 = array("type" => $cstyle["type"],
1925 "tag" => ilObjStyleSheet::_determineTag($cstyle["type"]),
1926 "class" => $cstyle["class"]);
1927 }
1928 return $c_styles;
1929 }
1930
1931 public static function isCoreStyle(
1932 string $a_type,
1933 string $a_class
1934 ): bool {
1935 foreach (self::$core_styles as $s) {
1936 if ($s["type"] == $a_type && $s["class"] == $a_class) {
1937 return true;
1938 }
1939 }
1940 return false;
1941 }
1942
1946 public static function _getTemplateClassTypes(
1947 string $a_template_type = ""
1948 ): array {
1949 if ($a_template_type == "") {
1950 return self::$templates;
1951 }
1952 return self::$templates[$a_template_type];
1953 }
1954
1955 public static function _getPseudoClasses(string $tag): array
1956 {
1957 return self::$pseudo_classes[$tag] ?? [];
1958 }
1959
1960 // e.g. table, row_head > table_cell
1962 string $t,
1963 string $k
1964 ): string {
1965 return self::$templates[$t][$k];
1966 }
1967
1968 public static function _determineTag(string $a_type): string
1969 {
1970 return self::$assigned_tags[$a_type];
1971 }
1972
1973 public static function getAvailableParameters(): array
1974 {
1975 $pars = array();
1976 foreach (self::$parameter as $p => $v) {
1977 $pars[$p] = $v["values"];
1978 }
1979
1980 return $pars;
1981 }
1982
1986 public static function _addMissingStyleClassesToStyle(
1987 int $a_id
1988 ): void {
1989 $styles = array(array("id" => $a_id));
1991 }
1992
1998 ?array $a_styles = null
1999 ): void {
2000 global $DIC;
2001
2002 $ilDB = $DIC->database();
2003
2004 if (is_null($a_styles)) {
2005 $styles = ilObject::_getObjectsDataForType("sty");
2006 } else {
2007 $styles = $a_styles;
2008 }
2009 $core_styles = ilObjStyleSheet::_getCoreStyles();
2011
2012 // get all core image files
2013 $core_images = array();
2014 $core_dir = self::$basic_style_image_dir;
2015 if (is_dir($core_dir)) {
2016 $dir = opendir($core_dir);
2017 while ($file = readdir($dir)) {
2018 if (substr($file, 0, 1) != "." && is_file($core_dir . "/" . $file)) {
2019 $core_images[] = $file;
2020 }
2021 }
2022 }
2023
2024 foreach ($styles as $style) {
2025 $id = $style["id"];
2026
2027 foreach ($core_styles as $cs) {
2028 // check, whether core style class exists
2029 $set = $ilDB->queryF(
2030 "SELECT * FROM style_char WHERE style_id = %s " .
2031 "AND type = %s AND characteristic = %s",
2032 array("integer", "text", "text"),
2033 array($id, $cs["type"], $cs["class"])
2034 );
2035
2036 // if not, add core style class
2037 if (!($rec = $ilDB->fetchAssoc($set))) {
2038 $ilDB->manipulateF(
2039 "INSERT INTO style_char (style_id, type, characteristic) " .
2040 " VALUES (%s,%s,%s) ",
2041 array("integer", "text", "text"),
2042 array($id, $cs["type"], $cs["class"])
2043 );
2044
2045 $xpath = new DOMXPath($bdom);
2046 $par_nodes = $xpath->query("/StyleSheet/Style[@Tag = '" . $cs["tag"] . "' and @Type='" .
2047 $cs["type"] . "' and @Class='" . $cs["class"] . "']/StyleParameter");
2048 foreach ($par_nodes as $par_node) {
2049 // check whether style parameter exists
2050 $set = $ilDB->queryF(
2051 "SELECT * FROM style_parameter WHERE style_id = %s " .
2052 "AND type = %s AND class = %s AND tag = %s AND parameter = %s",
2053 array("integer", "text", "text", "text", "text"),
2054 array($id, $cs["type"], $cs["class"],
2055 $cs["tag"], $par_node->getAttribute("Name"))
2056 );
2057
2058 // if not, create style parameter
2059 if (!($ilDB->fetchAssoc($set))) {
2060 $spid = $ilDB->nextId("style_parameter");
2061 $st = $ilDB->manipulateF(
2062 "INSERT INTO style_parameter (id, style_id, type, class, tag, parameter, value) " .
2063 " VALUES (%s,%s,%s,%s,%s,%s,%s)",
2064 array("integer", "integer", "text", "text", "text", "text", "text"),
2065 array($spid, $id, $cs["type"], $cs["class"], $cs["tag"],
2066 $par_node->getAttribute("Name"), $par_node->getAttribute("Value"))
2067 );
2068 }
2069 }
2070 }
2071 }
2072
2073 // now check, whether some core image files are missing
2076 foreach ($core_images as $cim) {
2077 if (!is_file($imdir . "/" . $cim)) {
2078 copy($core_dir . "/" . $cim, $imdir . "/" . $cim);
2079 }
2080 }
2081 }
2082 }
2083
2084 //
2085 // Color management
2086 //
2087
2091 public function do_3_10_Migration(): void
2092 {
2093 $ilDB = $this->db;
2094
2095 $this->do_3_9_Migration($this->getId());
2096
2097 $this->do_3_10_CharMigration($this->getId());
2098
2099 // style_char: type for characteristic
2100 $st = $ilDB->prepareManip("UPDATE style_char SET type = ? WHERE characteristic = ?" .
2101 " AND style_id = ? ", array("text", "text", "integer"));
2102 $ilDB->execute($st, array("media_cont", "Media", $this->getId()));
2103 $ilDB->execute($st, array("media_caption", "MediaCaption", $this->getId()));
2104 $ilDB->execute($st, array("page_fn", "Footnote", $this->getId()));
2105 $ilDB->execute($st, array("page_nav", "LMNavigation", $this->getId()));
2106 $ilDB->execute($st, array("page_title", "PageTitle", $this->getId()));
2107 $ilDB->execute($st, array("page_cont", "Page", $this->getId()));
2108
2109 // style_parameter: type for class
2110 $st = $ilDB->prepareManip("UPDATE style_parameter SET type = ? WHERE class = ?" .
2111 " AND style_id = ? ", array("text", "text", "integer"));
2112 $ilDB->execute($st, array("media_cont", "Media", $this->getId()));
2113 $ilDB->execute($st, array("media_caption", "MediaCaption", $this->getId()));
2114 $ilDB->execute($st, array("page_fn", "Footnote", $this->getId()));
2115 $ilDB->execute($st, array("page_nav", "LMNavigation", $this->getId()));
2116 $ilDB->execute($st, array("page_title", "PageTitle", $this->getId()));
2117 $ilDB->execute($st, array("table", "Page", $this->getId()));
2118
2119 $st = $ilDB->prepareManip("UPDATE style_parameter SET tag = ? WHERE class = ?" .
2120 " AND style_id = ? ", array("text", "text", "integer"));
2121 $ilDB->execute($st, array("div", "MediaCaption", $this->getId()));
2122
2123 // style_char: characteristic for characteristic
2124 $st = $ilDB->prepareManip("UPDATE style_char SET characteristic = ? WHERE characteristic = ?" .
2125 " AND style_id = ? ", array("text", "text", "integer"));
2126 $ilDB->execute($st, array("MediaContainer", "Media", $this->getId()));
2127 $ilDB->execute($st, array("PageContainer", "Page", $this->getId()));
2128
2129 // style_parameter: class for class
2130 $st = $ilDB->prepareManip("UPDATE style_parameter SET class = ? WHERE class = ?" .
2131 " AND style_id = ? ", array("text", "text", "integer"));
2132 $ilDB->execute($st, array("MediaContainer", "Media", $this->getId()));
2133 $ilDB->execute($st, array("PageContainer", "Page", $this->getId()));
2134
2135 // force rewriting of container style
2136 $st = $ilDB->prepareManip("DELETE FROM style_char WHERE type = ?" .
2137 " AND style_id = ? ", array("text", "integer"));
2138 $ilDB->execute($st, array("page_cont", $this->getId()));
2139 $st = $ilDB->prepareManip("DELETE FROM style_parameter WHERE type = ?" .
2140 " AND style_id = ? ", array("text", "integer"));
2141 $ilDB->execute($st, array("page_cont", $this->getId()));
2142 }
2143
2149 public function do_3_10_CharMigration(int $a_id = 0): void
2150 {
2151 $ilDB = $this->db;
2152
2153 $add_str = "";
2154 if ($a_id > 0) {
2155 $add_str = " AND style_id = " . $ilDB->quote($a_id, "integer");
2156 }
2157
2158 $set = $ilDB->query($q = "SELECT DISTINCT style_id, tag, class FROM style_parameter WHERE " .
2159 $ilDB->equals("type", "", "text", true) . " " . $add_str);
2160
2161 while ($rec = $ilDB->fetchAssoc($set)) {
2162 // derive types from tag
2163 $types = array();
2164 switch ($rec["tag"]) {
2165 case "div":
2166 case "p":
2167 if (in_array($rec["class"], array("Headline3", "Headline1",
2168 "Headline2", "TableContent", "List", "Standard", "Remark",
2169 "Additional", "Mnemonic", "Citation", "Example"))) {
2170 $types[] = "text_block";
2171 }
2172 if (in_array($rec["class"], array("Block", "Remark",
2173 "Additional", "Mnemonic", "Example", "Excursus", "Special"))) {
2174 $types[] = "section";
2175 }
2176 if (in_array($rec["class"], array("Page", "Footnote", "PageTitle", "LMNavigation"))) {
2177 $types[] = "page";
2178 }
2179 break;
2180
2181 case "td":
2182 $types[] = "table_cell";
2183 break;
2184
2185 case "a":
2186 if (in_array($rec["class"], array("ExtLink", "IntLink", "FootnoteLink"))) {
2187 $types[] = "link";
2188 }
2189 break;
2190
2191 case "span":
2192 $types[] = "text_inline";
2193 break;
2194
2195 case "table":
2196 $types[] = "table";
2197 break;
2198 }
2199
2200 // check if style_char set exists
2201 foreach ($types as $t) {
2202 // check if second type already exists
2203 $set4 = $ilDB->queryF(
2204 "SELECT * FROM style_char " .
2205 " WHERE style_id = %s AND type = %s AND characteristic = %s",
2206 array("integer", "text", "text"),
2207 array($rec["style_id"], $t, $rec["class"])
2208 );
2209 if ($rec4 = $ilDB->fetchAssoc($set4)) {
2210 // ok
2211 } else {
2212 //echo "<br>1-".$rec["style_id"]."-".$t."-".$rec["class"]."-";
2213 $ilDB->manipulateF(
2214 "INSERT INTO style_char " .
2215 " (style_id, type, characteristic) VALUES " .
2216 " (%s,%s,%s) ",
2217 array("integer", "text", "text"),
2218 array($rec["style_id"], $t, $rec["class"])
2219 );
2220 }
2221 }
2222
2223 // update types
2224 if ($rec["type"] == "") {
2225 if (count($types) > 0) {
2226 $ilDB->manipulateF(
2227 "UPDATE style_parameter SET type = %s " .
2228 " WHERE style_id = %s AND class = %s AND " . $ilDB->equals("type", "", "text", true),
2229 array("text", "integer", "text"),
2230 array($types[0], $rec["style_id"], $rec["class"])
2231 );
2232 //echo "<br>3-".$types[0]."-".$rec["style_id"]."-".$rec["class"]."-";
2233
2234 // links extra handling
2235 if ($types[0] == "link") {
2236 $ilDB->manipulateF(
2237 "UPDATE style_parameter SET type = %s " .
2238 " WHERE style_id = %s AND (class = %s OR class = %s) AND " . $ilDB->equals("type", "", "text", true),
2239 array("text", "integer", "text", "text"),
2240 array($types[0], $rec["style_id"], $rec["class"] . ":visited",
2241 $rec["class"] . ":hover")
2242 );
2243 }
2244 }
2245
2246 if (count($types) == 2) {
2247 // select all records of first type and add second type
2248 // records if necessary.
2249 $set2 = $ilDB->queryF(
2250 "SELECT * FROM style_parameter " .
2251 " WHERE style_id = %s AND class = %s AND type = %s",
2252 array("integer", "text", "text"),
2253 array($rec["style_id"], $rec["class"], $types[0])
2254 );
2255 while ($rec2 = $ilDB->fetchAssoc($set2)) {
2256 // check if second type already exists
2257 $set3 = $ilDB->queryF(
2258 "SELECT * FROM style_parameter " .
2259 " WHERE style_id = %s AND tag = %s AND class = %s AND type = %s AND parameter = %s",
2260 array("integer", "text", "text", "text", "text"),
2261 array($rec["style_id"], $rec["tag"], $rec["class"], $types[1], $rec["parameter"])
2262 );
2263 if ($rec3 = $ilDB->fetchAssoc($set3)) {
2264 // ok
2265 } else {
2266 $nid = $ilDB->nextId("style_parameter");
2267 $ilDB->manipulateF(
2268 "INSERT INTO style_parameter " .
2269 " (id, style_id, tag, class, parameter, value, type) VALUES " .
2270 " (%s, %s,%s,%s,%s,%s,%s) ",
2271 array("integer", "integer", "text", "text", "text", "text", "text"),
2272 array($nid, $rec2["style_id"], $rec2["tag"], $rec2["class"],
2273 $rec2["parameter"], $rec2["value"], $types[1])
2274 );
2275 }
2276 }
2277 }
2278 }
2279 }
2280 }
2281
2285 public function do_3_9_Migration(int $a_id): void
2286 {
2287 $ilDB = $this->db;
2288
2289 $classes = array("Example", "Additional", "Citation", "Mnemonic", "Remark");
2290 $pars = array("margin-top", "margin-bottom");
2291
2292 foreach ($classes as $curr_class) {
2293 foreach ($pars as $curr_par) {
2294 $res2 = $ilDB->queryF(
2295 "SELECT id FROM style_parameter WHERE style_id = %s" .
2296 " AND tag = %s AND class= %s AND parameter = %s",
2297 array("integer", "text", "text", "text"),
2298 array($a_id, "p", $curr_class, $curr_par)
2299 );
2300 if ($row2 = $ilDB->fetchAssoc($res2)) {
2301 $ilDB->manipulateF(
2302 "UPDATE style_parameter SET value= %s WHERE id = %s",
2303 array("text", "integer"),
2304 array("10px", $row2["id"])
2305 );
2306 } else {
2307 $nid = $ilDB->nextId("style_parameter");
2308 $ilDB->manipulateF(
2309 "INSERT INTO style_parameter " .
2310 "(id, style_id, tag, class, parameter,value) VALUES (%s,%s,%s,%s,%s,%s)",
2311 array("integer", "integer", "text", "text", "text", "text"),
2312 array($nid, $a_id, "div", $curr_class, $curr_par, "10px")
2313 );
2314 }
2315 }
2316 }
2317
2318 $ilDB->manipulateF(
2319 "UPDATE style_parameter SET tag = %s WHERE tag = %s and style_id = %s",
2320 array("text", "text", "integer"),
2321 array("div", "p", $a_id)
2322 );
2323 }
2324
2328
2332 public function getColors(): array
2333 {
2334 $ilDB = $this->db;
2335
2336 $set = $ilDB->query("SELECT * FROM style_color WHERE " .
2337 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
2338 "ORDER BY color_name");
2339
2340 $colors = array();
2341 while ($rec = $ilDB->fetchAssoc($set)) {
2342 $colors[] = array(
2343 "name" => $rec["color_name"],
2344 "code" => $rec["color_code"]
2345 );
2346 }
2347
2348 return $colors;
2349 }
2350
2354 public function removeColor(string $a_name): void
2355 {
2356 $ilDB = $this->db;
2357
2358 $ilDB->manipulate("DELETE FROM style_color WHERE " .
2359 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2360 " color_name = " . $ilDB->quote($a_name, "text"));
2361 }
2362
2363 public function getColorCodeForName(string $a_name): string
2364 {
2365 $ilDB = $this->db;
2366 $a_i = "";
2367 $pos = strpos($a_name, "(");
2368 if ($pos > 0) {
2369 $a_i = substr($a_name, $pos + 1);
2370 $a_i = str_replace(")", "", $a_i);
2371 $a_name = substr($a_name, 0, $pos);
2372 }
2373
2374 $set = $ilDB->query("SELECT color_code FROM style_color WHERE " .
2375 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2376 " color_name = " . $ilDB->quote($a_name, "text"));
2377 if ($rec = $ilDB->fetchAssoc($set)) {
2378 if ($a_i == "") {
2379 return "#" . $rec["color_code"];
2380 } else {
2382 $rec["color_code"],
2383 (int) $a_i
2384 );
2385 }
2386 }
2387 return "";
2388 }
2389
2393 public static function _getColorFlavor(
2394 string $a_rgb,
2395 int $a_i
2396 ): string {
2397 $rgb = ilObjStyleSheet::_explodeRGB($a_rgb, true);
2398 $hls = ilObjStyleSheet::_RGBToHLS($rgb);
2399
2400 if ($a_i > 0) {
2401 $hls["l"] = $hls["l"] + ((255 - $hls["l"]) * ($a_i / 100));
2402 }
2403 if ($a_i < 0) {
2404 $hls["l"] = $hls["l"] - (($hls["l"]) * (-$a_i / 100));
2405 }
2406
2407 $rgb = ilObjStyleSheet::_HLSToRGB($hls);
2408
2409 foreach ($rgb as $k => $v) {
2410 $rgb[$k] = str_pad(dechex((int) $v), 2, "0", STR_PAD_LEFT);
2411 }
2412
2413 return $rgb["r"] . $rgb["g"] . $rgb["b"];
2414 }
2415
2419 public static function _explodeRGB(
2420 string $a_rgb,
2421 bool $as_dec = false
2422 ): array {
2423 $r["r"] = substr($a_rgb, 0, 2);
2424 $r["g"] = substr($a_rgb, 2, 2);
2425 $r["b"] = substr($a_rgb, 4, 2);
2426 if ($as_dec) {
2427 $r["r"] = self::hexdec($r["r"]);
2428 $r["g"] = self::hexdec($r["g"]);
2429 $r["b"] = self::hexdec($r["b"]);
2430 }
2431
2432 return $r;
2433 }
2434
2435 protected static function hexdec(string $hex): int
2436 {
2437 $hex = preg_replace("/[^a-fA-F0-9]+/", "", $hex);
2438 if ($hex === "") {
2439 $hex = "0";
2440 }
2441 return (int) hexdec($hex);
2442 }
2443
2447 public static function _RGBToHLS(array $a_rgb): array
2448 {
2449 $r = $a_rgb["r"] / 255;
2450 $g = $a_rgb["g"] / 255;
2451 $b = $a_rgb["b"] / 255;
2452 $h = 0;
2453
2454 // max / min
2455 $max = max($r, $g, $b);
2456 $min = min($r, $g, $b);
2457
2458 //lightness
2459 $l = ($max + $min) / 2;
2460
2461 if ($max == $min) {
2462 $s = 0;
2463 } else {
2464 if ($l < 0.5) {
2465 $s = ($max - $min) / ($max + $min);
2466 } else {
2467 $s = ($max - $min) / (2.0 - $max - $min);
2468 }
2469
2470 if ($r == $max) {
2471 $h = ($g - $b) / ($max - $min);
2472 } elseif ($g == $max) {
2473 $h = 2.0 + ($b - $r) / ($max - $min);
2474 } elseif ($b == $max) {
2475 $h = 4.0 + ($r - $g) / ($max - $min);
2476 }
2477 }
2478
2479 $hls["h"] = round(($h / 6) * 255);
2480 $hls["l"] = round($l * 255);
2481 $hls["s"] = round($s * 255);
2482
2483 return $hls;
2484 }
2485
2489 public static function _HLSToRGB(array $a_hls): array
2490 {
2491 $h = $a_hls["h"] / 255;
2492 $l = $a_hls["l"] / 255;
2493 $s = $a_hls["s"] / 255;
2494 $temp3 = 0;
2495
2496 $rgb["r"] = $rgb["g"] = $rgb["b"] = 0;
2497
2498 // If S=0, define R, G, and B all to L
2499 if ($s == 0) {
2500 $rgb["r"] = $rgb["g"] = $rgb["b"] = $l;
2501 } else {
2502 if ($l < 0.5) {
2503 $temp2 = $l * (1.0 + $s);
2504 } else {
2505 $temp2 = $l + $s - $l * $s;
2506 }
2507
2508 $temp1 = 2.0 * $l - $temp2;
2509
2510
2511 # For each of R, G, B, compute another temporary value, temp3, as follows:
2512 foreach ($rgb as $k => $v) {
2513 switch ($k) {
2514 case "r":
2515 $temp3 = $h + 1.0 / 3.0;
2516 break;
2517
2518 case "g":
2519 $temp3 = $h;
2520 break;
2521
2522 case "b":
2523 $temp3 = $h - 1.0 / 3.0;
2524 break;
2525 }
2526 if ($temp3 < 0) {
2527 $temp3 = $temp3 + 1.0;
2528 }
2529 if ($temp3 > 1) {
2530 $temp3 = $temp3 - 1.0;
2531 }
2532
2533 if (6.0 * $temp3 < 1) {
2534 $rgb[$k] = $temp1 + ($temp2 - $temp1) * 6.0 * $temp3;
2535 } elseif (2.0 * $temp3 < 1) {
2536 $rgb[$k] = $temp2;
2537 } elseif (3.0 * $temp3 < 2) {
2538 $rgb[$k] = $temp1 + ($temp2 - $temp1) * ((2.0 / 3.0) - $temp3) * 6.0;
2539 } else {
2540 $rgb[$k] = $temp1;
2541 }
2542 }
2543 }
2544
2545 $rgb["r"] = round($rgb["r"] * 255);
2546 $rgb["g"] = round($rgb["g"] * 255);
2547 $rgb["b"] = round($rgb["b"] * 255);
2548
2549 return $rgb;
2550 }
2551
2552 //
2553 // Media queries
2554 //
2555
2559
2560 public function getMediaQueries(): array
2561 {
2562 $ilDB = $this->db;
2563
2564 $set = $ilDB->query("SELECT * FROM sty_media_query WHERE " .
2565 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
2566 "ORDER BY order_nr");
2567
2568 $mq = array();
2569 while ($rec = $ilDB->fetchAssoc($set)) {
2570 $mq[] = $rec;
2571 }
2572
2573 return $mq;
2574 }
2575
2576 public function addMediaQuery(
2577 string $a_mquery,
2578 int $order_nr = 0
2579 ): int {
2580 $ilDB = $this->db;
2581
2582 $id = $ilDB->nextId("sty_media_query");
2583 if ($order_nr == 0) {
2584 $order_nr = $this->getMaxMQueryOrderNr() + 10;
2585 }
2586
2587 $ilDB->manipulate("INSERT INTO sty_media_query (id, style_id, mquery, order_nr)" .
2588 " VALUES (" .
2589 $ilDB->quote($id, "integer") . "," .
2590 $ilDB->quote($this->getId(), "integer") . "," .
2591 $ilDB->quote($a_mquery, "text") . "," .
2592 $ilDB->quote($order_nr, "integer") .
2593 ")");
2594
2595 return $id;
2596 }
2597
2601 public function getMaxMQueryOrderNr(): int
2602 {
2603 $ilDB = $this->db;
2604
2605 $set = $ilDB->query(
2606 "SELECT max(order_nr) mnr FROM sty_media_query " .
2607 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer")
2608 );
2609 $rec = $ilDB->fetchAssoc($set);
2610
2611 return (int) $rec["mnr"];
2612 }
2613
2614 public function updateMediaQuery(
2615 int $a_id,
2616 string $a_mquery
2617 ): void {
2618 $ilDB = $this->db;
2619
2620 $ilDB->manipulate(
2621 "UPDATE sty_media_query SET " .
2622 " mquery = " . $ilDB->quote($a_mquery, "text") .
2623 " WHERE id = " . $ilDB->quote($a_id, "integer")
2624 );
2625 }
2626
2633 public function getMediaQueryForId(
2634 int $a_id
2635 ): array {
2636 $ilDB = $this->db;
2637
2638 $set = $ilDB->query(
2639 "SELECT * FROM sty_media_query " .
2640 " WHERE id = " . $ilDB->quote($a_id, "integer")
2641 );
2642 return $ilDB->fetchAssoc($set);
2643 }
2644
2650 public function deleteMediaQuery(
2651 int $a_id
2652 ): void {
2653 $ilDB = $this->db;
2654
2655 $ilDB->manipulate(
2656 "DELETE FROM sty_media_query WHERE " .
2657 " style_id = " . $ilDB->quote($this->getId(), "integer") .
2658 " AND id = " . $ilDB->quote($a_id, "integer")
2659 );
2660 $this->saveMediaQueryOrder();
2661 }
2662
2666 public function saveMediaQueryOrder(
2667 ?array $a_order_nr = null
2668 ): void {
2669 $ilDB = $this->db;
2670
2671 $mqueries = $this->getMediaQueries();
2672 if (is_array($a_order_nr)) {
2673 foreach ($mqueries as $k => $mq) {
2674 $mqueries[$k]["order_nr"] = $a_order_nr[$mq["id"]];
2675 }
2676 $mqueries = ilArrayUtil::sortArray($mqueries, "order_nr", "", true);
2677 }
2678 $cnt = 10;
2679 foreach ($mqueries as $mq) {
2680 $ilDB->manipulate(
2681 "UPDATE sty_media_query SET " .
2682 " order_nr = " . $ilDB->quote($cnt, "integer") .
2683 " WHERE id = " . $ilDB->quote($mq["id"], "integer")
2684 );
2685 $cnt += 10;
2686 }
2687 }
2688
2689
2690 //
2691 // Table template management
2692 //
2693
2697 public function getTemplates(
2698 string $a_type
2699 ): array {
2700 $ilDB = $this->db;
2701
2702 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
2703 "style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2704 "temp_type = " . $ilDB->quote($a_type, "text") . " " .
2705 "ORDER BY name");
2706
2707 $templates = array();
2708 while ($rec = $ilDB->fetchAssoc($set)) {
2709 $rec["classes"] = $this->getTemplateClasses((int) $rec["id"]);
2710 $templates[] = $rec;
2711 }
2712
2713 return $templates;
2714 }
2715
2719 public function getTemplateClasses(
2720 int $a_tid
2721 ): array {
2722 $ilDB = $this->db;
2723 $set = $ilDB->query("SELECT * FROM style_template_class WHERE " .
2724 "template_id = " . $ilDB->quote($a_tid, "integer"));
2725
2726 $class = array();
2727 while ($rec = $ilDB->fetchAssoc($set)) {
2728 $key = $rec["class_type"];
2729 $class[$key] = $rec["class"];
2730 }
2731
2732 return $class;
2733 }
2734
2735
2739 public function addTemplate(
2740 string $a_type,
2741 string $a_name,
2742 array $a_classes
2743 ): int {
2744 $ilDB = $this->db;
2745
2746 $tid = $ilDB->nextId("style_template");
2747 $ilDB->manipulate("INSERT INTO style_template " .
2748 "(id, style_id, name, temp_type)" .
2749 " VALUES (" .
2750 $ilDB->quote($tid, "integer") . "," .
2751 $ilDB->quote($this->getId(), "integer") . "," .
2752 $ilDB->quote($a_name, "text") . "," .
2753 $ilDB->quote($a_type, "text") .
2754 ")");
2755
2756 foreach ($a_classes as $t => $c) {
2757 $ilDB->manipulate("INSERT INTO style_template_class " .
2758 "(template_id, class_type, class)" .
2759 " VALUES (" .
2760 $ilDB->quote($tid, "integer") . "," .
2761 $ilDB->quote($t, "text") . "," .
2762 $ilDB->quote($c, "text") .
2763 ")");
2764 }
2765
2766 $this->writeTemplatePreview(
2767 $tid,
2768 ilObjStyleSheetGUI::_getTemplatePreview($this, $a_type, $tid, true)
2769 );
2770
2771 return $tid;
2772 }
2773
2777 public function updateTemplate(
2778 int $a_t_id,
2779 string $a_name,
2780 array $a_classes
2781 ): void {
2782 $ilDB = $this->db;
2783
2784 $ilDB->manipulate("UPDATE style_template SET " .
2785 "name = " . $ilDB->quote($a_name, "text") .
2786 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
2787
2788 $ilDB->manipulate(
2789 "DELETE FROM style_template_class WHERE " .
2790 "template_id = " . $ilDB->quote($a_t_id, "integer")
2791 );
2792 foreach ($a_classes as $t => $c) {
2793 $ilDB->manipulate("INSERT INTO style_template_class " .
2794 "(template_id, class_type, class)" .
2795 " VALUES (" .
2796 $ilDB->quote($a_t_id, "integer") . "," .
2797 $ilDB->quote($t, "text") . "," .
2798 $ilDB->quote($c, "text") .
2799 ")");
2800 }
2801 }
2802
2803 public function addTemplateClass(
2804 int $a_t_id,
2805 string $a_type,
2806 string $a_class
2807 ): void {
2808 $ilDB = $this->db;
2809
2810 $ilDB->manipulate("INSERT INTO style_template_class " .
2811 "(template_id, class_type, class)" .
2812 " VALUES (" .
2813 $ilDB->quote($a_t_id, "integer") . "," .
2814 $ilDB->quote($a_type, "text") . "," .
2815 $ilDB->quote($a_class, "text") .
2816 ")");
2817 }
2818
2822 public function templateExists(
2823 string $a_template_name
2824 ): bool {
2825 $ilDB = $this->db;
2826
2827 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
2828 "style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2829 "name = " . $ilDB->quote($a_template_name, "text"));
2830 if ($ilDB->fetchAssoc($set)) {
2831 return true;
2832 }
2833 return false;
2834 }
2835
2839 public function getTemplate(int $a_t_id): array
2840 {
2841 $ilDB = $this->db;
2842
2843 $set = $ilDB->query("SELECT * FROM style_template WHERE " .
2844 "style_id = " . $ilDB->quote($this->getId(), "integer") . " " .
2845 " AND id = " . $ilDB->quote($a_t_id, "integer"));
2846
2847 if ($rec = $ilDB->fetchAssoc($set)) {
2848 $rec["classes"] = $this->getTemplateClasses((int) $rec["id"]);
2849
2850 $template = $rec;
2851 return $template;
2852 }
2853 return array();
2854 }
2855
2859 public function lookupTemplateName(int $a_t_id): string
2860 {
2861 return self::_lookupTemplateName($a_t_id);
2862 }
2863
2867 public static function _lookupTemplateName(int $a_t_id): ?string
2868 {
2869 global $DIC;
2870
2871 $ilDB = $DIC->database();
2872
2873 $set = $ilDB->query("SELECT name FROM style_template WHERE " .
2874 " id = " . $ilDB->quote($a_t_id, "integer"));
2875
2876 if ($rec = $ilDB->fetchAssoc($set)) {
2877 return $rec["name"];
2878 }
2879
2880 return null;
2881 }
2882
2886 public function getTemplateXML(): string
2887 {
2888 $ilDB = $this->db;
2889
2890 $tag = "<StyleTemplates>";
2891
2892 $ttypes = array("table", "vaccordion", "haccordion", "carousel");
2893
2894 foreach ($ttypes as $ttype) {
2895 $ts = $this->getTemplates($ttype);
2896
2897 foreach ($ts as $t) {
2899 /*$atts = array("table" => "TableClass",
2900 "caption" => "CaptionClass",
2901 "row_head" => "RowHeadClass",
2902 "row_foot" => "RowFootClass",
2903 "col_head" => "ColHeadClass",
2904 "col_foot" => "ColFootClass",
2905 "odd_row" => "OddRowClass",
2906 "even_row" => "EvenRowClass",
2907 "odd_col" => "OddColClass",
2908 "even_col" => "EvenColClass");*/
2909 $c = $t["classes"];
2910
2911 $tag .= '<StyleTemplate Name="' . $t["name"] . '">';
2912
2913 foreach ($atts as $type => $t2) {
2914 if (($c[$type] ?? "") != "") {
2915 $tag .= '<StyleClass Type="' . $type . '" Value="' . $c[$type] . '" />';
2916 }
2917 }
2918
2919 $tag .= "</StyleTemplate>";
2920 }
2921 }
2922
2923 $tag .= "</StyleTemplates>";
2924
2925 //echo htmlentities($tag);
2926 return $tag;
2927 }
2928
2932 public function writeTemplatePreview(
2933 int $a_t_id,
2934 string $a_preview_html
2935 ): void {
2936 $ilDB = $this->db;
2937 $a_preview_html = str_replace(' width=""', "", $a_preview_html);
2938 $a_preview_html = str_replace(' valign="top"', "", $a_preview_html);
2939 $a_preview_html = str_replace('<div class="ilc_text_block_TableContent">', "<div>", $a_preview_html);
2940 //echo "1-".strlen($a_preview_html)."-";
2941 //echo htmlentities($a_preview_html);
2942 if (strlen($a_preview_html) > 4000) {
2943 //echo "2";
2944 $a_preview_html = "";
2945 }
2946 $ilDB->manipulate("UPDATE style_template SET " .
2947 "preview = " . $ilDB->quote($a_preview_html, "text") .
2948 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
2949 }
2950
2954 public function lookupTemplatePreview(int $a_t_id): string
2955 {
2956 $ilDB = $this->db;
2957
2958 $set = $ilDB->query("SELECT preview FROM style_template " .
2959 " WHERE id = " . $ilDB->quote($a_t_id, "integer"));
2960 if ($rec = $ilDB->fetchAssoc($set)) {
2961 return $rec["preview"] ?? "";
2962 }
2963
2964 return "";
2965 }
2966
2970 public static function _lookupTemplateIdByName(
2971 int $a_style_id,
2972 string $a_name
2973 ): ?int {
2974 global $DIC;
2975
2976 $ilDB = $DIC->database();
2977
2978 $set = $ilDB->query("SELECT id FROM style_template " .
2979 " WHERE style_id = " . $ilDB->quote($a_style_id, "integer") .
2980 " AND name = " . $ilDB->quote($a_name, "text"));
2981 if ($rec = $ilDB->fetchAssoc($set)) {
2982 return (int) $rec["id"];
2983 }
2984
2985 return null;
2986 }
2987
2991 public function removeTemplate(int $a_t_id): void
2992 {
2993 $ilDB = $this->db;
2994
2995 $ilDB->manipulate("DELETE FROM style_template WHERE " .
2996 " style_id = " . $ilDB->quote($this->getId(), "integer") . " AND " .
2997 " id = " . $ilDB->quote($a_t_id, "integer"));
2998
2999 $ilDB->manipulate(
3000 "DELETE FROM style_template_class WHERE " .
3001 "template_id = " . $ilDB->quote($a_t_id, "integer")
3002 );
3003 }
3004
3005 public function writeStyleSetting(
3006 string $a_name,
3007 string $a_value
3008 ): void {
3009 $ilDB = $this->db;
3010
3011 $ilDB->manipulate(
3012 "DELETE FROM style_setting WHERE " .
3013 " style_id = " . $ilDB->quote($this->getId(), "integer") .
3014 " AND name = " . $ilDB->quote($a_name, "text")
3015 );
3016
3017 $ilDB->manipulate("INSERT INTO style_setting " .
3018 "(style_id, name, value) VALUES (" .
3019 $ilDB->quote($this->getId(), "integer") . "," .
3020 $ilDB->quote($a_name, "text") . "," .
3021 $ilDB->quote($a_value, "text") .
3022 ")");
3023 }
3024
3028 public function lookupStyleSetting(string $a_name): string
3029 {
3030 $ilDB = $this->db;
3031
3032 $set = $ilDB->query(
3033 "SELECT value FROM style_setting " .
3034 " WHERE style_id = " . $ilDB->quote($this->getId(), "integer") .
3035 " AND name = " . $ilDB->quote($a_name, "text")
3036 );
3037 $rec = $ilDB->fetchAssoc($set);
3038
3039 return $rec["value"] ?? '';
3040 }
3041
3045 public static function writeStyleUsage(
3046 int $a_obj_id,
3047 int $a_style_id
3048 ): void {
3049 global $DIC;
3050
3051 $ilDB = $DIC->database();
3052
3053 $ilDB->replace(
3054 "style_usage",
3055 array(
3056 "obj_id" => array("integer", $a_obj_id)),
3057 array(
3058 "style_id" => array("integer", $a_style_id))
3059 );
3060 }
3061
3065 public static function lookupObjectStyle(
3066 int $a_obj_id
3067 ): int {
3068 global $DIC;
3069
3070 $ilDB = $DIC->database();
3071
3072 $set = $ilDB->query(
3073 "SELECT style_id FROM style_usage " .
3074 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer")
3075 );
3076 $rec = $ilDB->fetchAssoc($set);
3077 if (!is_array($rec)) {
3078 return 0;
3079 }
3080
3081 if (ilObject::_lookupType((int) $rec["style_id"]) == "sty") {
3082 return (int) $rec["style_id"];
3083 }
3084
3085 return 0;
3086 }
3087
3092 public static function lookupObjectForStyle(
3093 int $a_style_id
3094 ): array {
3095 global $DIC;
3096
3097 $ilDB = $DIC->database();
3098
3099 $obj_ids = array();
3100 if (ilObject::_lookupType($a_style_id) == "sty") {
3101 $set = $ilDB->query(
3102 "SELECT DISTINCT obj_id FROM style_usage " .
3103 " WHERE style_id = " . $ilDB->quote($a_style_id, "integer")
3104 );
3105
3106 while ($rec = $ilDB->fetchAssoc($set)) {
3107 $obj_ids[] = (int) $rec["obj_id"];
3108 }
3109 }
3110 return $obj_ids;
3111 }
3112}
$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 getWebspaceDir(string $mode="filesystem")
get webspace directory
static zip(string $a_dir, string $a_file, bool $compress_content=false)
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.
Class ilObjStyleSheet.
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)
InternalDomainService $domain
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.
hasCharacteristic(string $type, string $char)
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)
Class ilObject Basic functions for all objects.
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:21
$c
Definition: deliver.php:25
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ref_id
Definition: ltiauth.php:66
$service
Definition: ltiresult.php:36
$path
Definition: ltiservices.php:30
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
global $lng
Definition: privfeed.php:31
global $ilSetting
Definition: privfeed.php:31
$ilErr
Definition: raiseError.php:33
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:25