ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilSystemStyleSkinContainer.php
Go to the documentation of this file.
1 <?php
2 include_once("Services/Style/System/classes/Utilities/class.ilSkinStyleXML.php");
3 include_once("Services/Style/System/classes/class.ilStyleDefinition.php");
4 include_once("Services/Style/System/classes/Exceptions/class.ilSystemStyleException.php");
5 include_once("Services/Style/System/classes/Utilities/class.ilSystemStyleMessageStack.php");
6 include_once("Services/Style/System/classes/Utilities/class.ilSystemStyleMessage.php");
7 include_once("Services/Style/System/classes/Less/class.ilSystemStyleLessFile.php");
8 include_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{
192  $this->createMainLessFile($style);
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) {
311  self::recursiveRemoveDir($this->getSkinDirectory() . $dir);
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 
371  self::recursiveRemoveDir($this->getSkinDirectory().$style->getImageDirectory());
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()){
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 
515  $this->removeResourceDirectory($style->getImageDirectory());
516  $this->removeResourceDirectory($style->getFontDirectory());
517  $this->removeResourceDirectory($style->getSoundDirectory());
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){
578  if(!$system_styles_conf){
579  $system_styles_conf = new ilSystemStyleConfig();
580  }
581 
582  $skin_id = preg_replace('/[^A-Za-z0-9\-_]/', '', rtrim($name,".zip"));
583 
584  while(ilStyleDefinition::skinExists($skin_id,$system_styles_conf)){
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 
600  return self::generateFromId($skin_id,$message_stack,$system_styles_conf);
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  {
706  return self::$message_stack;
707  }
708 
712  public static function setMessageStack($message_stack)
713  {
714  self::$message_stack = $message_stack;
715  }
716 
720  public function addStyle(ilSkinStyleXML $style){
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 
741  public function setSystemStylesConf($system_styles_conf)
742  {
743  $this->system_styles_conf = $system_styles_conf;
744  }
745 }
move($from, $to)
Used to move a complete directory of a skin.
createLessStructure(ilSkinStyleXML $style)
Creates the less/css structure of a style.
updateSkin(ilSkinXML $old_skin)
Updates the skin.
$path
Definition: aliased.php:25
$style
Definition: example_012.php:70
deleteStyle(ilSkinStyleXML $style)
Deletes a style completely.
This class is responsible for all file system related actions related actions of a skin such as copyi...
removeResourceDirectory($dir)
Deletes a resource directory.
create(ilSystemStyleMessageStack $message_stack)
Creates a new skin.
getSubstyleOf()
Returns the parent style of this style if set.
deleteFile($path)
Deletes a given file in the container.
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
addMessage(ilSystemStyleMessage $message)
Add a message to be displayed by the stack.
ilSkinXml holds an manages the basic data of a skin as provide by the template of the skin...
getLessMainFileDefautContent(ilSkinStyleXML $style)
Returns the main less default content if a new style is created.
createMainLessFile(ilSkinStyleXML $style)
Creates the main less file.
isSubstyle()
Return wheter this style is a substyle of another.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
updateStyle($style_id, ilSkinStyleXML $old_style)
Updates one single style.
static deliverFileAttached($path_to_file, $download_file_name=null, $mime_type=null, $delete_file=false)
createResourceDirectory($source, $target)
Creates a resource directory (sound, images or fonts) by copying from the source (mostly delos) ...
static recursiveRemoveDir($dir)
Recursive delete of a folder.
copyCSSFromDefault(ilSkinStyleXML $style)
Copies (resets) the images from delos.
static deleteSubStyleCategoryAssignments($a_skin_id, $a_style_id, $a_substyle)
Delets a sub styles category assignment.
Class for advanced editing exception handling in ILIAS.
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
static skinExists($skin_id, ilSystemStyleConfig $system_style_config=null)
Check whether a skin exists.
Create styles array
The data for the language used.
static generateFromId($skin_id, ilSystemStyleMessageStack $message_stack=null, ilSystemStyleConfig $system_styles_conf=null)
Generate the container class by parsing the corresponding XML.
copyVariablesFromDefault(ilSkinStyleXML $style)
Copies (resets) the variables file from delos.
ilSystemStyleConfig wraps all &#39;constants&#39; to ensure the testability of all classes using those &#39;const...
__construct(ilSkinXML $skin, ilSystemStyleMessageStack $message_stack=null, ilSystemStyleConfig $system_styles_conf=null)
ilSystemStyleSkinContainer constructor.
changeResourceDirectory($new_dir, $old_dir)
Alters the name/path of a resource directory.
resourcesStyleReferences($resource)
Checks if a given resource (folder) is still referenced by a style of the containers skin...
Used to stack messages to be shown to the user.
changeVariablesImport($main_path, $old_style_import, $new_style_import)
resetImages(ilSkinStyleXML $style)
Copies (resets) the images from delos.
global $DIC
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
export()
Exports the complete skin to an zip file.
static xCopy($src, $dest)
Recursive copy of a folder.