From 4658220b2dc43c6a6c561afd2668bcd17cbd9ca5 Mon Sep 17 00:00:00 2001 From: Cameron Ball Date: Thu, 8 Feb 2018 13:32:04 +0800 Subject: [PATCH] MDL-61394 Administration: Add experimental feature to use SassC --- admin/settings/development.php | 2 ++ lang/en/admin.php | 2 ++ lib/classes/scss.php | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/admin/settings/development.php b/admin/settings/development.php index 80a804767df..e31a4542903 100644 --- a/admin/settings/development.php +++ b/admin/settings/development.php @@ -14,6 +14,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page $temp->add(new admin_setting_configcheckbox('dndallowtextandlinks', new lang_string('dndallowtextandlinks', 'admin'), new lang_string('configdndallowtextandlinks', 'admin'), 0)); + $temp->add(new admin_setting_configexecutable('pathtosassc', new lang_string('pathtosassc', 'admin'), new lang_string('pathtosassc_help', 'admin'), null)); + $ADMIN->add('experimental', $temp); // "debugging" settingpage diff --git a/lang/en/admin.php b/lang/en/admin.php index 4a49dd73aab..eb6030da540 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -837,6 +837,8 @@ $string['pathtopsqldesc'] = 'This is only necessary to enter if you have more th $string['pathtopsqlinvalid'] = 'Invalid path to psql - either wrong path or not executable'; $string['pathtopython'] = 'Path to Python'; $string['pathtopythondesc'] = 'Path to your executable Python binary (both Python 2 and Python 3 are acceptable).'; +$string['pathtosassc'] = 'Path to SassC'; +$string['pathtosassc_help'] = 'Specifying the location of the SassC binary will switch the SASS compiler from Moodle\'s PHP implementation to SassC. See https://github.com/sass/sassc for more information.'; $string['pcreunicodewarning'] = 'It is strongly recommended to use PCRE PHP extension that is compatible with Unicode characters.'; $string['perfdebug'] = 'Performance info'; $string['performance'] = 'Performance'; diff --git a/lib/classes/scss.php b/lib/classes/scss.php index a8aa4a9081e..0b13e49050f 100644 --- a/lib/classes/scss.php +++ b/lib/classes/scss.php @@ -98,6 +98,54 @@ class core_scss extends \Leafo\ScssPhp\Compiler { return $this->compile($content); } + /** + * Compile scss. + * + * Overrides ScssPHP's implementation, using the SassC compiler if it is available. + * + * @param string $code SCSS to compile. + * @param string $path Path to SCSS to compile. + * + * @return string The compiled CSS. + */ + public function compile($code, $path = null) { + global $CFG; + + $pathtosassc = trim($CFG->pathtosassc); + + if (!empty($pathtosassc) && is_executable($pathtosassc) && !is_dir($pathtosassc)) { + $process = proc_open( + $pathtosassc . ' -I' . implode(':', $this->importPaths) . ' -s', + [ + ['pipe', 'r'], // Set the process stdin pipe to read mode. + ['pipe', 'w'], // Set the process stdout pipe to write mode. + ['pipe', 'w'] // Set the process stderr pipe to write mode. + ], + $pipes // Pipes become available in $pipes (pass by reference). + ); + if (is_resource($process)) { + fwrite($pipes[0], $code); // Write the raw scss to the sassc process stdin. + fclose($pipes[0]); + + $stdout = stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + + fclose($pipes[1]); + fclose($pipes[2]); + + // The proc_close function returns the process exit status. Anything other than 0 is bad. + if (proc_close($process) !== 0) { + throw new coding_exception($stderr); + } + + // Compiled CSS code will be available from stdout. + return $stdout; + } + } + + return parent::compile($code, $path); + } + /** * Compile child; returns a value to halt execution *