PluginProbe
GetResponse Forms by Optin Cat / 1.5.4
GetResponse Forms by Optin Cat v1.5.4
1.3.4 1.3.5 1.3.6 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 2.0.0 All 36 releases
getresponse / includes / classes / scssphp / src / Server.php

Server.php in GetResponse Forms by Optin Cat 1.5.4, at includes/classes/scssphp/src/Server.php

316 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * SCSSPHP
4 *
5 * @copyright 2012-2014 Leaf Corcoran
6 *
7 * @license http://opensource.org/licenses/gpl-license GPL-3.0
8 * @license http://opensource.org/licenses/MIT MIT
9 *
10 * @link http://leafo.net/scssphp
11 */
12
13 namespace Leafo\ScssPhp;
14
15 use Leafo\ScssPhp\Compiler;
16
17 /**
18 * SCSS server
19 *
20 * @author Leaf Corcoran <leafot@gmail.com>
21 */
22 class Server
23 {
24 /**
25 * Join path components
26 *
27 * @param string $left Path component, left of the directory separator
28 * @param string $right Path component, right of the directory separator
29 *
30 * @return string
31 */
32 protected function join($left, $right)
33 {
34 return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
35 }
36
37 /**
38 * Get name of requested .scss file
39 *
40 * @return string|null
41 */
42 protected function inputName()
43 {
44 switch (true) {
45 case isset($_GET['p']):
46 return $_GET['p'];
47 case isset($_SERVER['PATH_INFO']):
48 return $_SERVER['PATH_INFO'];
49 case isset($_SERVER['DOCUMENT_URI']):
50 return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
51 }
52 }
53
54 /**
55 * Get path to requested .scss file
56 *
57 * @return string
58 */
59 protected function findInput()
60 {
61 if (($input = $this->inputName())
62 && strpos($input, '..') === false
63 && substr($input, -5) === '.scss'
64 ) {
65 $name = $this->join($this->dir, $input);
66
67 if (is_file($name) && is_readable($name)) {
68 return $name;
69 }
70 }
71
72 return false;
73 }
74
75 /**
76 * Get path to cached .css file
77 *
78 * @return string
79 */
80 protected function cacheName($fname)
81 {
82 return $this->join($this->cacheDir, md5($fname) . '.css');
83 }
84
85 /**
86 * Get path to meta data
87 *
88 * @return string
89 */
90 protected function metadataName($out)
91 {
92 return $out . '.meta';
93 }
94
95 /**
96 * Determine whether .scss file needs to be re-compiled.
97 *
98 * @param string $in Input path
99 * @param string $out Output path
100 * @param string $etag ETag
101 *
102 * @return boolean True if compile required.
103 */
104 protected function needsCompile($in, $out, &$etag)
105 {
106 if (! is_file($out)) {
107 return true;
108 }
109
110 $mtime = filemtime($out);
111
112 if (filemtime($in) > $mtime) {
113 return true;
114 }
115
116 $metadataName = $this->metadataName($out);
117
118 if (is_readable($metadataName)) {
119 $metadata = unserialize(file_get_contents($metadataName));
120
121 if ($metadata['etag'] === $etag) {
122 return false;
123 }
124
125 foreach ($metadata['imports'] as $import) {
126 if (filemtime($import) > $mtime) {
127 return true;
128 }
129 }
130
131 $etag = $metadata['etag'];
132
133 return false;
134 }
135
136 return true;
137 }
138
139 /**
140 * Get If-Modified-Since header from client request
141 *
142 * @return string|null
143 */
144 protected function getIfModifiedSinceHeader()
145 {
146 $modifiedSince = null;
147
148 if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
149 $modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
150
151 if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
152 $modifiedSince = substr($modifiedSince, 0, $semicolonPos);
153 }
154 }
155
156 return $modifiedSince;
157 }
158
159 /**
160 * Get If-None-Match header from client request
161 *
162 * @return string|null
163 */
164 protected function getIfNoneMatchHeader()
165 {
166 $noneMatch = null;
167
168 if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
169 $noneMatch = $_SERVER['HTTP_IF_NONE_MATCH'];
170 }
171
172 return $noneMatch;
173 }
174
175 /**
176 * Compile .scss file
177 *
178 * @param string $in Input path (.scss)
179 * @param string $out Output path (.css)
180 *
181 * @return array
182 */
183 protected function compile($in, $out)
184 {
185 $start = microtime(true);
186 $css = $this->scss->compile(file_get_contents($in), $in);
187 $elapsed = round((microtime(true) - $start), 4);
188
189 $v = Compiler::$VERSION;
190 $t = @date('r');
191 $css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
192 $etag = md5($css);
193
194 file_put_contents($out, $css);
195 file_put_contents(
196 $this->metadataName($out),
197 serialize(array(
198 'etag' => $etag,
199 'imports' => $this->scss->getParsedFiles(),
200 ))
201 );
202
203 return array($css, $etag);
204 }
205
206 /**
207 * Compile requested scss and serve css. Outputs HTTP response.
208 *
209 * @param string $salt Prefix a string to the filename for creating the cache name hash
210 */
211 public function serve($salt = '')
212 {
213 $protocol = isset($_SERVER['SERVER_PROTOCOL'])
214 ? $_SERVER['SERVER_PROTOCOL']
215 : 'HTTP/1.0';
216
217 if ($input = $this->findInput()) {
218 $output = $this->cacheName($salt . $input);
219 $etag = $noneMatch = trim($this->getIfNoneMatchHeader(), '"');
220
221 if ($this->needsCompile($input, $output, $etag)) {
222 try {
223 list($css, $etag) = $this->compile($input, $output);
224
225 $lastModified = gmdate('D, d M Y H:i:s', filemtime($output)) . ' GMT';
226
227 header('Last-Modified: ' . $lastModified);
228 header('Content-type: text/css');
229 header('ETag: "' . $etag . '"');
230
231 echo $css;
232
233 return;
234 } catch (\Exception $e) {
235 header($protocol . ' 500 Internal Server Error');
236 header('Content-type: text/plain');
237
238 echo 'Parse error: ' . $e->getMessage() . "\n";
239 }
240 }
241
242 header('X-SCSS-Cache: true');
243 header('Content-type: text/css');
244 header('ETag: "' . $etag . '"');
245
246 if ($etag === $noneMatch) {
247 header($protocol . ' 304 Not Modified');
248
249 return;
250 }
251
252 $modifiedSince = $this->getIfModifiedSinceHeader();
253 $mtime = filemtime($output);
254
255 if (@strtotime($modifiedSince) === $mtime) {
256 header($protocol . ' 304 Not Modified');
257
258 return;
259 }
260
261 $lastModified = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
262 header('Last-Modified: ' . $lastModified);
263
264 echo file_get_contents($output);
265
266 return;
267 }
268
269 header($protocol . ' 404 Not Found');
270 header('Content-type: text/plain');
271
272 $v = Compiler::$VERSION;
273 echo "/* INPUT NOT FOUND scss $v */\n";
274 }
275
276 /**
277 * Constructor
278 *
279 * @param string $dir Root directory to .scss files
280 * @param string $cacheDir Cache directory
281 * @param \Leafo\ScssPhp\Compiler|null $scss SCSS compiler instance
282 */
283 public function __construct($dir, $cacheDir = null, $scss = null)
284 {
285 $this->dir = $dir;
286
287 if (!isset($cacheDir)) {
288 $cacheDir = $this->join($dir, 'scss_cache');
289 }
290
291 $this->cacheDir = $cacheDir;
292
293 if (!is_dir($this->cacheDir)) {
294 mkdir($this->cacheDir, 0755, true);
295 }
296
297 if (!isset($scss)) {
298 $scss = new Compiler();
299 $scss->setImportPaths($this->dir);
300 }
301
302 $this->scss = $scss;
303 }
304
305 /**
306 * Helper method to serve compiled scss
307 *
308 * @param string $path Root path
309 */
310 public static function serveFrom($path)
311 {
312 $server = new self($path);
313 $server->serve();
314 }
315 }
316