[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> StyleUtils.php (source)

   1  <?php
   2  
   3  namespace dokuwiki;
   4  
   5  /**
   6   * Class StyleUtils
   7   *
   8   * Reads and applies the template's style.ini settings
   9   */
  10  class StyleUtils
  11  {
  12  
  13      /** @var string current template */
  14      protected $tpl;
  15      /** @var bool reinitialize styles config */
  16      protected $reinit;
  17      /** @var bool $preview preview mode */
  18      protected $preview;
  19      /** @var array default replacements to be merged with custom style configs */
  20      protected $defaultReplacements = array(
  21          '__text__' => "#000",
  22          '__background__' => "#fff",
  23          '__text_alt__' => "#999",
  24          '__background_alt__' => "#eee",
  25          '__text_neu__' => "#666",
  26          '__background_neu__' => "#ddd",
  27          '__border__' => "#ccc",
  28          '__highlight__' => "#ff9",
  29          '__link__' => "#00f",
  30      );
  31  
  32      /**
  33       * StyleUtils constructor.
  34       * @param string $tpl template name: if not passed as argument, the default value from $conf will be used
  35       * @param bool $preview
  36       * @param bool $reinit whether static style conf should be reinitialized
  37       */
  38      public function __construct($tpl = '', $preview = false, $reinit = false)
  39      {
  40          if (!$tpl) {
  41              global $conf;
  42              $tpl = $conf['template'];
  43          }
  44          $this->tpl = $tpl;
  45          $this->reinit = $reinit;
  46          $this->preview = $preview;
  47      }
  48  
  49      /**
  50       * Load style ini contents
  51       *
  52       * Loads and merges style.ini files from template and config and prepares
  53       * the stylesheet modes
  54       *
  55       * @author Andreas Gohr <andi@splitbrain.org>
  56       * @author Anna Dabrowska <info@cosmocode.de>
  57       *
  58       * @return array with keys 'stylesheets' and 'replacements'
  59       */
  60      public function cssStyleini()
  61      {
  62          static $combined = [];
  63          if (!empty($combined) && !$this->reinit) {
  64              return $combined;
  65          }
  66  
  67          global $conf;
  68          global $config_cascade;
  69          $stylesheets = array(); // mode, file => base
  70  
  71          // guaranteed placeholder => value
  72          $replacements = $this->defaultReplacements;
  73  
  74          // merge all styles from config cascade
  75          if (!is_array($config_cascade['styleini'])) {
  76              trigger_error('Missing config cascade for styleini', E_USER_WARNING);
  77          }
  78  
  79          // allow replacement overwrites in preview mode
  80          if ($this->preview) {
  81              $config_cascade['styleini']['local'][] = $conf['cachedir'] . '/preview.ini';
  82          }
  83  
  84          $combined['stylesheets'] = [];
  85          $combined['replacements'] = [];
  86  
  87          foreach (array('default', 'local', 'protected') as $config_group) {
  88              if (empty($config_cascade['styleini'][$config_group])) continue;
  89  
  90              // set proper server dirs
  91              $webbase = $this->getWebbase($config_group);
  92  
  93              foreach ($config_cascade['styleini'][$config_group] as $inifile) {
  94                  // replace the placeholder with the name of the current template
  95                  $inifile = str_replace('%TEMPLATE%', $this->tpl, $inifile);
  96  
  97                  $incbase = dirname($inifile) . '/';
  98  
  99                  if (file_exists($inifile)) {
 100                      $config = parse_ini_file($inifile, true);
 101  
 102                      if (is_array($config['stylesheets'])) {
 103                          foreach ($config['stylesheets'] as $inifile => $mode) {
 104                              // validate and include style files
 105                              $stylesheets = array_merge(
 106                                  $stylesheets,
 107                                  $this->getValidatedStyles($stylesheets, $inifile, $mode, $incbase, $webbase)
 108                              );
 109                              $combined['stylesheets'] = array_merge($combined['stylesheets'], $stylesheets);
 110                          }
 111                      }
 112  
 113                      if (is_array($config['replacements'])) {
 114                          $replacements = array_replace(
 115                              $replacements,
 116                              $this->cssFixreplacementurls($config['replacements'], $webbase)
 117                          );
 118                          $combined['replacements'] = array_merge($combined['replacements'], $replacements);
 119                      }
 120                  }
 121              }
 122          }
 123  
 124          return $combined;
 125      }
 126  
 127      /**
 128       * Checks if configured style files exist and, if necessary, adjusts file extensions in config
 129       *
 130       * @param array $stylesheets
 131       * @param string $file
 132       * @param string $mode
 133       * @param string $incbase
 134       * @param string $webbase
 135       * @return mixed
 136       */
 137      protected function getValidatedStyles($stylesheets, $file, $mode, $incbase, $webbase)
 138      {
 139          global $conf;
 140          if (!file_exists($incbase . $file)) {
 141              list($extension, $basename) = array_map('strrev', explode('.', strrev($file), 2));
 142              $newExtension = $extension === 'css' ? 'less' : 'css';
 143              if (file_exists($incbase . $basename . '.' . $newExtension)) {
 144                  $stylesheets[$mode][$incbase . $basename . '.' . $newExtension] = $webbase;
 145                  if ($conf['allowdebug']) {
 146                      msg("Stylesheet $file not found, using $basename.$newExtension instead. " .
 147                          "Please contact developer of \"$this->tpl\" template.", 2);
 148                  }
 149              } elseif ($conf['allowdebug']) {
 150                  msg("Stylesheet $file not found, please contact the developer of \"$this->tpl\" template.", 2);
 151              }
 152          }
 153          $stylesheets[$mode][fullpath($incbase . $file)] = $webbase;
 154          return $stylesheets;
 155      }
 156  
 157      /**
 158       * Returns the web base path for the given level/group in config cascade.
 159       * Style resources are relative to the template directory for the main (default) styles
 160       * but relative to DOKU_BASE for everything else"
 161       *
 162       * @param string $config_group
 163       * @return string
 164       */
 165      protected function getWebbase($config_group)
 166      {
 167          if ($config_group === 'default') {
 168              return tpl_basedir($this->tpl);
 169          } else {
 170              return DOKU_BASE;
 171          }
 172      }
 173  
 174      /**
 175       * Amend paths used in replacement relative urls, refer FS#2879
 176       *
 177       * @author Chris Smith <chris@jalakai.co.uk>
 178       *
 179       * @param array $replacements with key-value pairs
 180       * @param string $location
 181       * @return array
 182       */
 183      protected function cssFixreplacementurls($replacements, $location)
 184      {
 185          foreach ($replacements as $key => $value) {
 186              $replacements[$key] = preg_replace(
 187                  '#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#',
 188                  '\\1' . $location,
 189                  $value
 190              );
 191          }
 192          return $replacements;
 193      }
 194  }