ILIAS  release_8 Revision v8.24
class.ilSkinStyleContainer.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27{
28 protected ilLanguage $lng;
29
33 protected ilSkin $skin;
34
39
44
46
47 public function __construct(
53 ) {
54 $this->lng = $lng;
55 $this->skin = $skin;
56 $this->setMessageStack($message_stack);
57
60 } else {
61 $this->setSystemStylesConf($system_styles_conf);
62 }
63
64 if (!$file_system) {
65 $this->file_system = new ilFileSystemHelper($this->lng, $message_stack);
66 } else {
67 $this->file_system = $file_system;
68 }
69 }
70
76 {
77 if (file_exists($this->getSkinDirectory())) {
79 }
80
81 mkdir($this->getSkinDirectory(), 0777, true);
82
83 foreach ($this->getSkin()->getStyles() as $style) {
84 $this->file_system->createResourceDirectory(
85 $this->getSystemStylesConf()->getDefaultImagesPath(),
86 $this->getImagesSkinPath($style->getId())
87 );
88 $this->file_system->createResourceDirectory(
89 $this->getSystemStylesConf()->getDefaultSoundsPath(),
90 $this->getSkinDirectory() . $style->getSoundDirectory()
91 );
92 $this->file_system->createResourceDirectory(
93 $this->getSystemStylesConf()->getDefaultFontsPath(),
94 $this->getSkinDirectory() . $style->getFontDirectory()
95 );
96 try {
97 $this->createLessStructure($style);
98 } catch (Exception $e) {
100 $this->lng->txt('less_compile_failed') . ' ' . $e->getMessage(),
102 ));
103 }
104 }
105 $this->writeSkinToXML();
106 }
107
112 public function updateSkin(ilSkin $old_skin = null): void
113 {
114 if (!$old_skin) {
115 $old_skin = $this->getSkin();
116 }
117 $old_customizing_skin_directory = $this->getSystemStylesConf()->getCustomizingSkinPath() . $old_skin->getId() . '/';
118
119 //Move if skin id has been changed
120 if ($old_skin->getId() != $this->getSkin()->getId()) {
121 $this->file_system->move($old_customizing_skin_directory, $this->getSkinDirectory());
122 }
123
124 //Delete old template.xml and write a new one
125 $this->file_system->delete($this->getSkinDirectory() . 'template.xml');
126 $this->writeSkinToXML();
127 }
128
132 public function updateStyle(string $style_id, ilSkinStyle $old_style): void
133 {
134 $style = $this->getSkin()->getStyle($style_id);
135 if ($style->getImageDirectory() != $old_style->getImageDirectory()) {
136 if (file_exists($this->getSkinDirectory() . $old_style->getImageDirectory())) {
137 $this->file_system->changeResourceDirectory(
138 $this->getSkinDirectory(),
139 $style->getImageDirectory(),
140 $old_style->getImageDirectory(),
141 count($this->resourcesStyleReferences($old_style->getImageDirectory())) > 0
142 );
143 } else {
144 $this->file_system->createResourceDirectory(
145 $this->getSystemStylesConf()->getDefaultImagesPath(),
146 $this->getImagesSkinPath($style->getId())
147 );
148 }
149 }
150
151 if ($style->getFontDirectory() != $old_style->getFontDirectory()) {
152 if (file_exists($this->getSkinDirectory() . $old_style->getFontDirectory())) {
153 $this->file_system->changeResourceDirectory(
154 $this->getSkinDirectory(),
155 $style->getFontDirectory(),
156 $old_style->getFontDirectory(),
157 count($this->resourcesStyleReferences($old_style->getFontDirectory())) > 0
158 );
159 } else {
160 $this->file_system->createResourceDirectory(
161 $this->getSystemStylesConf()->getDefaultFontsPath(),
162 $this->getSkinDirectory() . $style->getFontDirectory()
163 );
164 }
165 }
166
167 if ($style->getSoundDirectory() != $old_style->getSoundDirectory()) {
168 if (file_exists($this->getSkinDirectory() . $old_style->getSoundDirectory())) {
169 $this->file_system->changeResourceDirectory(
170 $this->getSkinDirectory(),
171 $style->getSoundDirectory(),
172 $old_style->getSoundDirectory(),
173 count($this->resourcesStyleReferences($old_style->getSoundDirectory())) > 0
174 );
175 } else {
176 $this->file_system->createResourceDirectory(
177 $this->getSystemStylesConf()->getDefaultSoundsPath(),
178 $this->getSkinDirectory() . $style->getSoundDirectory()
179 );
180 }
181 }
182
183 if (file_exists($this->getSkinDirectory() . $old_style->getCssFile() . '.less')) {
184 rename(
185 $this->getSkinDirectory() . $old_style->getCssFile() . '.less',
186 $this->getLessFilePath($style->getId())
187 );
188 } else {
189 $this->createMainLessFile($style);
190 }
191
192 if (file_exists($this->getSkinDirectory() . $old_style->getCssFile() . '-variables.less')) {
193 rename(
194 $this->getSkinDirectory() . $old_style->getCssFile() . '-variables.less',
195 $this->getLessVariablesFilePath($style->getId())
196 );
197 } else {
198 $this->copyVariablesFromDefault($style);
199 }
200
202 $this->getLessFilePath($style->getId()),
203 $old_style->getCssFile() . '-variables.less',
204 $this->getLessVariablesName($style->getId())
205 );
206
207 if (file_exists($this->getSkinDirectory() . $old_style->getCssFile() . '.css')) {
208 rename(
209 $this->getSkinDirectory() . $old_style->getCssFile() . '.css',
210 $this->getCSSFilePath($style->getId())
211 );
212 } else {
213 try {
214 $this->compileLess($style->getId());
215 } catch (Exception $e) {
216 $this->getMessageStack()->addMessage(
218 $e->getMessage(),
220 )
221 );
222 copy($this->getSystemStylesConf()->getDelosPath() . '.css', $this->getCSSFilePath($style->getId()));
223 }
224 }
225
226 $this->writeSkinToXML();
227 }
228
232 protected function resourcesStyleReferences(string $resource): array
233 {
234 $references_ids = [];
235 foreach ($this->getSkin()->getStyles() as $style) {
236 if ($style->referencesResource($resource)) {
237 $references_ids[] = $style->getId();
238 }
239 }
240 return $references_ids;
241 }
242
247 protected function createLessStructure(ilSkinStyle $style): void
248 {
249 $this->createMainLessFile($style);
250 $this->copyVariablesFromDefault($style);
251 $this->copyCSSFromDefault($style);
252 $this->compileLess($style->getId());
253 }
254
258 public function createMainLessFile(ilSkinStyle $style): void
259 {
260 $path = $this->getLessFilePath($style->getId());
261 file_put_contents($path, $this->getLessMainFileDefautContent($style));
262 $this->getMessageStack()->addMessage(
264 $this->lng->txt('main_less_created') . ' ' . $path,
266 )
267 );
268 }
269
274 {
275 $less_file = new ilSystemStyleLessFile($this->getSystemStylesConf()->getDefaultVariablesPath());
276 $less_file->setLessVariablesFilePathName($this->getLessVariablesFilePath($style->getId()));
277 $less_file->write();
278 return $less_file;
279 }
280
284 public function resetImages(ilSkinStyle $style): void
285 {
286 $this->file_system->recursiveRemoveDir($this->getSkinDirectory() . $style->getImageDirectory());
287 $this->file_system->createResourceDirectory(
288 $this->getSystemStylesConf()->getDefaultImagesPath(),
289 $this->getImagesSkinPath($style->getId())
290 );
291 }
292
296 public function copyCSSFromDefault(ilSkinStyle $style): void
297 {
298 copy($this->getSystemStylesConf()->getDelosPath() . '.css', $this->getCSSFilePath($style->getId()));
299 }
300
304 protected function getLessMainFileDefautContent(ilSkinStyle $style): string
305 {
306 $content = "@import \"" . $this->getSystemStylesConf()->getRelDelosPath() . "\";\n";
307 $content .= "// Import Custom Less Files here\n";
308
309 $content .= "@import \"" . $this->getLessVariablesName($style->getId()) . "\";\n";
310 return $content;
311 }
312
316 public function delete(): void
317 {
318 $this->file_system->recursiveRemoveDir(self::getSkinDirectory());
319 $this->getMessageStack()->addMessage(
321 $this->lng->txt('skin_deleted') . $this->getSkinDirectory(),
323 )
324 );
325 }
326
330 public function deleteStyle(ilSkinStyle $style): void
331 {
332 if ($style->isSubstyle()) {
334 $this->getSkin()->getId(),
335 $style->getSubstyleOf(),
336 $style->getId()
337 );
338 $this->getMessageStack()->prependMessage(
340 $this->lng->txt('style_assignments_deleted') . ' ' . $style->getName(),
342 )
343 );
344 }
345
346 $this->file_system->saveDeleteFile($this->getLessFilePath($style->getId()));
347 $this->file_system->saveDeleteFile($this->getCSSFilePath($style->getId()));
348 $this->file_system->saveDeleteFile($this->getLessVariablesFilePath($style->getId()));
349
350 $this->getSkin()->removeStyle($style->getId());
351
352 $this->file_system->removeResourceDirectory(
353 $this->getSkinDirectory(),
354 $style->getImageDirectory(),
355 count($this->resourcesStyleReferences($style->getImageDirectory())) > 0
356 );
357 $this->file_system->removeResourceDirectory(
358 $this->getSkinDirectory(),
359 $style->getFontDirectory(),
360 count($this->resourcesStyleReferences($style->getImageDirectory())) > 0
361 );
362 $this->file_system->removeResourceDirectory(
363 $this->getSkinDirectory(),
364 $style->getSoundDirectory(),
365 count($this->resourcesStyleReferences($style->getImageDirectory())) > 0
366 );
367
368 $this->writeSkinToXML();
369 $this->getMessageStack()->prependMessage(
371 $this->lng->txt('style_deleted') . ' ' . $style->getName(),
373 )
374 );
375 }
376
380 public function export(): void
381 {
383 $this->createTempZip(),
384 $this->getSkin()->getId() . '.zip',
385 '',
386 true
387 );
388 }
389
393 public function createTempZip(): string
394 {
395 $rel_tmp_zip = '../' . $this->getSkin()->getId() . '.zip';
396 ilFileUtils::zip($this->getSkinDirectory(), $rel_tmp_zip, true);
397 return rtrim($this->getSkinDirectory(), '/') . '.zip';
398 }
399
400 protected function changeVariablesImport(
401 string $main_path,
402 string $old_style_import,
403 string $new_style_import
404 ): void {
405 $main_less_content = file_get_contents($main_path);
406 $main_less_content = str_replace(
407 "@import \"" . $old_style_import,
408 "@import \"" . $new_style_import,
409 $main_less_content
410 );
411 file_put_contents($main_path, $main_less_content);
412 }
413
417 public function compileLess(string $style_id): void
418 {
419 if (!PATH_TO_LESSC) {
421 }
422
423 $output = shell_exec(PATH_TO_LESSC . ' ' . $this->getLessFilePath($style_id));
424 if (!$output) {
425 $less_error = shell_exec(PATH_TO_LESSC . ' ' . $this->getLessFilePath($style_id) . ' 2>&1');
426 if (!$less_error) {
427 throw new ilSystemStyleException(
429 'Empty css output, unknown error.'
430 );
431 }
433 }
434 file_put_contents($this->getCSSFilePath($style_id), $output);
435 }
436
437 public function getSkin(): ilSkin
438 {
439 return $this->skin;
440 }
441
442 public function setSkin(ilSkin $skin): void
443 {
444 $this->skin = $skin;
445 }
446
447 public function getSkinDirectory(): string
448 {
449 return $this->getSystemStylesConf()->getCustomizingSkinPath() . $this->getSkin()->getId() . '/';
450 }
451
452 public function getCSSFilePath(string $style_id): string
453 {
454 return $this->getSkinDirectory() . $this->getSkin()->getStyle($style_id)->getCssFile() . '.css';
455 }
456
457 public function getLessFilePath(string $style_id): string
458 {
459 return $this->getSkinDirectory() . $this->getSkin()->getStyle($style_id)->getCssFile() . '.less';
460 }
461
462 public function getLessVariablesFilePath(string $style_id): string
463 {
464 return $this->getSkinDirectory() . $this->getLessVariablesName($style_id);
465 }
466
467 public function getLessVariablesName(string $style_id): string
468 {
469 return $this->getSkin()->getStyle($style_id)->getCssFile() . '-variables.less';
470 }
471
472 public function getImagesSkinPath(string $style_id): string
473 {
474 return $this->getSkinDirectory() . $this->getSkin()->getStyle($style_id)->getImageDirectory();
475 }
476
478 {
479 return $this->message_stack;
480 }
481
482 public function setMessageStack(ilSystemStyleMessageStack $message_stack): void
483 {
484 $this->message_stack = $message_stack;
485 }
486
487 public function addStyle(ilSkinStyle $style): void
488 {
489 $this->getSkin()->addStyle($style);
490 $old_style = new ilSkinStyle('', '');
491 $this->updateStyle($style->getId(), $old_style);
492 }
493
494 protected function writeSkinToXML(): void
495 {
496 $this->getSkin()->writeToXMLFile($this->getSkinDirectory() . 'template.xml');
497 }
498
500 {
501 return $this->system_styles_conf;
502 }
503
504 public function setSystemStylesConf(ilSystemStyleConfig $system_styles_conf): void
505 {
506 $this->system_styles_conf = $system_styles_conf;
507 }
508}
static deliverFileAttached(string $path_to_file, ?string $download_file_name=null, ?string $mime_type=null, bool $delete_file=false)
File System Helper, to reduce deps.
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
language handling
This class is responsible for all file system related actions related actions of a skin such as copyi...
updateSkin(ilSkin $old_skin=null)
Updates the skin.
export()
Exports the complete skin to an zip file.
__construct(ilLanguage $lng, ilSkin $skin, ilSystemStyleMessageStack $message_stack, ilSystemStyleConfig $system_styles_conf=null, ilFileSystemHelper $file_system=null)
createLessStructure(ilSkinStyle $style)
Creates the less/css structure of a style.
getLessMainFileDefautContent(ilSkinStyle $style)
Returns the main less default content if a new style is created.
createTempZip()
Creates a temp zip file.
deleteStyle(ilSkinStyle $style)
Deletes a style completely.
getLessVariablesFilePath(string $style_id)
ilSystemStyleConfig $system_styles_conf
Used to wire this component up with the correct pathes into the customizing directory.
ilSkin $skin
Data-scope for the skin this container capsules.
create(ilSystemStyleMessageStack $message_stack)
Creates a new skin.
setSystemStylesConf(ilSystemStyleConfig $system_styles_conf)
createMainLessFile(ilSkinStyle $style)
Creates the main less file.
getLessVariablesName(string $style_id)
resourcesStyleReferences(string $resource)
Checks if a given resource (folder) is still referenced by a style of the containers skin.
resetImages(ilSkinStyle $style)
Copies (resets) the images from delos.
ilSystemStyleMessageStack $message_stack
Used to stack messages to be displayed to the user (mostly reports for failed actions)
setMessageStack(ilSystemStyleMessageStack $message_stack)
updateStyle(string $style_id, ilSkinStyle $old_style)
Updates one single style.
copyVariablesFromDefault(ilSkinStyle $style)
Copies (resets) the variables file from delos.
copyCSSFromDefault(ilSkinStyle $style)
Copies (resets) the images from delos.
changeVariablesImport(string $main_path, string $old_style_import, string $new_style_import)
isSubstyle()
Return wheter this style is a substyle of another.
getSubstyleOf()
Returns the parent style of this style if set.
ilSkin holds an manages the basic data of a skin as provide by the template of the skin.
ilSystemStyleConfig wraps all 'constants' to ensure the testability of all classes using those 'const...
Class for advanced editing exception handling in ILIAS.
Used to stack messages to be shown to the user.
addMessage(ilSystemStyleMessage $message)
Add a message to be displayed by the stack.
static deleteSubStyleCategoryAssignments(string $a_skin_id, string $a_style_id, string $a_substyle)
Delets a sub styles category assignment.
$path
Definition: ltiservices.php:32