scss_server

SCSS server.

Defined (1)

The class is defined in the following location(s).

/library/admin/redux-framework/inc/scssphp/scss.inc.php  
  1. class scss_server { 
  2. /** 
  3. * Join path components 
  4. * @param string $left Path component, left of the directory separator 
  5. * @param string $right Path component, right of the directory separator 
  6. * @return string 
  7. */ 
  8. protected function join($left, $right) { 
  9. return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\'); 
  10.  
  11. /** 
  12. * Get name of requested .scss file 
  13. * @return string|null 
  14. */ 
  15. protected function inputName() { 
  16. switch (true) { 
  17. case isset($_GET['p']): 
  18. return $_GET['p']; 
  19. case isset($_SERVER['PATH_INFO']): 
  20. return $_SERVER['PATH_INFO']; 
  21. case isset($_SERVER['DOCUMENT_URI']): 
  22. return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME'])); 
  23.  
  24. /** 
  25. * Get path to requested .scss file 
  26. * @return string 
  27. */ 
  28. protected function findInput() { 
  29. if (($input = $this->inputName()) 
  30. && strpos($input, '..') === false 
  31. && substr($input, -5) === '.scss' 
  32. ) { 
  33. $name = $this->join($this->dir, $input); 
  34.  
  35. if (is_file($name) && is_readable($name)) { 
  36. return $name; 
  37.  
  38. return false; 
  39.  
  40. /** 
  41. * Get path to cached .css file 
  42. * @return string 
  43. */ 
  44. protected function cacheName($fname) { 
  45. return $this->join($this->cacheDir, md5($fname) . '.css'); 
  46.  
  47. /** 
  48. * Get path to cached imports 
  49. * @return string 
  50. */ 
  51. protected function importsCacheName($out) { 
  52. return $out . '.imports'; 
  53.  
  54. /** 
  55. * Determine whether .scss file needs to be re-compiled. 
  56. * @param string $in Input path 
  57. * @param string $out Output path 
  58. * @return boolean True if compile required. 
  59. */ 
  60. protected function needsCompile($in, $out) { 
  61. if (!is_file($out)) return true; 
  62.  
  63. $mtime = filemtime($out); 
  64. if (filemtime($in) > $mtime) return true; 
  65.  
  66. // look for modified imports 
  67. $icache = $this->importsCacheName($out); 
  68. if (is_readable($icache)) { 
  69. $imports = unserialize( self::$parent->filesystem->execute( 'get_contents', $icache )); 
  70. //$imports = unserialize(file_get_contents($icache)); 
  71. foreach ($imports as $import) { 
  72. if (filemtime($import) > $mtime) return true; 
  73. return false; 
  74.  
  75. /** 
  76. * Get If-Modified-Since header from client request 
  77. * @return string 
  78. */ 
  79. protected function getModifiedSinceHeader() 
  80. $modifiedSince = ''; 
  81.  
  82. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 
  83. $modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE']; 
  84.  
  85. if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) { 
  86. $modifiedSince = substr($modifiedSince, 0, $semicolonPos); 
  87.  
  88. return $modifiedSince; 
  89.  
  90. /** 
  91. * Compile .scss file 
  92. * @param string $in Input path (.scss) 
  93. * @param string $out Output path (.css) 
  94. * @return string 
  95. */ 
  96. protected function compile($in, $out) { 
  97. $start = microtime(true); 
  98.  
  99. $css = $this->scss->compile(self::$parent->filesystem->execute( 'get_contents', $in ), $in); 
  100. //$css = $this->scss->compile(file_get_contents($in), $in); 
  101. $elapsed = round((microtime(true) - $start), 4); 
  102.  
  103. $v = scssc::$VERSION; 
  104. $t = @date('r'); 
  105. $css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css; 
  106.  
  107. self::$parent->filesystem->execute( 'put_contents', $out, array('content'=>$css) ); 
  108. self::$parent->filesystem->execute( 'put_contents', $this->importsCacheName($out), array('content'=>serialize($this->scss->getParsedFiles())) ); 
  109. //file_put_contents($out, $css); 
  110. //file_put_contents($this->importsCacheName($out),  
  111. // serialize($this->scss->getParsedFiles())); 
  112. return $css; 
  113.  
  114. /** 
  115. * Compile requested scss and serve css. Outputs HTTP response. 
  116. * @param string $salt Prefix a string to the filename for creating the cache name hash 
  117. */ 
  118. public function serve($salt = '') { 
  119. $protocol = isset($_SERVER['SERVER_PROTOCOL']) 
  120. ? $_SERVER['SERVER_PROTOCOL'] 
  121. : 'HTTP/1.0'; 
  122.  
  123. if ($input = $this->findInput()) { 
  124. $output = $this->cacheName($salt . $input); 
  125.  
  126. if ($this->needsCompile($input, $output)) { 
  127. try { 
  128. $css = $this->compile($input, $output); 
  129.  
  130. $lastModified = gmdate('D, d M Y H:i:s', filemtime($output)) . ' GMT'; 
  131.  
  132. header('Last-Modified: ' . $lastModified); 
  133. header('Content-type: text/css'); 
  134.  
  135. echo $css; 
  136.  
  137. return; 
  138. } catch (Exception $e) { 
  139. header($protocol . ' 500 Internal Server Error'); 
  140. header('Content-type: text/plain'); 
  141.  
  142. echo 'Parse error: ' . $e->getMessage() . "\n"; 
  143.  
  144. header('X-SCSS-Cache: true'); 
  145. header('Content-type: text/css'); 
  146.  
  147. $modifiedSince = $this->getModifiedSinceHeader(); 
  148. $mtime = filemtime($output); 
  149.  
  150. if (@strtotime($modifiedSince) === $mtime) { 
  151. header($protocol . ' 304 Not Modified'); 
  152.  
  153. return; 
  154.  
  155. $lastModified = gmdate('D, d M Y H:i:s', $mtime) . ' GMT'; 
  156. header('Last-Modified: ' . $lastModified); 
  157.  
  158. echo self::$parent->filesystem->execute( 'get_contents', $output ); 
  159. //echo file_get_contents($output); 
  160.  
  161. return; 
  162.  
  163. header($protocol . ' 404 Not Found'); 
  164. header('Content-type: text/plain'); 
  165.  
  166. $v = scssc::$VERSION; 
  167. echo "/* INPUT NOT FOUND scss $v */\n"; 
  168.  
  169. /** 
  170. * Constructor 
  171. * @param string $dir Root directory to .scss files 
  172. * @param string $cacheDir Cache directory 
  173. * @param \scssc|null $scss SCSS compiler instance 
  174. */ 
  175. public function __construct($dir, $cacheDir=null, $scss=null) { 
  176. $this->dir = $dir; 
  177.  
  178. if (!isset($cacheDir)) { 
  179. $cacheDir = $this->join($dir, 'scss_cache'); 
  180.  
  181. $this->cacheDir = $cacheDir; 
  182. if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true); 
  183.  
  184. if (!isset($scss)) { 
  185. $scss = new scssc(); 
  186. $scss->setImportPaths($this->dir); 
  187. $this->scss = $scss; 
  188.  
  189. /** 
  190. * Helper method to serve compiled scss 
  191. * @param string $path Root path 
  192. */ 
  193. static public function serveFrom($path) { 
  194. $server = new self($path); 
  195. $server->serve();