[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/exe/ -> css.php (source)

   1  <?php
   2  /**
   3   * DokuWiki StyleSheet creator
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   */
   8  
   9  if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
  10  if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
  11  require_once (DOKU_INC.'inc/init.php');
  12  require_once (DOKU_INC.'inc/pageutils.php');
  13  require_once (DOKU_INC.'inc/io.php');
  14  require_once (DOKU_INC.'inc/confutils.php');
  15  
  16  // Main (don't run when UNIT test)
  17  if(!defined('SIMPLE_TEST')){
  18      header('Content-Type: text/css; charset=utf-8');
  19      css_out();
  20  }
  21  
  22  
  23  // ---------------------- functions ------------------------------
  24  
  25  /**
  26   * Output all needed Styles
  27   *
  28   * @author Andreas Gohr <andi@splitbrain.org>
  29   */
  30  function css_out(){
  31      global $conf;
  32      global $lang;
  33      switch ($_REQUEST['s']) {
  34          case 'all':
  35          case 'print':
  36          case 'feed':
  37              $style = $_REQUEST['s'];
  38          break;
  39          default:
  40              $style = '';
  41          break;
  42      }
  43  
  44      $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t']));
  45      if($tpl){
  46          $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
  47          $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
  48      }else{
  49          $tplinc = DOKU_TPLINC;
  50          $tpldir = DOKU_TPL;
  51      }
  52  
  53      // The generated script depends on some dynamic options
  54      $cache = getCacheName('styles'.DOKU_BASE.$tplinc.$style,'.css');
  55  
  56      // load template styles
  57      $tplstyles = array();
  58      if(@file_exists($tplinc.'style.ini')){
  59          $ini = parse_ini_file($tplinc.'style.ini',true);
  60          foreach($ini['stylesheets'] as $file => $mode){
  61              $tplstyles[$mode][$tplinc.$file] = $tpldir;
  62          }
  63      }
  64  
  65      // Array of needed files and their web locations, the latter ones
  66      // are needed to fix relative paths in the stylesheets
  67      $files   = array();
  68      //if (isset($tplstyles['all'])) $files = array_merge($files, $tplstyles['all']);
  69      if(!empty($style)){
  70          $files[DOKU_INC.'lib/styles/'.$style.'.css'] = DOKU_BASE.'lib/styles/';
  71          // load plugin, template, user styles
  72          $files = array_merge($files, css_pluginstyles($style));
  73          if (isset($tplstyles[$style])) $files = array_merge($files, $tplstyles[$style]);
  74          $files[DOKU_CONF.'user'.$style.'.css'] = DOKU_BASE;
  75      }else{
  76          $files[DOKU_INC.'lib/styles/style.css'] = DOKU_BASE.'lib/styles/';
  77          if($conf['spellchecker']){
  78              $files[DOKU_INC.'lib/styles/spellcheck.css'] = DOKU_BASE.'lib/styles/';
  79          }
  80          // load plugin, template, user styles
  81          $files = array_merge($files, css_pluginstyles('screen'));
  82          if (isset($tplstyles['screen'])) $files = array_merge($files, $tplstyles['screen']);
  83          if($lang['direction'] == 'rtl'){
  84              if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']);
  85          }
  86          $files[DOKU_CONF.'userstyle.css'] = DOKU_BASE;
  87      }
  88  
  89      // check cache age & handle conditional request
  90      header('Cache-Control: public, max-age=3600');
  91      header('Pragma: public');
  92      if(css_cacheok($cache,array_keys($files),$tplinc)){
  93          http_conditionalRequest(filemtime($cache));
  94          if($conf['allowdebug']) header("X-CacheUsed: $cache");
  95          readfile($cache);
  96          return;
  97      } else {
  98          http_conditionalRequest(time());
  99      }
 100  
 101      // start output buffering and build the stylesheet
 102      ob_start();
 103  
 104      // print the default classes for interwiki links and file downloads
 105      css_interwiki();
 106      css_filetypes();
 107  
 108      // load files
 109      foreach($files as $file => $location){
 110          print css_loadfile($file, $location);
 111      }
 112  
 113      // end output buffering and get contents
 114      $css = ob_get_contents();
 115      ob_end_clean();
 116  
 117      // apply style replacements
 118      $css = css_applystyle($css,$tplinc);
 119  
 120      // compress whitespace and comments
 121      if($conf['compress']){
 122          $css = css_compress($css);
 123      }
 124  
 125      // save cache file
 126      io_saveFile($cache,$css);
 127  
 128      // finally send output
 129      print $css;
 130  }
 131  
 132  /**
 133   * Checks if a CSS Cache file still is valid
 134   *
 135   * @author Andreas Gohr <andi@splitbrain.org>
 136   */
 137  function css_cacheok($cache,$files,$tplinc){
 138      if($_REQUEST['purge']) return false; //support purge request
 139  
 140      $ctime = @filemtime($cache);
 141      if(!$ctime) return false; //There is no cache
 142  
 143      // some additional files to check
 144      $files[] = DOKU_CONF.'dokuwiki.php';
 145      $files[] = DOKU_CONF.'local.php';
 146      $files[] = $tplinc.'style.ini';
 147      $files[] = __FILE__;
 148  
 149      // now walk the files
 150      foreach($files as $file){
 151          if(@filemtime($file) > $ctime){
 152              return false;
 153          }
 154      }
 155      return true;
 156  }
 157  
 158  /**
 159   * Does placeholder replacements in the style according to
 160   * the ones defined in a templates style.ini file
 161   *
 162   * @author Andreas Gohr <andi@splitbrain.org>
 163   */
 164  function css_applystyle($css,$tplinc){
 165      if(@file_exists($tplinc.'style.ini')){
 166          $ini = parse_ini_file($tplinc.'style.ini',true);
 167          $css = strtr($css,$ini['replacements']);
 168      }
 169      return $css;
 170  }
 171  
 172  /**
 173   * Prints classes for interwikilinks
 174   *
 175   * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where
 176   * $name is the identifier given in the config. All Interwiki links get
 177   * an default style with a default icon. If a special icon is available
 178   * for an interwiki URL it is set in it's own class. Both classes can be
 179   * overwritten in the template or userstyles.
 180   *
 181   * @author Andreas Gohr <andi@splitbrain.org>
 182   */
 183  function css_interwiki(){
 184  
 185      // default style
 186      echo 'a.interwiki {';
 187      echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;';
 188      echo ' padding-left: 16px;';
 189      echo '}';
 190  
 191      // additional styles when icon available
 192      $iwlinks = getInterwiki();
 193      foreach(array_keys($iwlinks) as $iw){
 194          $class = preg_replace('/[^_\-a-z0-9]+/i','_',$iw);
 195          if(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.png')){
 196              echo "a.iw_$class {";
 197              echo '  background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.png)';
 198              echo '}';
 199          }elseif(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.gif')){
 200              echo "a.iw_$class {";
 201              echo '  background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.gif)';
 202              echo '}';
 203          }
 204      }
 205  }
 206  
 207  /**
 208   * Prints classes for file download links
 209   *
 210   * @author Andreas Gohr <andi@splitbrain.org>
 211   */
 212  function css_filetypes(){
 213  
 214      // default style
 215      echo 'a.mediafile {';
 216      echo ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/file.png) 0px 1px no-repeat;';
 217      echo ' padding-left: 18px;';
 218      echo ' padding-bottom: 1px;';
 219      echo '}';
 220  
 221      // additional styles when icon available
 222      $mimes = getMimeTypes();
 223      foreach(array_keys($mimes) as $mime){
 224          $class = preg_replace('/[^_\-a-z0-9]+/i','_',$mime);
 225          if(@file_exists(DOKU_INC.'lib/images/fileicons/'.$mime.'.png')){
 226              echo "a.mf_$class {";
 227              echo '  background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$mime.'.png)';
 228              echo '}';
 229          }elseif(@file_exists(DOKU_INC.'lib/images/fileicons/'.$mime.'.gif')){
 230              echo "a.mf_$class {";
 231              echo '  background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$mime.'.gif)';
 232              echo '}';
 233          }
 234      }
 235  }
 236  
 237  /**
 238   * Loads a given file and fixes relative URLs with the
 239   * given location prefix
 240   */
 241  function css_loadfile($file,$location=''){
 242      if(!@file_exists($file)) return '';
 243      $css = io_readFile($file);
 244      if(!$location) return $css;
 245  
 246      $css = preg_replace('#(url\([ \'"]*)((?!/|http://|https://| |\'|"))#','\\1'.$location.'\\3',$css);
 247      return $css;
 248  }
 249  
 250  
 251  /**
 252   * Returns a list of possible Plugin Styles (no existance check here)
 253   *
 254   * @author Andreas Gohr <andi@splitbrain.org>
 255   */
 256  function css_pluginstyles($mode='screen'){
 257      global $lang;
 258      $list = array();
 259      $plugins = plugin_list();
 260      foreach ($plugins as $p){
 261          if($mode == 'all'){
 262              $list[DOKU_PLUGIN."$p/all.css"]  = DOKU_BASE."lib/plugins/$p/";
 263          }elseif($mode == 'print'){
 264              $list[DOKU_PLUGIN."$p/print.css"]  = DOKU_BASE."lib/plugins/$p/";
 265          }elseif($mode == 'feed'){
 266              $list[DOKU_PLUGIN."$p/feed.css"]  = DOKU_BASE."lib/plugins/$p/";
 267          }else{
 268              $list[DOKU_PLUGIN."$p/style.css"]  = DOKU_BASE."lib/plugins/$p/";
 269              $list[DOKU_PLUGIN."$p/screen.css"] = DOKU_BASE."lib/plugins/$p/";
 270          }
 271          if($lang['direction'] == 'rtl'){
 272              $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/";
 273          }
 274      }
 275      return $list;
 276  }
 277  
 278  /**
 279   * Very simple CSS optimizer
 280   *
 281   * @author Andreas Gohr <andi@splitbrain.org>
 282   */
 283  function css_compress($css){
 284      //strip comments through a callback
 285      $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_comment_cb',$css);
 286  
 287      //strip (incorrect but common) one line comments
 288      $css = preg_replace('/(?<!:)\/\/.*$/m','',$css);
 289  
 290      // strip whitespaces
 291      $css = preg_replace('![\r\n\t ]+!',' ',$css);
 292      $css = preg_replace('/ ?([:;,{}\/]) ?/','\\1',$css);
 293  
 294      // shorten colors
 295      $css = preg_replace("/#([0-9a-fA-F]{1})\\1([0-9a-fA-F]{1})\\2([0-9a-fA-F]{1})\\3/", "#\\1\\2\\3",$css);
 296  
 297      return $css;
 298  }
 299  
 300  /**
 301   * Callback for css_compress()
 302   *
 303   * Keeps short comments (< 5 chars) to maintain typical browser hacks
 304   *
 305   * @author Andreas Gohr <andi@splitbrain.org>
 306   */
 307  function css_comment_cb($matches){
 308      if(strlen($matches[2]) > 4) return '';
 309      return $matches[0];
 310  }
 311  
 312  //Setup VIM: ex: et ts=4 enc=utf-8 :
 313  ?>


Generated: Wed Oct 1 01:30:01 2008 Cross-referenced by PHPXref 0.7