/** * Imports css via @import statements * * @author Anthony Short * @param $css */ public static function server_import($css, $previous = "") { # If they want to override the CSS syntax if (CSScaffold::config('core.override_import') === true) { $import = 'import'; } else { $import = 'include'; } if (preg_match_all('/\\@' . $import . '\\s+(?:\'|\\")([^\'\\"]+)(?:\'|\\")\\;/', $css, $matches)) { $unique = array_unique($matches[1]); $include = str_replace("\\", "/", unquote($unique[0])); # If they're getting an absolute file if ($include[0] == "/") { $include = DOCROOT . ltrim($include, "/"); } # Make sure recursion isn't happening if ($include == $previous) { throw new Scaffold_Exception("Recursion occurring with CSS @includes in {$include}"); } # 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 (!is_css($include)) { throw new Scaffold_Exception("Included file isn't a CSS file ({$include})"); } # If the url starts with ~, we'll assume it's from the root of the css directory if ($include[0] == "~") { $include = ltrim($include, '~/'); $include = CSScaffold::config('core.path.css') . $include; } if (file_exists($include)) { # Make sure it hasn't already been included if (!in_array($include, self::$loaded)) { self::$loaded[] = $include; $css = str_replace($matches[0][0], file_get_contents($include), $css); } else { $css = str_replace($matches[0][0], '', $css); } # Compress it which removes any commented out @imports CSS::compress($css); # Check the file again for more imports $css = self::server_import($css, $include); } else { throw new Scaffold_Exception("Included CSS file doesn't exist ({$include})"); } } return $css; }
/** * Import mixins * * @author Anthony Short * @return string */ public static function import_mixins($dir) { if ($mixin_files = CSScaffold::list_files($dir, true)) { foreach ($mixin_files as $item) { if (!is_css($item)) { continue; } # Add it to our css CSS::append(file_get_contents($item)); } } else { throw new Scaffold_Exception('Cannot find the mixin directory - ' . $dir); } }
private static function parse_request($path) { # Get rid of those pesky slashes $requested_file = trim_slashes($path); # Remove anything after .css - like /typography/ $requested_file = preg_replace('/\\.css(.*)$/', '.css', $requested_file); # Remove the start of the url if it exists (http://www.example.com) $requested_file = preg_replace('/https?\\:\\/\\/[^\\/]+/i', '', $requested_file); # Add our requested file var to the array $request['file'] = $requested_file; # Path to the file, relative to the css directory $request['relative_file'] = ltrim(str_replace(self::config('core.url.css'), '/', $requested_file), '/'); # Path to the directory containing the file, relative to the css directory $request['relative_dir'] = pathinfo($request['relative_file'], PATHINFO_DIRNAME); # Find the server path to the requested file if (file_exists(self::config('core.path.docroot') . $requested_file)) { # The request is sent with the absolute path most of the time $request['path'] = self::config('core.path.docroot') . $requested_file; } else { # Otherwise we'll try to find it inside the CSS directory $request['path'] = self::find_file($request['relative_dir'] . '/', basename($requested_file, '.css'), FALSE, 'css'); } # If the file doesn't exist if (!file_exists($request['path'])) { throw new Scaffold_Exception("Requested CSS file doesn't exist:" . $request['file']); } # or if it's not a css file if (!is_css($requested_file)) { throw new Scaffold_Exception("Requested file isn't a css file: {$requested_file}"); } # or if the requested file wasn't from the css directory if (!substr(pathinfo($request['path'], PATHINFO_DIRNAME), 0, strlen(self::config('core.path.css')))) { throw new Scaffold_Exception("Requested file wasn't within the CSS directory"); } return $request; }
/** * Sets the initial variables, checks if we need to process the css * and then sends whichever file to the browser. * * @return void * @author Anthony Short **/ public static function setup($url_params) { static $run; # This function can only be run once if ($run === TRUE) { return; } # Change into the system directory chdir(SYSPATH); # Load the include paths self::include_paths(TRUE); # Recache is off by default $recache = false; # Set the user agent self::$user_agent = !empty($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : ''; # Set timezone date_default_timezone_set('UTC'); # Define Scaffold error constant define('E_SCAFFOLD', 42); # Set error handler set_error_handler(array('CSScaffold', 'exception_handler')); # Set exception handler set_exception_handler(array('CSScaffold', 'exception_handler')); if (!isset($url_params['request'])) { throw new Scaffold_Exception('core.no_file_requested'); } # Get rid of those pesky slashes $requested_file = trim_slashes($url_params['request']); # Remove anything about .css - like /typography/ $requested_file = preg_replace('/\\.css(.*)$/', '.css', $requested_file); # Remove the start of the url if it exists (http://www.example.com) $requested_file = preg_replace('/https?\\:\\/\\/[^\\/]+/i', '', $requested_file); # Add our requested file var to the array $request['file'] = $requested_file; # Path to the file, relative to the css directory $request['relative_file'] = ltrim(str_replace(CSSURL, '/', $requested_file), '/'); # Path to the directory containing the file, relative to the css directory $request['relative_dir'] = pathinfo($request['relative_file'], PATHINFO_DIRNAME); # Find the server path to the requested file if (file_exists(DOCROOT . $requested_file)) { # The request is sent with the absolute path most of the time $request['path'] = DOCROOT . $requested_file; } else { # Otherwise we'll try to find it inside the CSS directory $request['path'] = self::find_file($request['relative_dir'] . '/', basename($requested_file, '.css'), FALSE, 'css'); } # If they've put a param in the url, consider it set to 'true' foreach ($url_params as $key => $value) { if (!in_array($key, self::$system_url_params)) { if ($value == "") { self::config_set('core.options.' . $key, true); } else { self::config_set('core.options.' . $key, $value); } } } # If the file doesn't exist if (!file_exists($request['path'])) { throw new Scaffold_Exception("core.doesnt_exist", $request['file']); } # or if it's not a css file if (!is_css($requested_file)) { throw new Scaffold_Exception("core.not_css", $requested_file); } # or if the requested file wasn't from the css directory if (!substr(pathinfo($request['path'], PATHINFO_DIRNAME), 0, strlen(CSSPATH))) { throw new Scaffold_Exception("core.outside_css_directory"); } # Make sure the files/folders are writeable if (!is_dir(CACHEPATH) || !is_writable(CACHEPATH)) { throw new Scaffold_Exception("core.missing_cache", CACHEPATH); } # Send it off to the config self::config_set('core.request', $request); # Get the modified time of the CSS file self::config_set('core.request.mod_time', filemtime(self::config('core.request.path'))); # Set the recache to true if needed if (self::config('core.always_recache') or isset($url_params['recache'])) { $recache = true; } # Set it back to false if it's locked if (self::config('core.cache_lock') === true || IN_PRODUCTION) { $recache = false; } # Load the modules. self::load_addons(self::$modules, 'modules'); # Load the plugins $plugins = self::config('core.plugins'); # If the plugin is disabled, remove it. foreach ($plugins as $key => $value) { if ($value !== false) { self::$plugins[] = $key; } } # Now we can load them self::load_addons(self::$plugins, PLUGINS); # Prepare the cache, and tell it if we want to recache self::cache_set($recache); # Work in the same directory as the requested CSS file chdir(dirname($request['path'])); # Load the CSS file into the object CSS::load(file_get_contents(self::config('core.request.path'))); # Setup is complete, prevent it from being run again $run = TRUE; }
public function get_css() { $cache_id = array('resources', 'css', $this->modules['module']); $cache = Cache::Instance(); $files = $cache->get($cache_id); // go and fetch the data and populate the cache if ($files === FALSE) { // START FETCHING FILES $files = array(); $dirs = array(); $dirs['shared'] = self::findModulePath(PUBLIC_MODULES, 'shared', FALSE); $dirs['module'] = self::findModulePath(PUBLIC_MODULES, $this->modules['module'], FALSE); $dirs['module'] .= DIRECTORY_SEPARATOR . 'resources/css'; foreach ($dirs as $dir) { if (file_exists($dir)) { $it = new RecursiveDirectoryIterator($dir); // loop through each file found foreach (new RecursiveIteratorIterator($it) as $file) { if (is_css($file)) { $files[] = str_replace(FILE_ROOT, '', $file); } } } } // loop through discovered files, remove sibling less => css files foreach ($files as $key => $css) { if (get_file_extension($css) === 'less') { // build the 'wanted' path and search in the array for it $find_path = str_replace('.less', '.css', $css); $matching_key = array_search($find_path, $files); // if a key is found, delete it if ($matching_key !== FALSE) { unset($files[$matching_key]); } } } // END $cache->add($cache_id, $files); } return $files; }