Example #1
0
 public function filterLoad(AssetInterface $asset)
 {
     $lc = new \lessc();
     if ($dir = $asset->getSourceDirectory()) {
         $lc->importDir = $dir;
     }
     foreach ($this->loadPaths as $loadPath) {
         $lc->addImportDir($loadPath);
     }
     foreach ($this->customFunctions as $name => $callable) {
         $lc->registerFunction($name, $callable);
     }
     if ($this->formatter) {
         $lc->setFormatter($this->formatter);
     }
     if (null !== $this->preserveComments) {
         $lc->setPreserveComments($this->preserveComments);
     }
     $asset->setContent($lc->parse($asset->getContent(), $this->presets));
 }
Example #2
0
/**
 * Compile less to css. Creates a cache-file of the last compiled less-file.
 *
 * This code is originally from the manual of lessphp.
 *
 * @param string $inputFile  the filename of the less-file.
 * @param string $outputFile the filename of the css-file to be created.
 * @param array  $config     with configuration details.
 *
 * @return void
 */
function autoCompileLess($inputFile, $outputFile, $config)
{
    $cacheFile = $inputFile . ".cache";
    if (file_exists($cacheFile)) {
        $cache = unserialize(file_get_contents($cacheFile));
    } else {
        $cache = $inputFile;
    }
    $less = new lessc();
    // Add custom less functions
    if (isset($config['functions'])) {
        foreach ($config['functions'] as $key => $val) {
            $less->registerFunction($key, $val);
        }
    }
    // Add import dirs
    if (isset($config['imports'])) {
        foreach ($config['imports'] as $val) {
            $less->addImportDir($val);
        }
    }
    // Set output formatter
    if (isset($config['formatter'])) {
        $less->setFormatter($config['formatter']);
    }
    // Preserve comments
    if (isset($config['comments'])) {
        $less->setPreserveComments($config['comments']);
    }
    // Compile a new cache
    $newCache = $less->cachedCompile($cache);
    if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) {
        file_put_contents($cacheFile, serialize($newCache));
        file_put_contents($outputFile, $newCache['compiled']);
    }
}
Example #3
0
 /**
  * @return lessc
  */
 protected function _initProcessor()
 {
     // lazy load
     if (!class_exists('lessc')) {
         require_once dirname(__FILE__) . '/class.less.leafo.php';
     }
     $less = new lessc();
     if ($this->_isDebug()) {
         $formatter = new lessc_formatter_lessjs();
         // configurate css view
         $formatter->openSingle = " { ";
         $formatter->closeSingle = "}\n";
         $formatter->close = "}\n";
         $formatter->indentChar = "    ";
         $formatter->disableSingle = true;
         $formatter->breakSelectors = true;
         $formatter->assignSeparator = ": ";
         $formatter->selectorSeparator = ", ";
     } else {
         // compress mode
         $formatter = new lessc_formatter_compressed();
         $formatter->closeSingle = "}\n";
         $formatter->close = "}\n";
     }
     // set formatter
     $less->setFormatter($formatter);
     $less->setPreserveComments(false);
     // add paths for imports
     $less->addImportDir($this->_tpl->lessFull);
     $less->addImportDir(JPATH_ROOT);
     // from php
     $less->setVariables(array('css' => str_replace($this->_tpl->baseurl, '', $this->_tpl->css), 'less' => str_replace($this->_tpl->baseurl, '', $this->_tpl->less), 'images' => str_replace($this->_tpl->baseurl, '', $this->_tpl->img), 'debug' => (int) $this->_isDebug()));
     // add custom functions
     $less->registerFunction('data-uri', array($this, 'lib_dataUri'));
     return $less;
 }
Example #4
0
 /**
  * Lessify the stylesheet and return the href of the compiled file
  *
  * @param  string $src    Source URL of the file to be parsed
  * @param  string $handle An identifier for the file used to create the file name in the cache
  * @return string         URL of the compiled stylesheet
  */
 public function parse_stylesheet($src, $handle)
 {
     // we only want to handle .less files
     if (!preg_match('/\\.less(\\.php)?$/', preg_replace('/\\?.*$/', '', $src))) {
         return $src;
     }
     // get file path from $src
     if (!strstr($src, '?')) {
         $src .= '?';
     }
     // prevent non-existent index warning when using list() & explode()
     // Match the URL schemes between WP_CONTENT_URL and $src,
     // so the str_replace further down will work
     $src_scheme = parse_url($src, PHP_URL_SCHEME);
     $wp_content_url_scheme = parse_url(WP_CONTENT_URL, PHP_URL_SCHEME);
     if ($src_scheme != $wp_content_url_scheme) {
         $src = set_url_scheme($src, $wp_content_url_scheme);
     }
     list($less_path, $query_string) = explode('?', str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $src));
     // output css file name
     $css_path = trailingslashit($this->get_cache_dir()) . "{$handle}.css";
     // automatically regenerate files if source's modified time has changed or vars have changed
     try {
         // initialise the parser
         $less = new lessc();
         // load the cache
         $cache_path = "{$css_path}.cache";
         if (file_exists($cache_path)) {
             $cache = unserialize(file_get_contents($cache_path));
         }
         // vars to pass into the compiler - default @themeurl var for image urls etc...
         $this->vars['themeurl'] = '~"' . get_stylesheet_directory_uri() . '"';
         $this->vars['lessurl'] = '~"' . dirname($src) . '"';
         $this->vars = apply_filters('less_vars', $this->vars, $handle);
         // If the cache or root path in it are invalid then regenerate
         if (empty($cache) || empty($cache['less']['root']) || !file_exists($cache['less']['root'])) {
             $cache = array('vars' => $this->vars, 'less' => $less_path);
         }
         // less config
         $less->setFormatter(apply_filters('less_compression', $this->compression));
         $less->setPreserveComments(apply_filters('less_preserve_comments', $this->preserve_comments));
         $less->setVariables($this->vars);
         // add directories to scan for imports
         $import_dirs = apply_filters('less_import_dirs', $this->import_dirs);
         if (!empty($import_dirs)) {
             foreach ((array) $import_dirs as $dir) {
                 $less->addImportDir($dir);
             }
         }
         // register and unregister functions
         foreach ($this->registered_functions as $name => $callable) {
             $less->registerFunction($name, $callable);
         }
         foreach ($this->unregistered_functions as $name) {
             $less->unregisterFunction($name);
         }
         // allow devs to mess around with the less object configuration
         do_action_ref_array('lessc', array(&$less));
         // $less->cachedCompile only checks for changed file modification times
         // if using the theme customiser (changed variables not files) then force a compile
         if ($this->vars !== $cache['vars']) {
             $force = true;
         } else {
             $force = false;
         }
         $less_cache = $less->cachedCompile($cache['less'], apply_filters('less_force_compile', $force));
         if (empty($cache) || empty($cache['less']['updated']) || $less_cache['updated'] > $cache['less']['updated'] || $this->vars !== $cache['vars']) {
             file_put_contents($cache_path, serialize(array('vars' => $this->vars, 'less' => $less_cache)));
             file_put_contents($css_path, $less_cache['compiled']);
         }
     } catch (exception $ex) {
         wp_die($ex->getMessage());
     }
     // restore query string it had if any
     $url = trailingslashit($this->get_cache_dir(false)) . "{$handle}.css" . (!empty($query_string) ? "?{$query_string}" : '');
     // restore original url scheme
     $url = set_url_scheme($url, $src_scheme);
     return add_query_arg('ver', $less_cache['updated'], $url);
 }
Example #5
0
 /**
  * Lessify the stylesheet and return the href of the compiled file
  *
  * @param  string $src    Source URL of the file to be parsed
  * @param  string $handle An identifier for the file used to create the file name in the cache
  * @return string         URL of the compiled stylesheet
  */
 public function parse_stylesheet($src, $handle)
 {
     // we only want to handle .less files
     if (!preg_match('/\\.less(\\.php)?$/', preg_replace('/\\?.*$/', '', $src))) {
         return $src;
     }
     // get file path from $src
     if (!strstr($src, '?')) {
         $src .= '?';
     }
     // prevent non-existent index warning when using list() & explode()
     // Match the URL schemes between WP_CONTENT_URL and $src,
     // so the str_replace further down will work
     $src_scheme = parse_url($src, PHP_URL_SCHEME);
     $wp_content_url_scheme = parse_url(WP_CONTENT_URL, PHP_URL_SCHEME);
     if ($src_scheme != $wp_content_url_scheme) {
         $src = set_url_scheme($src, $wp_content_url_scheme);
     }
     list($less_path, $query_string) = explode('?', str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $src));
     $cache = $this->get_cached_file_data($handle);
     // vars to pass into the compiler - default @themeurl var for image urls etc...
     $this->vars['themeurl'] = '~"' . get_stylesheet_directory_uri() . '"';
     $this->vars['lessurl'] = '~"' . dirname($src) . '"';
     $this->vars = apply_filters('less_vars', $this->vars, $handle);
     // The overall "version" of the LESS file is all it's vars, src etc.
     $less_version = md5(serialize(array($this->vars, $src)));
     /**
      * Give the ability to disable always compiling the LESS with lessc()
      * and instead just use the $vars and $version of the LESS file to
      * dictate whether the LESS should be (re)generated.
      *
      * This means we don't need to run everything through the lessc() compiler
      * on every page load. The tradeoff is making a change in a LESS file will not
      * necessarily cause a (re)generation, one would need to bump the $ver param
      * on wp_enqueue_script() to cause that.
      */
     if (!get_option('wp_less_always_compile_less', true)) {
         if (!empty($cache['version']) && $cache['version'] === $less_version) {
             // restore query string it had if any
             $url = $cache['url'] . (!empty($query_string) ? "?{$query_string}" : '');
             $url = set_url_scheme($url, $src_scheme);
             return add_query_arg('ver', $less_version, $url);
         }
     }
     // automatically regenerate files if source's modified time has changed or vars have changed
     try {
         // initialise the parser
         if (!class_exists('lessc')) {
             return $url;
             //wp_die( 'the lessphp library is missing, aborting, run composer update' );
         }
         // If the cache or root path in it are invalid then regenerate
         if (empty($cache) || empty($cache['less']['root']) || !file_exists($cache['less']['root'])) {
             $cache = array('vars' => $this->vars, 'less' => $less_path);
         }
         if (empty($cache['url'])) {
             $cache['url'] = trailingslashit($this->get_cache_dir(false)) . "{$handle}.css";
         }
         // less config
         $less = new lessc();
         $less->setFormatter(apply_filters('less_compression', $this->compression));
         $less->setPreserveComments(apply_filters('less_preserve_comments', $this->preserve_comments));
         $less->setVariables($this->vars);
         // add directories to scan for imports
         $import_dirs = apply_filters('less_import_dirs', $this->import_dirs);
         if (!empty($import_dirs)) {
             foreach ((array) $import_dirs as $dir) {
                 $less->addImportDir($dir);
             }
         }
         // register and unregister functions
         foreach ($this->registered_functions as $name => $callable) {
             $less->registerFunction($name, $callable);
         }
         foreach ($this->unregistered_functions as $name) {
             $less->unregisterFunction($name);
         }
         // allow devs to mess around with the less object configuration
         do_action_ref_array('lessc', array(&$less));
         // $less->cachedCompile only checks for changed file modification times
         // if using the theme customiser (changed variables not files) then force a compile
         if ($this->vars !== $cache['vars']) {
             $force = true;
         } else {
             $force = false;
         }
         $force = apply_filters('less_force_compile', $force);
         $less_cache = $less->cachedCompile($cache['less'], $force);
         // if they have the same values but differing order, they wont match
         //sort( $cache['less'] );
         //sort( $less_cache );
         if (empty($cache) || empty($cache['less']['updated']) || md5($less_cache['compiled']) !== md5($cache['less']['compiled']) || $this->vars !== $cache['vars']) {
             // output css file name
             $css_path = trailingslashit($this->get_cache_dir()) . "{$handle}.css";
             $cache = array('vars' => $this->vars, 'url' => trailingslashit($this->get_cache_dir(false)) . "{$handle}.css", 'version' => $less_version, 'less' => null);
             /**
              * If the option to not have LESS always compiled is set,
              * then we dont store the whole less_cache in the options table as it's
              * not needed because we only do a comparison based off $vars and $src
              * (which includes the $ver param).
              *
              * This saves space on the options table for high performance environments.
              */
             if (get_option('wp_less_always_compile_less', true)) {
                 $cache['less'] = $less_cache;
             }
             $payload = '<strong>Rebuilt stylesheet with handle: "' . $handle . '"</strong><br>';
             if ($this->vars != $cache['vars']) {
                 $payload .= '<em>Variables changed</em>';
                 $difference = array_merge(array_diff_assoc($cache['vars'], $this->vars), array_diff_assoc($this->vars, $cache['vars']));
                 $payload .= '<pre>' . print_r($difference, true) . '</pre>';
             } else {
                 if (empty($cache) || empty($cache['less']['updated'])) {
                     $payload .= '<em>Empty cache or empty last update time</em>';
                 } else {
                     if ($less_cache['updated'] > $cache['less']['updated']) {
                         $payload .= '<em>Update times different</em>';
                     } else {
                         $payload .= '<em><strong>Unknown! Contact the developers poste haste!!!!!!!</em><strong></em>';
                     }
                 }
             }
             $payload .= '<br>src: <code>"' . $src . '"</code> css path: <code>"' . $css_path . '"</code> and cache path: <code>"' . $cache_path . '"</code> and scheme <code>"' . $src_scheme . '"</code>';
             $this->add_message(array('time' => time(), 'payload' => $payload));
             $this->save_parsed_css($css_path, $less_cache['compiled']);
             $this->update_cached_file_data($handle, $cache);
         }
     } catch (exception $ex) {
         $this->add_message(array('time' => time(), 'payload' => '<strong>Lessphp failure</strong> ' . $ex->GetMessage()));
         wp_die(wp_strip_all_tags($ex->getMessage()));
     }
     // restore query string it had if any
     $url = $cache['url'] . (!empty($query_string) ? "?{$query_string}" : '');
     // restore original url scheme
     $url = set_url_scheme($url, $src_scheme);
     if (get_option('wp_less_always_compile_less', true)) {
         return add_query_arg('ver', $less_cache['updated'], $url);
     }
     return add_query_arg('ver', $less_version, $url);
 }
Example #6
0
 /**
  * @param string $content
  * @param bool   $compress
  * @return string
  */
 private function _compileLess($content, $compress)
 {
     $render = $this->_render;
     $lessCompiler = new lessc();
     $lessCompiler->registerFunction('image', function ($arg) use($render) {
         /** @var CM_Frontend_Render $render */
         list($type, $delimiter, $values) = $arg;
         return array('function', 'url', array('string', $delimiter, array($render->getUrlResource('layout', 'img/' . $values[0]))));
     });
     $lessCompiler->registerFunction('image-inline', function ($arg) use($render) {
         /** @var CM_Frontend_Render $render */
         list($type, $delimiter, $values) = $arg;
         if (2 == sizeof($values) && is_array($values[0]) && is_array($values[1])) {
             $delimiter = (string) $values[0][1];
             $path = (string) $values[0][2][0];
             $size = (int) $values[1][1];
         } else {
             $path = $values[0];
             $size = 0;
         }
         $imagePath = $render->getLayoutPath('resource/img/' . $path, null, null, true, true);
         $cache = CM_Cache_Persistent::getInstance();
         $imageBase64 = $cache->get($cache->key(__METHOD__, md5($imagePath), 'size:' . $size), function () use($imagePath, $size) {
             $file = new CM_File($imagePath);
             $img = new CM_Image_Image($file->read());
             if ($size > 0) {
                 $img->resize($size, $size);
             }
             $img->setFormat(CM_Image_Image::FORMAT_GIF);
             return base64_encode($img->getBlob());
         });
         $url = 'data:image/gif;base64,' . $imageBase64;
         return array('function', 'url', array('string', $delimiter, array($url)));
     });
     $lessCompiler->registerFunction('urlFont', function ($arg) use($render) {
         /** @var CM_Frontend_Render $render */
         list($type, $delimiter, $values) = $arg;
         return array($type, $delimiter, array($render->getUrlStatic('/font/' . $values[0])));
     });
     if ($compress) {
         $lessCompiler->setFormatter('compressed');
     }
     return $lessCompiler->compile($content);
 }
Example #7
0
 function compileLess($inputFile, $outputFile)
 {
     if (!class_exists('lessc')) {
         require_once KPATH_FRAMEWORK . '/external/lessc/lessc.php';
     }
     // Load the cache.
     $cacheDir = JPATH_CACHE . '/kunena';
     if (!is_dir($cacheDir)) {
         KunenaFolder::create($cacheDir);
     }
     $cacheFile = "{$cacheDir}/kunena.{$this->name}.{$inputFile}.cache";
     if (is_file($cacheFile)) {
         $cache = unserialize(file_get_contents($cacheFile));
     } else {
         $cache = JPATH_SITE . '/' . $this->getFile($inputFile, false, 'less');
     }
     $outputDir = KPATH_MEDIA . "/cache/{$this->name}/css";
     if (!is_dir($outputDir)) {
         KunenaFolder::create($outputDir);
     }
     $outputFile = "{$outputDir}/{$outputFile}";
     $less = new lessc();
     $class = $this;
     $less->registerFunction('url', function ($arg) use($class) {
         list($type, $q, $values) = $arg;
         $value = reset($values);
         return "url({$q}{$class->getFile($value, true, 'media', 'media/kunena')}{$q})";
     });
     $less->setVariables($this->style_variables);
     $newCache = $less->cachedCompile($cache);
     if (!is_array($cache) || $newCache['updated'] > $cache['updated'] || !is_file($outputFile)) {
         $cache = serialize($newCache);
         KunenaFile::write($cacheFile, $cache);
         KunenaFile::write($outputFile, $newCache['compiled']);
     }
 }
Example #8
0
 public function inject(lessc $instance)
 {
     $instance->registerFunction('hsvsaturation', array($this, 'function_hsvsaturation'));
 }
Example #9
0
 /**
  * @param string $content
  * @param bool   $compress
  * @return string
  */
 private function _compileLess($content, $compress)
 {
     $render = $this->_render;
     $lessCompiler = new lessc();
     $lessCompiler->registerFunction('image', function ($arg) use($render) {
         /** @var CM_Frontend_Render $render */
         list($type, $delimiter, $values) = $arg;
         return array('function', 'url', array('string', $delimiter, array($render->getUrlResource('layout', 'img/' . $values[0]))));
     });
     $lessCompiler->registerFunction('urlFont', function ($arg) use($render) {
         /** @var CM_Frontend_Render $render */
         list($type, $delimiter, $values) = $arg;
         return array($type, $delimiter, array($render->getUrlStatic('/font/' . $values[0])));
     });
     if ($compress) {
         $lessCompiler->setFormatter('compressed');
     }
     return $lessCompiler->compile($content);
 }
Example #10
0
 /**
  *
  * @param array $variables
  * @param array $functions
  * @return \lessc|boolean
  */
 function get_less_parser($variables, $functions)
 {
     if (!(include_once LESSPHP_INC . 'lessc.inc.php')) {
         trigger_error('Unable to process .less file -- LESSPHP not configured correctly on your server. Check the LESSPHP_INC setting in settings/package_settings.php.');
         return false;
     }
     $less = new lessc();
     $less->setFormatter('compressed');
     $less->setVariables($variables);
     foreach ($functions as $name => $func) {
         $less->registerFunction($name, $func);
     }
     return $less;
 }
Example #11
0
 /**
  * Compile a less file
  *
  * @param \Zend_View $view
  * @param string $href The less file
  * @param boolean $always Always compile
  * @return boolean True when changed
  */
 public function compile(\Zend_View $view, $href, $always = false)
 {
     if (\MUtil_String::startsWith($href, 'http', true)) {
         // When a local url, strip the serverUrl and basepath
         $base = $view->serverUrl() . $view->baseUrl();
         if (\MUtil_String::startsWith($href, $base, true)) {
             // Only strip when urls match
             $href = substr($href, strlen($base));
         }
     }
     // Add full path to the webdir
     $inFile = $this->_webroot . '/' . $href;
     $outFile = substr($inFile, 0, -strlen(pathinfo($inFile, PATHINFO_EXTENSION))) . 'css';
     // Try compiling
     try {
         // \MUtil_Echo::track($inFile, $outFile);
         $lessc = new lessc();
         $lessc->registerFunction('base64encode', array($this, 'base64encode'));
         if ($always || array_key_exists('compilecss', \Zend_Controller_Front::getInstance()->getRequest()->getParams())) {
             $result = (bool) $lessc->compileFile($inFile, $outFile);
         } else {
             $result = $lessc->checkedCompile($inFile, $outFile);
         }
     } catch (\Exception $exc) {
         // If we have an error, present it if not in production
         if (APPLICATION_ENV !== 'production' || APPLICATION_ENV !== 'acceptance') {
             \MUtil_Echo::pre($exc->getMessage());
         }
         $result = null;
     }
     return $result;
 }
Example #12
0
 /**
  * @param lessc $c
  *
  * Register less functions in a lessc object
  */
 function registerFunctions(&$c)
 {
     $c->registerFunction('length', array($this, 'length'));
 }
Example #13
0
 /**
  * Add a less-based stylesheet
  * @param string $url
  * @param string $media optional media attribute
  * @param boolean $add_to_top
  * @param array $wrapper
  * @param array $less_variables
  * @param array $less_functions
  * @return boolean success
  */
 function add_less_stylesheet($url, $media = '', $add_to_top = false, $wrapper = array('before' => '', 'after' => ''), $less_variables = array(), $less_functions = array())
 {
     if (substr($url, 0, 1) != '/') {
         trigger_error('Less stylesheets must be specified relative to server root (i.e. starting with "/"). Path given (' . $url . ') does not conform to this specification. Stylesheet not added.');
         return false;
     }
     if (!(include_once LESSPHP_INC . 'lessc.inc.php')) {
         trigger_error('Unable to process .less file -- LESSPHP not configured correctly on your server. Check the LESSPHP_INC setting in settings/package_settings.php.');
         return false;
     }
     $input_path = WEB_PATH . substr($url, 1);
     if (!file_exists($input_path)) {
         trigger_error('Less stylesheet not found at "' . $input_path . '". Stylesheet not added.');
         return false;
     }
     $hash = md5($input_path . serialize($less_variables) . serialize(array_keys($less_functions)));
     $first2 = substr($hash, 0, 2);
     $output_filename = $hash . '_' . filemtime($input_path) . '.css';
     $output_url = WEB_TEMP . 'less_compiled/' . $first2 . '/' . $output_filename;
     $base_output_directory = WEB_PATH . substr(WEB_TEMP, 1) . 'less_compiled/';
     if (!file_exists($base_output_directory)) {
         mkdir($base_output_directory);
     }
     $output_directory = $base_output_directory . $first2 . '/';
     if (!file_exists($output_directory)) {
         mkdir($output_directory);
     }
     $output_path = $output_directory . $output_filename;
     $cache_path = $output_directory . $hash . '.cache';
     $less = new lessc();
     $less->setFormatter('compressed');
     $less->setVariables($less_variables);
     foreach ($less_functions as $less_function_name => $php_function) {
         $less->registerFunction($less_function_name, $php_function);
     }
     try {
         if ($this->less_cached_compile($input_path, $output_path, $less, $cache_path)) {
             $compiled = true;
             // something has changed
             if ($this->delete_old_less_css && ($handle = opendir($output_directory))) {
                 while (false !== ($entry = readdir($handle))) {
                     if ($entry != $output_filename && strpos($entry, $hash . '_') === 0 && substr($entry, -4) == '.css') {
                         unlink($output_directory . $entry);
                     }
                 }
             } else {
                 trigger_error('Unable to delete old less css files');
             }
         } else {
             $compiled = false;
             // nothing has changed
         }
     } catch (Exception $ex) {
         trigger_error('lessphp unable to compile less at "' . $input_path . '". Stylesheet not added. Message: ' . $ex->getMessage());
         return;
     }
     return $this->add_stylesheet($output_url, $media, $add_to_top, $wrapper);
     return true;
 }
Example #14
0
function validateLESS($templateDir, &$errors)
{
    $input = array('type' => 'css', 'params' => array('@font-swatch1-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch1-font-size' => '24px', '@font-swatch1-font-weight' => '400', '@font-swatch1-line-height' => '34px', '@font-swatch1-color' => '@color-swatch6', '@font-swatch2-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch2-font-size' => '24px', '@font-swatch2-font-weight' => '400', '@font-swatch2-line-height' => '34px', '@font-swatch2-color' => '@color-swatch3', '@font-swatch3-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch3-font-size' => '18px', '@font-swatch3-font-weight' => '400', '@font-swatch3-line-height' => '28px', '@font-swatch3-color' => '@color-swatch3', '@font-swatch4-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch4-font-size' => '14px', '@font-swatch4-font-weight' => '400', '@font-swatch4-line-height' => '24px', '@font-swatch4-color' => '@color-swatch3', '@font-swatch5-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch5-font-size' => '14px', '@font-swatch5-font-weight' => '400', '@font-swatch5-line-height' => '24px', '@font-swatch5-color' => '@color-swatch5', '@color-swatch1' => '#4a979d', '@color-swatch2' => '#eafffc', '@color-swatch3' => '#3e3e3e', '@color-swatch4' => '#6a6a6a', '@color-swatch5' => '#bdbdbd', '@siteBackgroundColor' => 'transparent', '@siteBackgroundGradientType' => 'vertical', '@siteBackgroundGradientFrom' => 'transparent', '@siteBackgroundGradientTo' => 'transparent', '@siteBackgroundImageScale' => 'original', '@siteBackgroundImage' => 'none', '@siteBackgroundPositionX' => 'center', '@siteBackgroundPositionY' => 'top', '@siteBackgroundRepeat' => 'no-repeat', '@font-swatch1-letter-spacing' => 'inherit', '@font-swatch2-letter-spacing' => 'inherit', '@font-swatch3-letter-spacing' => 'inherit', '@font-swatch4-letter-spacing' => 'inherit', '@font-swatch5-letter-spacing' => 'inherit', '@font-swatch6-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch6-font-size' => '16px', '@font-swatch6-font-weight' => '400', '@font-swatch6-line-height' => '26px', '@font-swatch6-letter-spacing' => 'inherit', '@font-swatch6-color' => '@color-swatch5', '@font-swatch6-color-hover' => '@color-swatch5', '@font-swatch6-background-color' => 'transparent', '@font-swatch6-background-color-hover' => 'transparent', '@font-swatch7-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch7-font-size' => '18px', '@font-swatch7-font-weight' => '400', '@font-swatch7-line-height' => '28px', '@font-swatch7-letter-spacing' => 'inherit', '@font-swatch7-color' => '@color-swatch5', '@font-swatch7-background-color' => 'transparent', '@font-swatch7-background-color-hover' => 'darken(@color-swatch1,5%)', '@color-swatch6' => '#ffffff', '@color-swatch7' => '#f4f4f4', '@font-swatch8-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch8-font-size' => '18px', '@font-swatch8-font-weight' => '400', '@font-swatch8-line-height' => '28px', '@font-swatch8-letter-spacing' => 'inherit', '@font-swatch8-color' => '@color-swatch5', '@font-swatch9-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch9-font-size' => '18px', '@font-swatch9-font-weight' => '400', '@font-swatch9-line-height' => '28px', '@font-swatch9-letter-spacing' => 'inherit', '@font-swatch9-color' => '@color-swatch5', '@font-swatch10-font-family' => '"Futura", "Helvetica", sans-serif', '@font-swatch10-font-size' => '24px', '@font-swatch10-font-weight' => '400', '@font-swatch10-line-height' => '34px', '@font-swatch10-letter-spacing' => 'inherit', '@font-swatch10-color' => '@color-swatch5'), 'options' => array('compress' => 1));
    $lessc = new lessc();
    $lessc->setImportDir(array($templateDir, __DIR__ . '../templates'));
    // convert any relative image URL's to use the FQDN
    $assetDomain = null;
    $assetVersion = null;
    $templateDirectory = $templateDir;
    $templateHash = null;
    $lessc->registerFunction('image', function ($arg) use($assetDomain, $templateDirectory, $templateHash, $assetVersion) {
        list($type, $delim, $path) = $arg;
        $url = sprintf('//%s/%s/templates', $assetDomain, $templateHash ? $templateHash : $assetVersion);
        if ($templateDirectory) {
            $url .= "/{$templateDirectory}";
        }
        $url .= $path[0];
        return array($type, '', array(" url({$url})"));
    });
    $lessc->registerFunction('bkscale', function ($arg) {
        list($type, $delim, $args) = $arg;
        $value = isset($args[0]) && isset($args[0][1]) ? $args[0][1] : '';
        $unit = isset($args[0]) && isset($args[0][2]) ? $args[0][2] : '';
        $scale = isset($args[1]) && isset($args[1][1]) ? $args[1][1] : '';
        $intValue = intval($value);
        $floatScale = floatval($scale);
        $returnValue = array();
        if ($intValue > 0 && $floatScale > 0) {
            $newScale = $intValue * $floatScale;
            $returnValue = array('string', '', array($newScale . $unit));
        } else {
            // return back the original value
            $returnValue = array('string', '', array($value));
        }
        return $returnValue;
    });
    if (null !== $templateDirectory) {
        $input['params']['@templateLocal'] = '"' . $templateDirectory . '"';
    } else {
        $input['params']['@templateLocal'] = '""';
    }
    $input['params']['@templateCommon'] = '"../templates/common"';
    //  Any passed in variables used to populate the parsed CSS
    if (isset($input['params']) && is_array($input['params']) && count($input['params']) > 0) {
        $lessc->setVariables($input['params']);
    }
    if (isset($input['options']) && isset($input['options']['compress']) && $input['options']['compress'] == true) {
        $lessc->setFormatter("compressed");
    }
    try {
        recruseImports($lessc, $templateDir, $templateDir . '/stylesheet.less');
    } catch (\Exception $e) {
        $errors[] = "LESS Error: " . $e->getMessage();
    }
}
Example #15
0
 /**
  * Get the CSS for the given style and preset
  *
  * @param $style
  * @param $preset
  * @return string
  */
 function create_css($style, $preset)
 {
     $paths = $this->get_widget_paths();
     $style_file = false;
     // Find the file - exit if it can't be found.
     foreach ($paths as $path) {
         if (file_exists($path . '/' . $this->origin_id . '/styles/' . $style . '.less')) {
             $style_file = $path . '/' . $this->origin_id . '/styles/' . $style . '.less';
             break;
         }
     }
     if (empty($style_file)) {
         return '';
     }
     if (!class_exists('lessc')) {
         include plugin_dir_path(__FILE__) . 'lib/lessc.inc.php';
     }
     foreach ($this->get_widget_folders() as $folder => $folder_url) {
         $filename = rtrim($folder, '/') . '/' . $this->origin_id . '/styles/' . $style . '.less';
         if (file_exists($filename)) {
             $less = file_get_contents($filename);
             break;
         }
     }
     // Add in the mixins
     $less = str_replace('@import "../../../less/mixins";', "\n\n" . file_get_contents(plugin_dir_path(__FILE__) . 'less/mixins.less'), $less);
     // Apply the preset variables to the LESS file
     $presets = $this->get_style_presets($style);
     if (!empty($presets[$preset]) && is_array($presets[$preset])) {
         foreach ($presets[$preset] as $k => $v) {
             $less = preg_replace('/@' . preg_quote($k) . ':(.*);/', '@' . $k . ': ' . $v . ';', $less);
         }
     }
     // Scope the CSS with the wrapper we'll be adding
     $less = '.origin-widget.origin-widget-' . $this->origin_id . '-' . $style . '-' . $preset . ' {' . $less . '}';
     $lc = new lessc();
     $lc->setPreserveComments(false);
     $lc->registerFunction('lumlighten', 'origin_widgets_less_lumlighten');
     $lc->registerFunction('lumdarken', 'origin_widgets_less_lumdarken');
     $lc->registerFunction('texture', 'origin_widgets_less_texture');
     $lc->registerFunction('widgetimage', 'origin_widgets_less_widgetimage');
     // Create the CSS
     return $lc->compile($less);
 }
Example #16
0
 /**
  * Execute lessphp on a .less file or a lessphp cache structure
  * 
  * The lessphp cache structure contains information about a specific
  * less 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 bool $force Force rebuild?
  * @param array $initial_variables Initial input variables
  * @param array $functions Functions to register into the created Less instance
  * @return array lessphp cache structure
  */
 public static function cexecute($in, $force = false, $initial_variables = null, $functions = null)
 {
     // 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.
         $less = new lessc($root);
         if (is_array($functions)) {
             foreach ($functions as $name => $function) {
                 if (is_callable($function)) {
                     $less->registerFunction($name, $function);
                 }
             }
         }
         $out = array();
         $out['root'] = $root;
         $out['compiled'] = $less->parse(null, $initial_variables);
         $out['files'] = $less->allParsedFiles();
         $out['updated'] = time();
         return $out;
     } else {
         // No changes, pass back the structure
         // we were given initially.
         return $in;
     }
 }
Example #17
0
 /**
  * Returns LESS compiler set up for use with MediaWiki
  *
  * @param Config $config
  * @throws MWException
  * @since 1.22
  * @return lessc
  */
 public static function getLessCompiler(Config $config)
 {
     // When called from the installer, it is possible that a required PHP extension
     // is missing (at least for now; see bug 47564). If this is the case, throw an
     // exception (caught by the installer) to prevent a fatal error later on.
     if (!class_exists('lessc')) {
         throw new MWException('MediaWiki requires the lessphp compiler');
     }
     if (!function_exists('ctype_digit')) {
         throw new MWException('lessc requires the Ctype extension');
     }
     $less = new lessc();
     $less->setPreserveComments(true);
     $less->setVariables(self::getLessVars($config));
     $less->setImportDir($config->get('ResourceLoaderLESSImportPaths'));
     foreach ($config->get('ResourceLoaderLESSFunctions') as $name => $func) {
         $less->registerFunction($name, $func);
     }
     return $less;
 }
Example #18
0
 /**
  * Processing less file.
  *
  * @param $path
  * @param string $cacheFolder
  * @return null|string
  * @throws \Exception
  */
 public function lessProcess($path, $cacheFolder = 'styles')
 {
     $output = null;
     $ext = pathinfo($path, PATHINFO_EXTENSION);
     if (!$ext) {
         $path .= '.less';
     }
     $systemPath = $path;
     $segments = explode('/', $path);
     $lessFolder = ROOT . DS . 'webroot' . DS . 'less';
     list($plugin, $path) = $this->_View->pluginSplit($path, false);
     $webRoot = ROOT . DS . 'webroot' . DS;
     $isPlugin = Plugin::loaded($plugin);
     $this->_imageFull = WWW_ROOT . DS . 'img' . DS;
     //  Set data for plugin less.
     if ($plugin && $isPlugin) {
         $pluginPath = Plugin::path($plugin);
         $lessFolder = $pluginPath . 'webroot' . DS . 'less';
         $webRootPlg = $pluginPath . 'webroot' . DS;
         $this->_type = 'plugin:' . $plugin;
         $this->_imageFull = $webRootPlg . 'img' . DS;
     }
     $lessFile = $lessFolder . DS . $path;
     //  Set data for module less.
     if (strpos($segments[0], ':')) {
         list($type, $name) = explode(':', $segments[0]);
         if ($type == 'modules') {
             $modulePath = ROOT . DS . 'modules' . DS . $name . DS . 'assets' . DS;
             $lessFile = $modulePath . 'less' . DS . $segments[1];
             $this->_type = 'modules:' . $name;
             $this->_imageFull = $modulePath . 'img' . DS;
         }
     }
     if (file_exists($lessFile)) {
         $less = new \lessc();
         $fileHash = md5(serialize(md5_file($lessFile)));
         $cssFileName = $fileHash . '.css';
         $less->registerFunction('url', array($this, 'lessPhpUrl'));
         $less->addImportDir(Plugin::path('Union/Core') . 'webroot' . DS . 'less' . DS);
         if (!DEBUG) {
             $formatter = new \lessc_formatter_compressed();
             $less->setFormatter($formatter);
             $less->setPreserveComments(false);
             $cssFileName = $fileHash . '.min.css';
         }
         $updateFile = false;
         try {
             $cssFile = $webRoot . 'cache' . DS . $cacheFolder . DS . $cssFileName;
             if (file_exists($cssFile)) {
                 $cacheRes = fopen($cssFile, 'r');
                 $firstLine = fgets($cacheRes);
                 fclose($cacheRes);
                 if (!preg_match("#{$fileHash}#i", $firstLine)) {
                     $updateFile = true;
                 }
             } else {
                 $updateFile = true;
             }
             $output = '/cache/' . $cacheFolder . '/' . $cssFileName;
             if ($this->_lessCompile) {
                 $updateFile = true;
             }
             if ($updateFile) {
                 $css = $less->compileFile($lessFile);
                 $css = $this->_getLessFileComment($fileHash, $systemPath) . $css;
                 $file = new File($cssFile, true);
                 $file->write($css);
                 $file->close();
             }
         } catch (Exception $error) {
             die('<strong>' . __d('union_dev', 'Less Error:') . '</strong><br/><pre>' . $error->getMessage() . '</pre>');
         }
     }
     return $output;
 }