/** * Imports css via @import statements * * @author Anthony Short * @param $css */ public static function server_import($css, $base) { if (preg_match_all('/\\@include\\s+(?:\'|\\")([^\'\\"]+)(?:\'|\\")\\;/', $css, $matches)) { $unique = array_unique($matches[1]); $include = str_replace("\\", "/", Scaffold_Utils::unquote($unique[0])); # If they haven't supplied an extension, we'll assume its a css file if (pathinfo($include, PATHINFO_EXTENSION) == "") { $include .= '.css'; } # Make sure it's a CSS file if (pathinfo($include, PATHINFO_EXTENSION) != 'css') { $css = str_replace($matches[0][0], '', $css); Scaffold::log('Invalid @include file - ' . $include); self::server_import($css, $base); } # Find the file if ($path = Scaffold::find_file($include, $base)) { # Make sure it hasn't already been included if (!in_array($path, self::$loaded)) { self::$loaded[] = $path; $contents = file_get_contents($path); # Check the file again for more imports $contents = self::server_import($contents, realpath(dirname($path)) . '/'); $css = str_replace($matches[0][0], $contents, $css); } else { $css = str_replace($matches[0][0], '', $css); } } else { Scaffold::error('Can\'t find the @include file - <strong>' . $unique[0] . '</strong>'); } $css = self::server_import($css, $base); } return $css; }
/** * Takes a CSS string, rewrites all URL's using Scaffold's built-in find_file method * * @author Anthony Short * @param $css * @return $css string */ public static function formatting_process() { # The absolute url to the directory of the current CSS file $dirPath = SCAFFOLD_DOCROOT . Scaffold::url_path(Scaffold::$css->path); $dir = rtrim(SCAFFOLD_URLPATH, '\\/') . '/' . str_replace(rtrim(SCAFFOLD_DOCROOT, '\\/') . DIRECTORY_SEPARATOR, '', Scaffold::$css->path); //$dir = str_replace('\\', '/', SCAFFOLD_URLPATH . str_replace(SCAFFOLD_DOCROOT, '', Scaffold::$css->path)); # @imports - Thanks to the guys from Minify for the regex :) if (preg_match_all('/ @import\\s+ (?:url\\(\\s*)? # maybe url( [\'"]? # maybe quote (.*?) # 1 = URI [\'"]? # maybe end quote (?:\\s*\\))? # maybe ) ([a-zA-Z,\\s]*)? # 2 = media list ; # end token /x', Scaffold::$css->string, $found)) { foreach ($found[1] as $key => $value) { # Should we skip it if (self::skip($value)) { continue; } $media = $found[2][$key] == "" ? '' : ' ' . preg_replace('/\\s+/', '', $found[2][$key]); # Absolute path $absolute = self::up_directory($dir, substr_count($url, '..' . DIRECTORY_SEPARATOR, 0)) . str_replace('..' . DIRECTORY_SEPARATOR, '', $url); $absolute = str_replace('\\', '/', $absolute); # Rewrite it # Webligo - PHP5.1 compat Scaffold::$css->string = str_replace($found[0][$key], '@import \'' . $absolute . '\'' . $media . ';', Scaffold::$css->string); } } # Convert all url()'s to absolute paths if required if (preg_match_all('/url\\(\\s*([^\\)\\s]+)\\s*\\)/', Scaffold::$css->__toString(), $found)) { foreach ($found[1] as $key => $value) { // START - Webligo Developments $original = $found[0][$key]; $url = Scaffold_Utils::unquote($value); # Absolute Path if (self::skip($url)) { continue; } # home path if ($url[0] == '~' && $url[1] == '/') { $absolute = str_replace('\\', '/', rtrim(SCAFFOLD_URLPATH, '/\\') . '/' . ltrim($url, '~/')); $absolutePath = rtrim(SCAFFOLD_DOCROOT, '/\\') . DIRECTORY_SEPARATOR . ltrim($url, '~/'); } else { $absolute = str_replace('\\', '/', self::up_directory($dir, substr_count($url, '..' . DIRECTORY_SEPARATOR, 0)) . str_replace('..' . DIRECTORY_SEPARATOR, '', $url)); $absolutePath = self::up_directory($dirPath, substr_count($url, '..' . DIRECTORY_SEPARATOR, 0)) . str_replace('..' . DIRECTORY_SEPARATOR, '', $url); } # If the file doesn't exist if (!Scaffold::find_file($absolutePath)) { Scaffold::log("Missing image - {$absolute} / {$absolutePath}", 1); } # Rewrite it Scaffold::$css->string = str_replace($original, 'url(' . $absolute . ')', Scaffold::$css->string); # Webligo - PHP5.1 compat // END - Webligo Developments } } }
/** * Parses enumerate()'s within the CSS. Enumerate * lets you build a selector based on a start and end * number. Like columns-1 through columns-12. * * enumerate('.name-',1,3) { properties } * * Will produce something like: * * .name-1, .name-2, .name-3 { properties } * * @param $string * @param $min * @param $max * @param $sep * @return string */ function Scaffold_enumerate($string, $min, $max, $sep = ",") { $ret = array(); $string = Scaffold_Utils::unquote($string); for ($i = $min; $i <= $max; $i++) { $ret[] = $string . $i; } return implode($sep, $ret); }
/** * Embeds a file in the CSS using Base64 * * @param $file * @return string */ function Scaffold_embed($file) { $path = Scaffold::find_file(Scaffold_Utils::unquote($file)); # Couldn't find it if ($path === false) { return false; } $data = 'data:image/' . pathinfo($path, PATHINFO_EXTENSION) . ';base64,' . base64_encode(file_get_contents($path)); return "url(" . $data . ")"; }
/** * Get or set the logging directory. * * @param string new log directory * @return string */ public static function log_directory($dir = NULL) { if (!empty($dir)) { // Get the directory path $dir = Scaffold_Utils::fix_path($dir); if (is_dir($dir) and is_writable($dir)) { // Change the log directory self::$log_directory = $dir; } } if (isset(self::$log_directory)) { return self::$log_directory; } }
/** * Takes a CSS string, rewrites all URL's using Scaffold's built-in find_file method * * @author Anthony Short * @param $css * @return $css string */ public static function formatting_process() { # The absolute url to the directory of the current CSS file $dir = Scaffold::url_path(Scaffold::$css->path); # @imports - Thanks to the guys from Minify for the regex :) if (preg_match_all('/ @import\\s+ (?:url\\(\\s*)? # maybe url( [\'"]? # maybe quote (.*?) # 1 = URI [\'"]? # maybe end quote (?:\\s*\\))? # maybe ) ([a-zA-Z,\\s]*)? # 2 = media list ; # end token /x', Scaffold::$css, $found)) { foreach ($found[1] as $key => $value) { # Should we skip it if (self::skip($value)) { continue; } $media = $found[2][$key] == "" ? '' : ' ' . preg_replace('/\\s+/', '', $found[2][$key]); # Absolute path $absolute = self::up_directory($dir, substr_count($value, '..' . DIRECTORY_SEPARATOR, 0)) . str_replace('..' . DIRECTORY_SEPARATOR, '', $value); # Rewrite it Scaffold::$css->string = str_replace($found[0][$key], '@import \'' . $absolute . '\'' . $media . ';', Scaffold::$css); } } # Convert all url()'s to absolute paths if required if (preg_match_all('/url\\(\\s*([^\\)\\s]+)\\s*\\)/', Scaffold::$css, $found)) { foreach ($found[1] as $key => $value) { $url = Scaffold_Utils::unquote($value); # Absolute Path if (self::skip($url)) { continue; } # Absolute path $absolute = self::up_directory($dir, substr_count($url, '..' . DIRECTORY_SEPARATOR, 0)) . str_replace('..' . DIRECTORY_SEPARATOR, '', $url); # If the file doesn't exist if (!Scaffold::find_file($absolute)) { Scaffold::log("Missing image - {$absolute}", 1); } # Rewrite it Scaffold::$css->string = str_replace($found[0][$key], 'url(' . $absolute . ')', Scaffold::$css); } } }
/** * Adds a path to the include paths list * * @param $path The server path to add * @return void */ public static function add_include_path($path) { if (func_num_args() > 1) { $args = func_get_args(); foreach ($args as $inc) { self::add_include_path($inc); } } if (is_file($path)) { $path = dirname($path); } if (!in_array($path, self::$include_paths)) { self::$include_paths[] = Scaffold_Utils::fix_path($path); } }
/** * Parses the parameters of the base * * @author Anthony Short * @param $params * @return array */ public static function parse_params($mixin_name, $params, $function_args = array()) { $parsed = array(); # Make sure any commas inside ()'s, such as rgba(255,255,255,0.5) are encoded before exploding # so that it doesn't break the rule. if (preg_match_all('/\\([^)]*?,[^)]*?\\)/', $params, $matches)) { foreach ($matches as $key => $value) { $original = $value; $new = str_replace(',', '#COMMA#', $value); $params = str_replace($original, $new, $params); } } $mixin_params = $params != "" ? explode(',', $params) : array(); # Loop through each function arg and create the parsed params array foreach ($function_args as $key => $value) { $v = explode('=', $value); # Remove the $ so we can set it as a constants $v[0] = str_replace('$', '', $v[0]); # If the user didn't include one of the params, we'll check to see if a default is available if (count($mixin_params) == 0 || !isset($mixin_params[$key])) { # If there is a default value for the param if (strstr($value, '=')) { $parsed_value = Constants::replace(Scaffold_Utils::unquote(trim($v[1]))); $parsed[trim($v[0])] = (string) $parsed_value; } else { throw new Exception("Missing mixin parameter - " . $mixin_name); } } else { $value = (string) Scaffold_Utils::unquote(trim($mixin_params[$key])); $parsed[trim($v[0])] = str_replace('#COMMA#', ',', $value); } } return $parsed; }
/** * Replaces all of the constants in a CSS string * with the constants defined in the member variable $constants * using PHP's interpolation. */ public static function replace($css) { // START - Modified by Webligo Developments # Strip SVN Keywords $css = preg_replace('/[$][a-z]+?[:].+?[$]/i', '', $css); //preg_match('/[$][a-z]+?[:].+?[$]/i', $css, $m); // END - Modified by Webligo Developments # Pull the constants into the local scope as variables extract(self::$constants, EXTR_SKIP); # Remove unset variables from the string, so errors aren't thrown foreach (array_unique(Scaffold_Utils::match('/\\{?\\$([A-Za-z0-9_-]+)\\}?/', $css, 1)) as $value) { if (!isset(${$value})) { Scaffold::error('Missing constant - ' . $value); } } $css = stripslashes(eval('return "' . addslashes($css) . '";')); # Replace the variables within the string like a normal PHP string return $css; }
* Various options can be set in the URL. Scaffold * itself doesn't use these, but they are handy hooks * for modules to activate functionality if they are * present. */ $options = isset($_GET['options']) ? array_flip(explode(',', $_GET['options'])) : array(); /** * Whether to output the CSS, or return the result of Scaffold */ $display = true; /** * Set a base directory */ if (isset($_GET['d'])) { foreach ($files as $key => $file) { $files[$key] = Scaffold_Utils::join_path($_GET['d'], $file); } } /** * Parse and join an array of files */ $result = Scaffold::parse($files, $config, $options, $display); if ($display === false) { stop($result); } } /** * Prints out the value and exits. * * @author Anthony Short * @param $var
/** * Finds all properties within a css string * * @author Anthony Short * @param $property string * @param $css string */ public function find_property($property) { if (preg_match_all('/(' . Scaffold_Utils::preg_quote($property) . ')\\s*\\:\\s*(.*?)\\s*\\;/sx', $this->string, $matches)) { return (array) $matches; } else { return array(); } }
function testReadableSize() { $this->assertEqual(Scaffold_Utils::readable_size(1), '1 bytes'); }
/** * Logs info about a file * * @author Anthony Short * @param $file * @return void */ private static function _file($file, $name = false) { if ($name === false) { $name = $file; } # Log about the compiled file $contents = file_get_contents($file); $gzipped = gzcompress($contents, 9); $table = array(); $table[] = array('Name', 'Value'); $table[] = array('Compressed Size', Scaffold_Utils::readable_size($contents)); $table[] = array('Gzipped Size', Scaffold_Utils::readable_size($gzipped)); FB::table($name, $table); }
/** * Replaces all of the constants in a CSS string * with the constants defined in the member variable $constants * using PHP's interpolation. */ public static function replace($css) { # Pull the constants into the local scope as variables extract(self::$constants, EXTR_SKIP); # Remove unset variables from the string, so errors aren't thrown foreach (array_unique(Scaffold_Utils::match('/\\{?\\$([A-Za-z0-9_-]+)\\}?/', $css, 1)) as $value) { if (!isset(${$value})) { Scaffold::error('Missing constant - ' . $value); } } $css = stripslashes(eval('return "' . addslashes($css) . '";')); # Replace the variables within the string like a normal PHP string return $css; }