ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilSystemStyleSkinContainer.php
Go to the documentation of this file.
1<?php
2include_once("Services/Style/System/classes/Utilities/class.ilSkinStyleXML.php");
3include_once("Services/Style/System/classes/class.ilStyleDefinition.php");
4include_once("Services/Style/System/classes/Exceptions/class.ilSystemStyleException.php");
5include_once("Services/Style/System/classes/Utilities/class.ilSystemStyleMessageStack.php");
6include_once("Services/Style/System/classes/Utilities/class.ilSystemStyleMessage.php");
7include_once("Services/Style/System/classes/Less/class.ilSystemStyleLessFile.php");
8include_once("Services/Style/System/classes/Utilities/class.ilSystemStyleConfig.php");
9
20
24 protected $lng;
25
31 protected $skin;
32
38 protected static $message_stack = null;
39
46
55 {
56 global $DIC;
57
58 $this->lng = $DIC->language();
59
60 $this->skin = $skin;
61
62 if(!$message_stack){
64 }else{
66 }
67
70 }else{
72 }
73 }
74
85 if(!$skin_id){
87 }
88
91 }
92
93 if ($skin_id != "default")
94 {
95 return new self(ilSkinXML::parseFromXML($system_styles_conf->getCustomizingSkinPath().$skin_id."/template.xml"), $message_stack, $system_styles_conf);
96 }else{
97 return new self(ilSkinXML::parseFromXML($system_styles_conf->getDefaultTemplatePath()), $message_stack, $system_styles_conf);
98 }
99
100 }
101
109 if(file_exists($this->getSkinDirectory())){
111 }
112
113
114 mkdir($this->getSkinDirectory(),0777,true);
115
116 foreach($this->getSkin()->getStyles() as $style){
117 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultImagesPath(),$style->getImageDirectory());
118 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultSoundsPath(),$style->getSoundDirectory());
119 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultFontsPath(),$style->getFontDirectory());
120 try{
121 $this->createLessStructure($style);
122 }catch(Exception $e){
123 $message_stack->addMessage(new ilSystemStyleMessage($this->lng->txt("less_compile_failed")." ".$e->getMessage(),ilSystemStyleMessage::TYPE_ERROR));
124 }
125
126 }
127 $this->writeSkinToXML();
128
129
130 }
131
138 public function updateSkin(ilSkinXML $old_skin){
139 $old_customizing_skin_directory = $this->getSystemStylesConf()->getCustomizingSkinPath().$old_skin->getId()."/";
140
141 //Move if skin id has been changed
142 if($old_skin->getId()!= $this->getSkin()->getId()){
143 $this->move($old_customizing_skin_directory,$this->getSkinDirectory());
144 }
145
146 //Delete old template.xml and write a new one
147 unlink($this->getSkinDirectory()."template.xml");
148 $this->writeSkinToXML();
149 }
150
157 public function updateStyle($style_id, ilSkinStyleXML $old_style){
158 $style = $this->getSkin()->getStyle($style_id);
159
160 if($style->getImageDirectory()!=$old_style->getImageDirectory())
161 {
162 if(file_exists($this->getSkinDirectory().$old_style->getImageDirectory())){
163 $this->changeResourceDirectory($style->getImageDirectory(),$old_style->getImageDirectory());
164 }else{
165 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultImagesPath(),$style->getImageDirectory());
166 }
167 }
168
169 if($style->getFontDirectory()!=$old_style->getFontDirectory())
170 {
171 if(file_exists($this->getSkinDirectory().$old_style->getFontDirectory())){
172 $this->changeResourceDirectory($style->getFontDirectory(),$old_style->getFontDirectory());
173 }else{
174 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultFontsPath(),$style->getFontDirectory());
175 }
176 }
177
178 if($style->getSoundDirectory()!=$old_style->getSoundDirectory())
179 {
180 if(file_exists($this->getSkinDirectory().$old_style->getSoundDirectory())){
181 $this->changeResourceDirectory($style->getSoundDirectory(),$old_style->getSoundDirectory());
182 }else{
183 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultSoundsPath(),$style->getSoundDirectory());
184 }
185 }
186
187
188
189 if(file_exists($this->getSkinDirectory().$old_style->getCssFile().".less")){
190 rename($this->getSkinDirectory().$old_style->getCssFile().".less", $this->getLessFilePath($style->getId()));
191 }else{
193 }
194
195 if(file_exists($this->getSkinDirectory().$old_style->getCssFile()."-variables.less")){
196 rename($this->getSkinDirectory().$old_style->getCssFile()."-variables.less", $this->getLessVariablesFilePath($style->getId()));
197 }else{
199 }
200
201 $this->changeVariablesImport($this->getLessFilePath($style->getId()),$old_style->getCssFile()."-variables.less",$this->getLessVariablesName($style->getId()));
202
203 if(file_exists($this->getSkinDirectory().$old_style->getCssFile().".css")){
204 rename($this->getSkinDirectory().$old_style->getCssFile().".css", $this->getCSSFilePath($style->getId()));
205 }else{
206 try{
207 $this->compileLess($style->getId());
208 }catch(Exception $e){
209 $this->getMessageStack()->addMessage(
210 new ilSystemStyleMessage($e->getMessage(),
212 ));
213 copy ($this->getSystemStylesConf()->getDelosPath().".css",$this->getCSSFilePath($style->getId()));
214 }
215 }
216
217 $this->writeSkinToXML();
218
219 }
220
227 protected function resourcesStyleReferences($resource){
228 $references_ids = array();
229 foreach ($this->getSkin()->getStyles() as $style) {
230 if($style->referencesResource($resource)){
231 $references_ids[] = $style->getId();
232 }
233 }
234 return $references_ids;
235
236 }
237
245 protected function createResourceDirectory($source, $target){
246 $path = $this->getSkinDirectory().$target;
247
248 mkdir($path,0777,true);
249
250 if($source != ""){
251 self::xCopy($source,$path);
252 $this->getMessageStack()->addMessage(
253 new ilSystemStyleMessage($this->lng->txt("dir_created").$path,
255 ));
256 }
257 }
258
266 protected function changeResourceDirectory($new_dir,$old_dir){
267 $absolut_new_dir = $this->getSkinDirectory().$new_dir;
268 $absolut_old_dir = $this->getSkinDirectory().$old_dir;
269
270 if(file_exists($absolut_new_dir)){
271 $this->getMessageStack()->addMessage(
272 new ilSystemStyleMessage($this->lng->txt("dir_changed_to")." ".$absolut_new_dir,
274 ));
275 $this->getMessageStack()->addMessage(
276 new ilSystemStyleMessage($this->lng->txt("dir_preserved_backup")." ".$absolut_old_dir,
278 ));
279 }else{
280 mkdir($absolut_new_dir,0777,true);
281 self::xCopy($absolut_old_dir, $absolut_new_dir);
282 $this->getMessageStack()->addMessage(
283 new ilSystemStyleMessage($this->lng->txt("dir_copied_from")." ".$absolut_old_dir." ".$this->lng->txt("to")." ".$absolut_new_dir,
285 ));
286 if(count($this->resourcesStyleReferences($old_dir))==0){
287 self::recursiveRemoveDir(self::getSkinDirectory().$old_dir);
288 $this->getMessageStack()->addMessage(
289 new ilSystemStyleMessage($this->lng->txt("dir_deleted")." ".$absolut_old_dir,
291 ));
292 }else{
293 $this->getMessageStack()->addMessage(
294 new ilSystemStyleMessage($this->lng->txt("dir_preserved_linked")." ".$absolut_old_dir,
296 ));
297 }
298 }
299 }
300
306 protected function removeResourceDirectory($dir){
307 $absolut_dir = $this->getSkinDirectory().$dir;
308
309 if(file_exists($absolut_dir)) {
310 if (count($this->resourcesStyleReferences($dir)) == 0) {
312 $this->getMessageStack()->addMessage(
313 new ilSystemStyleMessage($this->lng->txt("dir_deleted")." ". $dir,
315 ));
316 } else {
317 $this->getMessageStack()->addMessage(
318 new ilSystemStyleMessage($this->lng->txt("dir_preserved_linked")." ". $dir,
320 ));
321 }
322 }
323 }
324
332 $this->createMainLessFile($style);
333 $this->copyVariablesFromDefault($style);
334 $this->copyCSSFromDefault($style);
335 $this->compileLess($style->getId());
336 }
337
344 $path = $this->getLessFilePath($style->getId());
345 file_put_contents($path,$this->getLessMainFileDefautContent($style));
346 $this->getMessageStack()->addMessage(
347 new ilSystemStyleMessage($this->lng->txt("main_less_created")." ".$path,
349 ));
350 }
351
359 $less_file = new ilSystemStyleLessFile($this->getSystemStylesConf()->getDefaultVariablesPath());
360 $less_file->setLessVariablesFile($this->getLessVariablesFilePath($style->getId()));
361 $less_file->write();
362 return $less_file;
363 }
364
372 $this->createResourceDirectory($this->getSystemStylesConf()->getDefaultImagesPath(),$style->getImageDirectory());
373 }
374
381 copy ($this->getSystemStylesConf()->getDelosPath().".css",$this->getCSSFilePath($style->getId()));
382 }
383
391 static function xCopy($src, $dest)
392 {
393 foreach (scandir($src) as $file) {
394 $src_file = rtrim($src, '/') . '/' . $file;
395 $dest_file = rtrim($dest, '/') . '/' . $file;
396 if (!is_readable($src_file)) {
398 }
399 if (substr($file, 0, 1) != ".") {
400 if (is_dir($src_file)) {
401 if (!file_exists($dest_file)) {
402 try {
403 mkdir($dest_file);
404 } catch (Exception $e) {
405 throw new ilSystemStyleException(ilSystemStyleException::FOLDER_CREATION_FAILED, "Copy " . $src_file . " to " . $dest_file . " Error: " . $e);
406 }
407 }
408 self::xCopy($src_file, $dest_file);
409 } else {
410 try {
411 copy($src_file,$dest_file);
412 } catch (Exception $e) {
413 throw new ilSystemStyleException(ilSystemStyleException::FILE_CREATION_FAILED, "Copy " . $src_file . " to " . $dest_file . " Error: " . $e);
414 }
415 }
416 }
417 }
418 }
419
425 static function recursiveRemoveDir($dir){
426 if (is_dir($dir)) {
427 $objects = scandir($dir);
428 foreach ($objects as $object) {
429 if ($object != "." && $object != "..") {
430 if (is_dir($dir."/".$object))
431 self::recursiveRemoveDir($dir."/".$object);
432 else
433 unlink($dir."/".$object);
434 }
435 }
436 rmdir($dir);
437 }
438 }
439
440
448 $less_delos_import = $this->getSystemStylesConf()->getDelosPath();
449 $less_delos_import = str_replace("./","../../../../",$less_delos_import);
450 $content = "@import \"".$less_delos_import."\";\n";
451
452 $content .= "// Import Custom Less Files here\n";
453
454 $content .= "@import \"".$this->getLessVariablesName($style->getId())."\";\n";
455 return $content;
456 }
457
464 public function move($from,$to){
465 rename($from,$to);
466 }
467
468
472 public function delete(){
473 self::recursiveRemoveDir(self::getSkinDirectory());
474 $this->getMessageStack()->addMessage(
475 new ilSystemStyleMessage($this->lng->txt("skin_deleted").$this->getSkinDirectory(),
477 ));
478 }
479
485 protected function deleteFile($path){
486 if(file_exists($path)){
487 unlink($path);
488 $this->getMessageStack()->addMessage(
489 new ilSystemStyleMessage($this->lng->txt("file_deleted") . " " . $path,
491 ));
492 }
493 }
494
501 if($style->isSubstyle()){
502 ilSystemStyleSettings::deleteSubStyleCategoryAssignments($this->getSkin()->getId(),$style->getSubstyleOf(),$style->getId());
503 $this->getMessageStack()->prependMessage(
504 new ilSystemStyleMessage($this->lng->txt("style_assignments_deleted")." ".$style->getName(),
506 ));
507 }
508
509 $this->deleteFile($this->getLessFilePath($style->getId()));
510 $this->deleteFile($this->getCSSFilePath($style->getId()));
511 $this->deleteFile($this->getLessVariablesFilePath($style->getId()));
512
513 $this->getSkin()->removeStyle($style->getId());
514
518
519 $this->writeSkinToXML();
520 $this->getMessageStack()->prependMessage(
521 new ilSystemStyleMessage($this->lng->txt("style_deleted")." ".$style->getName(),
523 ));
524 }
525
532 public function copy(){
533 $new_skin_id_addon = "";
534
535 while(ilStyleDefinition::skinExists($this->getSkin()->getId().$new_skin_id_addon, $this->getSystemStylesConf())){
536 $new_skin_id_addon .= "Copy";
537 }
538
539 $new_skin_path = rtrim($this->getSkinDirectory(),"/").$new_skin_id_addon;
540
541 mkdir($new_skin_path,0777,true);
542 $this->xCopy($this->getSkinDirectory(),$new_skin_path);
543 $this->getMessageStack()->addMessage(new ilSystemStyleMessage($this->lng->txt("directory_created")." ".$new_skin_path,ilSystemStyleMessage::TYPE_SUCCESS));
544 return self::generateFromId($this->getSkin()->getId().$new_skin_id_addon,null,$this->getSystemStylesConf());
545
546 }
547
551 public function export(){
552 ilFileDelivery::deliverFileAttached($this->createTempZip(), $this->getSkin()->getId().".zip",null, true);
553 }
554
560 public function createTempZip(){
561 $rel_tmp_zip = "../".$this->getSkin()->getId().".zip";
562 ilUtil::zip($this->getSkinDirectory(),$rel_tmp_zip,true);
563 return rtrim($this->getSkinDirectory(),"/").".zip";
564 }
565
577 public static function import($import_zip_path, $name, ilSystemStyleMessageStack $message_stack = null, $system_styles_conf = null,$uploaded = true){
580 }
581
582 $skin_id = preg_replace('/[^A-Za-z0-9\-_]/', '', rtrim($name,".zip"));
583
585 $skin_id .= "Copy";
586 }
587
588 $skin_path = $system_styles_conf->getCustomizingSkinPath().$skin_id;
589 mkdir($skin_path,0777,true);
590
591 $temp_zip_path = $skin_path."/".$name;
592 if($uploaded){
593 move_uploaded_file ( $import_zip_path ,$temp_zip_path );
594 }else{
595 rename( $import_zip_path ,$temp_zip_path );
596 }
597 ilUtil::unzip($temp_zip_path);
598 unlink($temp_zip_path);
599
601 }
602
608 protected function changeVariablesImport($main_path,$old_style_import,$new_style_import){
609 $main_less_content = file_get_contents($main_path);
610 $main_less_content = str_replace("@import \"".$old_style_import,
611 "@import \"".$new_style_import,
612 $main_less_content);
613 file_put_contents($main_path,$main_less_content);
614 }
615
620 public function compileLess($style_id){
621
622 if(!PATH_TO_LESSC){
624 }
625
626 $output = shell_exec(PATH_TO_LESSC." ".$this->getLessFilePath($style_id));
627 if(!$output){
628 $less_error = shell_exec(PATH_TO_LESSC." ".$this->getLessFilePath($style_id)." 2>&1");
629 if(!$less_error){
630 throw new ilSystemStyleException(ilSystemStyleException::LESS_COMPILE_FAILED, "Empty css output, unknown error.");
631 }
633 }
634 file_put_contents($this->getCSSFilePath($style_id),$output);
635 }
639 public function getSkin()
640 {
641 return $this->skin;
642 }
643
647 public function setSkin($skin)
648 {
649 $this->skin = $skin;
650 }
651
655 public function getSkinDirectory()
656 {
657 return $this->getSystemStylesConf()->getCustomizingSkinPath().$this->getSkin()->getId()."/";
658 }
659
660
665 public function getCSSFilePath($style_id){
666 return $this->getSkinDirectory().$this->getSkin()->getStyle($style_id)->getCssFile().".css";
667 }
668
673 public function getLessFilePath($style_id){
674 return $this->getSkinDirectory().$this->getSkin()->getStyle($style_id)->getCssFile().".less";
675 }
676
681 public function getLessVariablesFilePath($style_id){
682 return $this->getSkinDirectory().$this->getLessVariablesName($style_id);
683 }
684
689 public function getLessVariablesName($style_id){
690 return $this->getSkin()->getStyle($style_id)->getCssFile()."-variables.less";
691 }
692
697 public function getImagesSkinPath($style_id){
698 return $this->getSkinDirectory().$this->getSkin()->getStyle($style_id)->getImageDirectory();
699 }
700
704 public static function getMessageStack()
705 {
707 }
708
712 public static function setMessageStack($message_stack)
713 {
714 self::$message_stack = $message_stack;
715 }
716
721 $this->getSkin()->addStyle($style);
722 $old_style = new ilSkinStyleXML("","");
723 $this->updateStyle($style->getId(), $old_style);
724 }
725
726 protected function writeSkinToXML(){
727 $this->getSkin()->writeToXMLFile($this->getSkinDirectory()."template.xml");
728 }
729
733 public function getSystemStylesConf()
734 {
736 }
737
742 {
743 $this->system_styles_conf = $system_styles_conf;
744 }
745}
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
static deliverFileAttached($path_to_file, $download_file_name=null, $mime_type=null, $delete_file=false)
ilSkinXml holds an manages the basic data of a skin as provide by the template of the skin.
static skinExists($skin_id, ilSystemStyleConfig $system_style_config=null)
Check whether a skin exists.
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.
static deleteSubStyleCategoryAssignments($a_skin_id, $a_style_id, $a_substyle)
Delets a sub styles category assignment.
This class is responsible for all file system related actions related actions of a skin such as copyi...
static recursiveRemoveDir($dir)
Recursive delete of a folder.
getLessMainFileDefautContent(ilSkinStyleXML $style)
Returns the main less default content if a new style is created.
deleteFile($path)
Deletes a given file in the container.
changeResourceDirectory($new_dir, $old_dir)
Alters the name/path of a resource directory.
createResourceDirectory($source, $target)
Creates a resource directory (sound, images or fonts) by copying from the source (mostly delos)
copyCSSFromDefault(ilSkinStyleXML $style)
Copies (resets) the images from delos.
updateSkin(ilSkinXML $old_skin)
Updates the skin.
removeResourceDirectory($dir)
Deletes a resource directory.
static generateFromId($skin_id, ilSystemStyleMessageStack $message_stack=null, ilSystemStyleConfig $system_styles_conf=null)
Generate the container class by parsing the corresponding XML.
static xCopy($src, $dest)
Recursive copy of a folder.
changeVariablesImport($main_path, $old_style_import, $new_style_import)
copyVariablesFromDefault(ilSkinStyleXML $style)
Copies (resets) the variables file from delos.
resourcesStyleReferences($resource)
Checks if a given resource (folder) is still referenced by a style of the containers skin.
export()
Exports the complete skin to an zip file.
deleteStyle(ilSkinStyleXML $style)
Deletes a style completely.
move($from, $to)
Used to move a complete directory of a skin.
__construct(ilSkinXML $skin, ilSystemStyleMessageStack $message_stack=null, ilSystemStyleConfig $system_styles_conf=null)
ilSystemStyleSkinContainer constructor.
updateStyle($style_id, ilSkinStyleXML $old_style)
Updates one single style.
resetImages(ilSkinStyleXML $style)
Copies (resets) the images from delos.
createMainLessFile(ilSkinStyleXML $style)
Creates the main less file.
create(ilSystemStyleMessageStack $message_stack)
Creates a new skin.
createLessStructure(ilSkinStyleXML $style)
Creates the less/css structure of a style.
static zip($a_dir, $a_file, $compress_content=false)
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
$style
Definition: example_012.php:70
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $DIC