mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-19 00:28:47 +02:00
N°2435.2 Manage SCSSPHP lib using composer
This commit is contained in:
@@ -1528,7 +1528,6 @@ class utils
|
||||
clearstatcache();
|
||||
if (!file_exists($sCssPath) || (is_writable($sCssPath) && (filemtime($sCssPath) < filemtime($sSassPath))))
|
||||
{
|
||||
require_once(APPROOT.'lib/scssphp/scss.inc.php');
|
||||
$oScss = new Compiler();
|
||||
$oScss->setImportPaths($aImportPaths);
|
||||
$oScss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\Expanded');
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"ext-gd": "*",
|
||||
"ext-ctype": "*",
|
||||
|
||||
"scssphp/scssphp": "1.0.0",
|
||||
|
||||
"symfony/console": "3.4.*",
|
||||
"symfony/dotenv": "3.4.*",
|
||||
"symfony/framework-bundle": "3.4.*",
|
||||
|
||||
61
composer.lock
generated
61
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "41f51225471c2e18c3488910cdeabcf6",
|
||||
"content-hash": "b5e0d8a47b8f42ff3820b452900c2d90",
|
||||
"packages": [
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
@@ -245,6 +245,65 @@
|
||||
],
|
||||
"time": "2017-10-23T01:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "scssphp/scssphp",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/scssphp/scssphp.git",
|
||||
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/6c8734b6edcf6c2fa785ad874b998fa854a7d030",
|
||||
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0 || ^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.6",
|
||||
"squizlabs/php_codesniffer": "~2.5",
|
||||
"twbs/bootstrap": "~4.3",
|
||||
"zurb/foundation": "~6.5"
|
||||
},
|
||||
"bin": [
|
||||
"bin/pscss"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ScssPhp\\ScssPhp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anthon Pang",
|
||||
"email": "apang@softwaredevelopment.ca",
|
||||
"homepage": "https://github.com/robocoder"
|
||||
},
|
||||
{
|
||||
"name": "Cédric Morin",
|
||||
"email": "cedric@yterium.com",
|
||||
"homepage": "https://github.com/Cerdic"
|
||||
}
|
||||
],
|
||||
"description": "scssphp is a compiler for SCSS written in PHP.",
|
||||
"homepage": "http://scssphp.github.io/scssphp/",
|
||||
"keywords": [
|
||||
"css",
|
||||
"less",
|
||||
"sass",
|
||||
"scss",
|
||||
"stylesheet"
|
||||
],
|
||||
"time": "2019-06-05T01:22:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v3.4.30",
|
||||
|
||||
10
lib/bin/pscss
Normal file
10
lib/bin/pscss
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
dir=$(cd "${0%[/\\]*}" > /dev/null; cd "../scssphp/scssphp/bin" && pwd)
|
||||
|
||||
if [ -d /proc/cygdrive ] && [[ $(which php) == $(readlink -n /proc/cygdrive)/* ]]; then
|
||||
# We are in Cgywin using Windows php, so the path must be translated
|
||||
dir=$(cygpath -m "$dir");
|
||||
fi
|
||||
|
||||
"${dir}/pscss" "$@"
|
||||
4
lib/bin/pscss.bat
Normal file
4
lib/bin/pscss.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/../scssphp/scssphp/bin/pscss
|
||||
php "%BIN_TARGET%" %*
|
||||
@@ -381,6 +381,34 @@ return array(
|
||||
'SQLUnionQuery' => $baseDir . '/core/sqlunionquery.class.inc.php',
|
||||
'ScalarExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||
'ScalarOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'ScssPhp\\ScssPhp\\Base\\Range' => $vendorDir . '/scssphp/scssphp/src/Base/Range.php',
|
||||
'ScssPhp\\ScssPhp\\Block' => $vendorDir . '/scssphp/scssphp/src/Block.php',
|
||||
'ScssPhp\\ScssPhp\\Cache' => $vendorDir . '/scssphp/scssphp/src/Cache.php',
|
||||
'ScssPhp\\ScssPhp\\Colors' => $vendorDir . '/scssphp/scssphp/src/Colors.php',
|
||||
'ScssPhp\\ScssPhp\\Compiler' => $vendorDir . '/scssphp/scssphp/src/Compiler.php',
|
||||
'ScssPhp\\ScssPhp\\Compiler\\Environment' => $vendorDir . '/scssphp/scssphp/src/Compiler/Environment.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\CompilerException' => $vendorDir . '/scssphp/scssphp/src/Exception/CompilerException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\ParserException' => $vendorDir . '/scssphp/scssphp/src/Exception/ParserException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\RangeException' => $vendorDir . '/scssphp/scssphp/src/Exception/RangeException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\ServerException' => $vendorDir . '/scssphp/scssphp/src/Exception/ServerException.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter' => $vendorDir . '/scssphp/scssphp/src/Formatter.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Compact' => $vendorDir . '/scssphp/scssphp/src/Formatter/Compact.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Compressed' => $vendorDir . '/scssphp/scssphp/src/Formatter/Compressed.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Crunched' => $vendorDir . '/scssphp/scssphp/src/Formatter/Crunched.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Debug' => $vendorDir . '/scssphp/scssphp/src/Formatter/Debug.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Expanded' => $vendorDir . '/scssphp/scssphp/src/Formatter/Expanded.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Nested' => $vendorDir . '/scssphp/scssphp/src/Formatter/Nested.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\OutputBlock' => $vendorDir . '/scssphp/scssphp/src/Formatter/OutputBlock.php',
|
||||
'ScssPhp\\ScssPhp\\Node' => $vendorDir . '/scssphp/scssphp/src/Node.php',
|
||||
'ScssPhp\\ScssPhp\\Node\\Number' => $vendorDir . '/scssphp/scssphp/src/Node/Number.php',
|
||||
'ScssPhp\\ScssPhp\\Parser' => $vendorDir . '/scssphp/scssphp/src/Parser.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64' => $vendorDir . '/scssphp/scssphp/src/SourceMap/Base64.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64VLQ' => $vendorDir . '/scssphp/scssphp/src/SourceMap/Base64VLQ.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64VLQEncoder' => $vendorDir . '/scssphp/scssphp/src/SourceMap/Base64VLQEncoder.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\SourceMapGenerator' => $vendorDir . '/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php',
|
||||
'ScssPhp\\ScssPhp\\Type' => $vendorDir . '/scssphp/scssphp/src/Type.php',
|
||||
'ScssPhp\\ScssPhp\\Util' => $vendorDir . '/scssphp/scssphp/src/Util.php',
|
||||
'ScssPhp\\ScssPhp\\Version' => $vendorDir . '/scssphp/scssphp/src/Version.php',
|
||||
'SearchMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'SecurityException' => $baseDir . '/core/coreexception.class.inc.php',
|
||||
'SeparatorPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php',
|
||||
|
||||
@@ -31,6 +31,7 @@ return array(
|
||||
'Symfony\\Bundle\\TwigBundle\\' => array($vendorDir . '/symfony/twig-bundle'),
|
||||
'Symfony\\Bundle\\FrameworkBundle\\' => array($vendorDir . '/symfony/framework-bundle'),
|
||||
'Symfony\\Bridge\\Twig\\' => array($vendorDir . '/symfony/twig-bridge'),
|
||||
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
|
||||
@@ -46,6 +46,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Symfony\\Bundle\\TwigBundle\\' => 26,
|
||||
'Symfony\\Bundle\\FrameworkBundle\\' => 31,
|
||||
'Symfony\\Bridge\\Twig\\' => 20,
|
||||
'ScssPhp\\ScssPhp\\' => 16,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
@@ -157,6 +158,10 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/twig-bridge',
|
||||
),
|
||||
'ScssPhp\\ScssPhp\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
|
||||
),
|
||||
'Psr\\SimpleCache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
|
||||
@@ -561,6 +566,34 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'SQLUnionQuery' => __DIR__ . '/../..' . '/core/sqlunionquery.class.inc.php',
|
||||
'ScalarExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||
'ScalarOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'ScssPhp\\ScssPhp\\Base\\Range' => __DIR__ . '/..' . '/scssphp/scssphp/src/Base/Range.php',
|
||||
'ScssPhp\\ScssPhp\\Block' => __DIR__ . '/..' . '/scssphp/scssphp/src/Block.php',
|
||||
'ScssPhp\\ScssPhp\\Cache' => __DIR__ . '/..' . '/scssphp/scssphp/src/Cache.php',
|
||||
'ScssPhp\\ScssPhp\\Colors' => __DIR__ . '/..' . '/scssphp/scssphp/src/Colors.php',
|
||||
'ScssPhp\\ScssPhp\\Compiler' => __DIR__ . '/..' . '/scssphp/scssphp/src/Compiler.php',
|
||||
'ScssPhp\\ScssPhp\\Compiler\\Environment' => __DIR__ . '/..' . '/scssphp/scssphp/src/Compiler/Environment.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\CompilerException' => __DIR__ . '/..' . '/scssphp/scssphp/src/Exception/CompilerException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\ParserException' => __DIR__ . '/..' . '/scssphp/scssphp/src/Exception/ParserException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\RangeException' => __DIR__ . '/..' . '/scssphp/scssphp/src/Exception/RangeException.php',
|
||||
'ScssPhp\\ScssPhp\\Exception\\ServerException' => __DIR__ . '/..' . '/scssphp/scssphp/src/Exception/ServerException.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Compact' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Compact.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Compressed' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Compressed.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Crunched' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Crunched.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Debug' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Debug.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Expanded' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Expanded.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\Nested' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/Nested.php',
|
||||
'ScssPhp\\ScssPhp\\Formatter\\OutputBlock' => __DIR__ . '/..' . '/scssphp/scssphp/src/Formatter/OutputBlock.php',
|
||||
'ScssPhp\\ScssPhp\\Node' => __DIR__ . '/..' . '/scssphp/scssphp/src/Node.php',
|
||||
'ScssPhp\\ScssPhp\\Node\\Number' => __DIR__ . '/..' . '/scssphp/scssphp/src/Node/Number.php',
|
||||
'ScssPhp\\ScssPhp\\Parser' => __DIR__ . '/..' . '/scssphp/scssphp/src/Parser.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64' => __DIR__ . '/..' . '/scssphp/scssphp/src/SourceMap/Base64.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64VLQ' => __DIR__ . '/..' . '/scssphp/scssphp/src/SourceMap/Base64VLQ.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\Base64VLQEncoder' => __DIR__ . '/..' . '/scssphp/scssphp/src/SourceMap/Base64VLQEncoder.php',
|
||||
'ScssPhp\\ScssPhp\\SourceMap\\SourceMapGenerator' => __DIR__ . '/..' . '/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php',
|
||||
'ScssPhp\\ScssPhp\\Type' => __DIR__ . '/..' . '/scssphp/scssphp/src/Type.php',
|
||||
'ScssPhp\\ScssPhp\\Util' => __DIR__ . '/..' . '/scssphp/scssphp/src/Util.php',
|
||||
'ScssPhp\\ScssPhp\\Version' => __DIR__ . '/..' . '/scssphp/scssphp/src/Version.php',
|
||||
'SearchMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'SecurityException' => __DIR__ . '/../..' . '/core/coreexception.class.inc.php',
|
||||
'SeparatorPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
|
||||
@@ -248,6 +248,67 @@
|
||||
"simple-cache"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scssphp/scssphp",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/scssphp/scssphp.git",
|
||||
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/6c8734b6edcf6c2fa785ad874b998fa854a7d030",
|
||||
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0 || ^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.6",
|
||||
"squizlabs/php_codesniffer": "~2.5",
|
||||
"twbs/bootstrap": "~4.3",
|
||||
"zurb/foundation": "~6.5"
|
||||
},
|
||||
"time": "2019-06-05T01:22:01+00:00",
|
||||
"bin": [
|
||||
"bin/pscss"
|
||||
],
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ScssPhp\\ScssPhp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anthon Pang",
|
||||
"email": "apang@softwaredevelopment.ca",
|
||||
"homepage": "https://github.com/robocoder"
|
||||
},
|
||||
{
|
||||
"name": "Cédric Morin",
|
||||
"email": "cedric@yterium.com",
|
||||
"homepage": "https://github.com/Cerdic"
|
||||
}
|
||||
],
|
||||
"description": "scssphp is a compiler for SCSS written in PHP.",
|
||||
"homepage": "http://scssphp.github.io/scssphp/",
|
||||
"keywords": [
|
||||
"css",
|
||||
"less",
|
||||
"sass",
|
||||
"scss",
|
||||
"stylesheet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v3.4.30",
|
||||
|
||||
0
lib/scssphp/bin/pscss → lib/scssphp/scssphp/bin/pscss
Executable file → Normal file
0
lib/scssphp/bin/pscss → lib/scssphp/scssphp/bin/pscss
Executable file → Normal file
48
lib/scssphp/scssphp/composer.json
Normal file
48
lib/scssphp/scssphp/composer.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "scssphp/scssphp",
|
||||
"type": "library",
|
||||
"description": "scssphp is a compiler for SCSS written in PHP.",
|
||||
"keywords": ["css", "stylesheet", "scss", "sass", "less"],
|
||||
"homepage": "http://scssphp.github.io/scssphp/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anthon Pang",
|
||||
"email": "apang@softwaredevelopment.ca",
|
||||
"homepage": "https://github.com/robocoder"
|
||||
},
|
||||
{
|
||||
"name": "Cédric Morin",
|
||||
"email": "cedric@yterium.com",
|
||||
"homepage": "https://github.com/Cerdic"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": { "ScssPhp\\ScssPhp\\": "src/" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "ScssPhp\\ScssPhp\\Test\\": "tests/" }
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0 || ^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"squizlabs/php_codesniffer": "~2.5",
|
||||
"phpunit/phpunit": "~4.6",
|
||||
"twbs/bootstrap": "~4.3",
|
||||
"zurb/foundation": "~6.5"
|
||||
},
|
||||
"bin": ["bin/pscss"],
|
||||
"archive": {
|
||||
"exclude": [
|
||||
"/Makefile",
|
||||
"/.gitattributes",
|
||||
"/.gitignore",
|
||||
"/.travis.yml",
|
||||
"/phpunit.xml.dist",
|
||||
"/tests"
|
||||
]
|
||||
}
|
||||
}
|
||||
515
lib/scssphp/scssphp/example/Server.php
Normal file
515
lib/scssphp/scssphp/example/Server.php
Normal file
@@ -0,0 +1,515 @@
|
||||
<?php
|
||||
/**
|
||||
* SCSSPHP
|
||||
*
|
||||
* @copyright 2012-2019 Leaf Corcoran
|
||||
*
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*
|
||||
* @link http://scssphp.github.io/scssphp
|
||||
*/
|
||||
|
||||
namespace ScssPhp\ScssPhp;
|
||||
|
||||
use ScssPhp\ScssPhp\Compiler;
|
||||
use ScssPhp\ScssPhp\Exception\ServerException;
|
||||
use ScssPhp\ScssPhp\Version;
|
||||
|
||||
/**
|
||||
* Server
|
||||
*
|
||||
* @author Leaf Corcoran <leafot@gmail.com>
|
||||
*/
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $showErrorsAsCSS;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheDir;
|
||||
|
||||
/**
|
||||
* @var \ScssPhp\ScssPhp\Compiler
|
||||
*/
|
||||
private $scss;
|
||||
|
||||
/**
|
||||
* Join path components
|
||||
*
|
||||
* @param string $left Path component, left of the directory separator
|
||||
* @param string $right Path component, right of the directory separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function join($left, $right)
|
||||
{
|
||||
return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of requested .scss file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function inputName()
|
||||
{
|
||||
switch (true) {
|
||||
case isset($_GET['p']):
|
||||
return $_GET['p'];
|
||||
case isset($_SERVER['PATH_INFO']):
|
||||
return $_SERVER['PATH_INFO'];
|
||||
case isset($_SERVER['DOCUMENT_URI']):
|
||||
return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to requested .scss file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function findInput()
|
||||
{
|
||||
if (($input = $this->inputName())
|
||||
&& strpos($input, '..') === false
|
||||
&& substr($input, -5) === '.scss'
|
||||
) {
|
||||
$name = $this->join($this->dir, $input);
|
||||
|
||||
if (is_file($name) && is_readable($name)) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to cached .css file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function cacheName($fname)
|
||||
{
|
||||
return $this->join($this->cacheDir, md5($fname) . '.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to meta data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function metadataName($out)
|
||||
{
|
||||
return $out . '.meta';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether .scss file needs to be re-compiled.
|
||||
*
|
||||
* @param string $out Output path
|
||||
* @param string $etag ETag
|
||||
*
|
||||
* @return boolean True if compile required.
|
||||
*/
|
||||
protected function needsCompile($out, &$etag)
|
||||
{
|
||||
if (! is_file($out)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$mtime = filemtime($out);
|
||||
|
||||
$metadataName = $this->metadataName($out);
|
||||
|
||||
if (is_readable($metadataName)) {
|
||||
$metadata = unserialize(file_get_contents($metadataName));
|
||||
|
||||
foreach ($metadata['imports'] as $import => $originalMtime) {
|
||||
$currentMtime = filemtime($import);
|
||||
|
||||
if ($currentMtime !== $originalMtime || $currentMtime > $mtime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$metaVars = crc32(serialize($this->scss->getVariables()));
|
||||
|
||||
if ($metaVars !== $metadata['vars']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$etag = $metadata['etag'];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get If-Modified-Since header from client request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getIfModifiedSinceHeader()
|
||||
{
|
||||
$modifiedSince = null;
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
$modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
||||
|
||||
if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
|
||||
$modifiedSince = substr($modifiedSince, 0, $semicolonPos);
|
||||
}
|
||||
}
|
||||
|
||||
return $modifiedSince;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get If-None-Match header from client request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getIfNoneMatchHeader()
|
||||
{
|
||||
$noneMatch = null;
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
$noneMatch = $_SERVER['HTTP_IF_NONE_MATCH'];
|
||||
}
|
||||
|
||||
return $noneMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile .scss file
|
||||
*
|
||||
* @param string $in Input path (.scss)
|
||||
* @param string $out Output path (.css)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function compile($in, $out)
|
||||
{
|
||||
$start = microtime(true);
|
||||
$css = $this->scss->compile(file_get_contents($in), $in);
|
||||
$elapsed = round((microtime(true) - $start), 4);
|
||||
|
||||
$v = Version::VERSION;
|
||||
$t = gmdate('r');
|
||||
$css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
|
||||
$etag = md5($css);
|
||||
|
||||
file_put_contents($out, $css);
|
||||
file_put_contents(
|
||||
$this->metadataName($out),
|
||||
serialize([
|
||||
'etag' => $etag,
|
||||
'imports' => $this->scss->getParsedFiles(),
|
||||
'vars' => crc32(serialize($this->scss->getVariables())),
|
||||
])
|
||||
);
|
||||
|
||||
return [$css, $etag];
|
||||
}
|
||||
|
||||
/**
|
||||
* Format error as a pseudo-element in CSS
|
||||
*
|
||||
* @param \Exception $error
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function createErrorCSS(\Exception $error)
|
||||
{
|
||||
$message = str_replace(
|
||||
["'", "\n"],
|
||||
["\\'", "\\A"],
|
||||
$error->getfile() . ":\n\n" . $error->getMessage()
|
||||
);
|
||||
|
||||
return "body { display: none !important; }
|
||||
html:after {
|
||||
background: white;
|
||||
color: black;
|
||||
content: '$message';
|
||||
display: block !important;
|
||||
font-family: mono;
|
||||
padding: 1em;
|
||||
white-space: pre;
|
||||
}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Render errors as a pseudo-element within valid CSS, displaying the errors on any
|
||||
* page that includes this CSS.
|
||||
*
|
||||
* @param boolean $show
|
||||
*/
|
||||
public function showErrorsAsCSS($show = true)
|
||||
{
|
||||
$this->showErrorsAsCSS = $show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile .scss file
|
||||
*
|
||||
* @param string $in Input file (.scss)
|
||||
* @param string $out Output file (.css) optional
|
||||
*
|
||||
* @return string|bool
|
||||
*
|
||||
* @throws \ScssPhp\ScssPhp\Exception\ServerException
|
||||
*/
|
||||
public function compileFile($in, $out = null)
|
||||
{
|
||||
if (! is_readable($in)) {
|
||||
throw new ServerException('load error: failed to find ' . $in);
|
||||
}
|
||||
|
||||
$pi = pathinfo($in);
|
||||
|
||||
$this->scss->addImportPath($pi['dirname'] . '/');
|
||||
|
||||
$compiled = $this->scss->compile(file_get_contents($in), $in);
|
||||
|
||||
if ($out !== null) {
|
||||
return file_put_contents($out, $compiled);
|
||||
}
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file need compiling
|
||||
*
|
||||
* @param string $in Input file (.scss)
|
||||
* @param string $out Output file (.css)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkedCompile($in, $out)
|
||||
{
|
||||
if (! is_file($out) || filemtime($in) > filemtime($out)) {
|
||||
$this->compileFile($in, $out);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile requested scss and serve css. Outputs HTTP response.
|
||||
*
|
||||
* @param string $salt Prefix a string to the filename for creating the cache name hash
|
||||
*/
|
||||
public function serve($salt = '')
|
||||
{
|
||||
$protocol = isset($_SERVER['SERVER_PROTOCOL'])
|
||||
? $_SERVER['SERVER_PROTOCOL']
|
||||
: 'HTTP/1.0';
|
||||
|
||||
if ($input = $this->findInput()) {
|
||||
$output = $this->cacheName($salt . $input);
|
||||
$etag = $noneMatch = trim($this->getIfNoneMatchHeader(), '"');
|
||||
|
||||
if ($this->needsCompile($output, $etag)) {
|
||||
try {
|
||||
list($css, $etag) = $this->compile($input, $output);
|
||||
|
||||
$lastModified = gmdate('r', filemtime($output));
|
||||
|
||||
header('Last-Modified: ' . $lastModified);
|
||||
header('Content-type: text/css');
|
||||
header('ETag: "' . $etag . '"');
|
||||
|
||||
echo $css;
|
||||
} catch (\Exception $e) {
|
||||
if ($this->showErrorsAsCSS) {
|
||||
header('Content-type: text/css');
|
||||
|
||||
echo $this->createErrorCSS($e);
|
||||
} else {
|
||||
header($protocol . ' 500 Internal Server Error');
|
||||
header('Content-type: text/plain');
|
||||
|
||||
echo 'Parse error: ' . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
header('X-SCSS-Cache: true');
|
||||
header('Content-type: text/css');
|
||||
header('ETag: "' . $etag . '"');
|
||||
|
||||
if ($etag === $noneMatch) {
|
||||
header($protocol . ' 304 Not Modified');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$modifiedSince = $this->getIfModifiedSinceHeader();
|
||||
$mtime = filemtime($output);
|
||||
|
||||
if (strtotime($modifiedSince) === $mtime) {
|
||||
header($protocol . ' 304 Not Modified');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$lastModified = gmdate('r', $mtime);
|
||||
header('Last-Modified: ' . $lastModified);
|
||||
|
||||
echo file_get_contents($output);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
header($protocol . ' 404 Not Found');
|
||||
header('Content-type: text/plain');
|
||||
|
||||
$v = Version::VERSION;
|
||||
echo "/* INPUT NOT FOUND scss $v */\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on explicit input/output files does a full change check on cache before compiling.
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $out
|
||||
* @param boolean $force
|
||||
*
|
||||
* @return string Compiled CSS results
|
||||
*
|
||||
* @throws \ScssPhp\ScssPhp\Exception\ServerException
|
||||
*/
|
||||
public function checkedCachedCompile($in, $out, $force = false)
|
||||
{
|
||||
if (! is_file($in) || ! is_readable($in)) {
|
||||
throw new ServerException('Invalid or unreadable input file specified.');
|
||||
}
|
||||
|
||||
if (is_dir($out) || ! is_writable(file_exists($out) ? $out : dirname($out))) {
|
||||
throw new ServerException('Invalid or unwritable output file specified.');
|
||||
}
|
||||
|
||||
if ($force || $this->needsCompile($out, $etag)) {
|
||||
list($css, $etag) = $this->compile($in, $out);
|
||||
} else {
|
||||
$css = file_get_contents($out);
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute scssphp on a .scss file or a scssphp cache structure
|
||||
*
|
||||
* The scssphp cache structure contains information about a specific
|
||||
* scss file having been parsed. It can be used as a hint for future
|
||||
* calls to determine whether or not a rebuild is required.
|
||||
*
|
||||
* The cache structure contains two important keys that may be used
|
||||
* externally:
|
||||
*
|
||||
* compiled: The final compiled CSS
|
||||
* updated: The time (in seconds) the CSS was last compiled
|
||||
*
|
||||
* The cache structure is a plain-ol' PHP associative array and can
|
||||
* be serialized and unserialized without a hitch.
|
||||
*
|
||||
* @param mixed $in Input
|
||||
* @param boolean $force Force rebuild?
|
||||
*
|
||||
* @return array scssphp cache structure
|
||||
*/
|
||||
public function cachedCompile($in, $force = false)
|
||||
{
|
||||
// assume no root
|
||||
$root = null;
|
||||
|
||||
if (is_string($in)) {
|
||||
$root = $in;
|
||||
} elseif (is_array($in) and isset($in['root'])) {
|
||||
if ($force or ! isset($in['files'])) {
|
||||
// If we are forcing a recompile or if for some reason the
|
||||
// structure does not contain any file information we should
|
||||
// specify the root to trigger a rebuild.
|
||||
$root = $in['root'];
|
||||
} elseif (isset($in['files']) and is_array($in['files'])) {
|
||||
foreach ($in['files'] as $fname => $ftime) {
|
||||
if (! file_exists($fname) or filemtime($fname) > $ftime) {
|
||||
// One of the files we knew about previously has changed
|
||||
// so we should look at our incoming root again.
|
||||
$root = $in['root'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO: Throw an exception? We got neither a string nor something
|
||||
// that looks like a compatible lessphp cache structure.
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($root !== null) {
|
||||
// If we have a root value which means we should rebuild.
|
||||
$out = [];
|
||||
$out['root'] = $root;
|
||||
$out['compiled'] = $this->compileFile($root);
|
||||
$out['files'] = $this->scss->getParsedFiles();
|
||||
$out['updated'] = time();
|
||||
return $out;
|
||||
} else {
|
||||
// No changes, pass back the structure
|
||||
// we were given initially.
|
||||
return $in;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $dir Root directory to .scss files
|
||||
* @param string $cacheDir Cache directory
|
||||
* @param \ScssPhp\ScssPhp\Compiler|null $scss SCSS compiler instance
|
||||
*/
|
||||
public function __construct($dir, $cacheDir = null, $scss = null)
|
||||
{
|
||||
$this->dir = $dir;
|
||||
|
||||
if (! isset($cacheDir)) {
|
||||
$cacheDir = $this->join($dir, 'scss_cache');
|
||||
}
|
||||
|
||||
$this->cacheDir = $cacheDir;
|
||||
|
||||
if (! is_dir($this->cacheDir)) {
|
||||
throw new ServerException('Cache directory doesn\'t exist: ' . $cacheDir);
|
||||
}
|
||||
|
||||
if (! isset($scss)) {
|
||||
$scss = new Compiler();
|
||||
$scss->setImportPaths($this->dir);
|
||||
}
|
||||
|
||||
$this->scss = $scss;
|
||||
$this->showErrorsAsCSS = false;
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user