/** * @param $tpl template object * @return bool optimize success or not */ public static function optimizecss($tpl) { $outputpath = JPATH_ROOT . '/' . $tpl->getParam('plazart-assets', 'plazart-assets') . '/css'; $outputurl = JURI::root(true) . '/' . $tpl->getParam('plazart-assets', 'plazart-assets') . '/css'; if (!JFile::exists($outputpath)) { JFolder::create($outputpath); @chmod($outputpath, 0755); } if (!is_writeable($outputpath)) { return false; } //prepare config self::prepare($tpl); $doc = JFactory::getDocument(); //======================= Group css ================= // $mediagroup = array(); $cssgroups = array(); $stylesheets = array(); $ielimit = 4095; $selcounts = 0; $regex = '/\\{.+?\\}|,/s'; //selector counter $csspath = ''; // group css into media $mediagroup['all'] = array(); $mediagroup['screen'] = array(); foreach ($doc->_styleSheets as $url => $stylesheet) { $media = $stylesheet['media'] ? $stylesheet['media'] : 'all'; if (empty($mediagroup[$media])) { $mediagroup[$media] = array(); } $mediagroup[$media][$url] = $stylesheet; } foreach ($mediagroup as $media => $group) { $stylesheets = array(); // empty - begin a new group foreach ($group as $url => $stylesheet) { $url = self::fixUrl($url); if ($stylesheet['mime'] == 'text/css' && ($csspath = self::cssPath($url))) { $stylesheet['path'] = $csspath; $stylesheet['data'] = file_get_contents($csspath); $selcount = preg_match_all($regex, $stylesheet['data'], $matched); if (!$selcount) { $selcount = 1; //just for sure } //if we found an @import rule or reach IE limit css selector count, break into the new group if (preg_match('#@import\\s+.+#', $stylesheet['data']) || $selcounts + $selcount >= $ielimit) { if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } $stylesheets = array($url => $stylesheet); // empty - begin a new group $selcounts = $selcount; } else { $stylesheets[$url] = $stylesheet; $selcounts += $selcount; } } else { // first get all the stylsheets up to this point, and get them into // the items array if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } //mark ignore current stylesheet $cssgroup = array($url => $stylesheet, 'ignore' => true); $cssgroups[] = $cssgroup; $stylesheets = array(); // empty - begin a new group } } if (count($stylesheets)) { $cssgroup = array(); $groupname = array(); foreach ($stylesheets as $gurl => $gsheet) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroup['media'] = $media; $cssgroups[] = $cssgroup; } } //======================= Group css ================= // $output = array(); foreach ($cssgroups as $cssgroup) { if (isset($cssgroup['ignore'])) { unset($cssgroup['ignore']); unset($cssgroup['groupname']); unset($cssgroup['media']); foreach ($cssgroup as $furl => $fsheet) { $output[$furl] = $fsheet; } } else { $media = $cssgroup['media']; $groupname = 'css-' . substr(md5($cssgroup['groupname']), 0, 5) . '.css'; $groupfile = $outputpath . '/' . $groupname; $grouptime = JFile::exists($groupfile) ? @filemtime($groupfile) : -1; $rebuild = $grouptime < 0; //filemtime == -1 => rebuild unset($cssgroup['groupname']); unset($cssgroup['media']); foreach ($cssgroup as $furl => $fsheet) { if (!$rebuild && @filemtime($fsheet['path']) > $grouptime) { $rebuild = true; } } if ($rebuild) { $cssdata = array(); foreach ($cssgroup as $furl => $fsheet) { $cssdata[] = "\n\n/*==============================="; $cssdata[] = $furl; $cssdata[] = "================================================================================*/"; $cssmin = self::minifyCss($fsheet['data']); $cssmin = PlazartPath::updateUrl($cssmin, PlazartPath::relativePath($outputurl, dirname($furl))); $cssdata[] = $cssmin; } $cssdata = implode("\n", $cssdata); if (!JFile::write($groupfile, $cssdata)) { // cannot write file, ignore minify return false; } $grouptime = @filemtime($groupfile); @chmod($groupfile, 0644); } $output[$outputurl . '/' . $groupname . '?t=' . $grouptime % 1000] = array('mime' => 'text/css', 'media' => $media == 'all' ? NULL : $media, 'attribs' => array()); } } //apply the change make change $doc->_styleSheets = $output; }
function compileCss($path, $topath = '') { $app = JFactory::getApplication(); $theme = $app->getUserState('vars_theme'); $realpath = realpath(JPATH_ROOT . '/' . $path); // check path if (!is_file($realpath)) { //if (!JPath::check ($realpath)){ return; } // Get file content $content = JFile::read($realpath); // remove comments $content = preg_replace('!/\\*[^*]*\\*+([^/][^*]*\\*+)*/!', '', $content); // split into array, separated by the import $arr = preg_split('#^\\s*@import\\s+"([^"]*)"\\s*;#im', $content, -1, PREG_SPLIT_DELIM_CAPTURE); // check and add theme less if not is theme less if ($theme && !preg_match('#themes/#', $path)) { $themepath = 'themes/' . $theme . '/' . basename($path); if (is_file(PLAZART_TEMPLATE_PATH . '/less/' . $themepath)) { $arr[] = $themepath; $arr[] = ''; } } // variables & mixin $vars = $this->getVars(); // add vars $this->setImportDir(array(dirname($realpath), PLAZART_TEMPLATE_PATH . '/less/')); // compile chuck $import = false; $output = ''; foreach ($arr as $s) { if ($import) { $import = false; if ($s == 'vars.less') { continue; } // process import file $url = PlazartPath::cleanPath(dirname($path) . '/' . $s); $importcontent = JFile::read(JPATH_ROOT . '/' . $url); $output .= "#less-file-path{content: \"{$url}\";}\n" . $importcontent . "\n\n"; } else { $import = true; $s = trim($s); if ($s) { $output .= "#less-file-path{content: \"{$path}\";}\n" . $s . "\n\n"; } } } $output = $this->compile($vars . "\n" . $output); $arr = preg_split('#^\\s*\\#less-file-path\\s*{\\s*[\\r\\n]*\\s*content:\\s*"([^"]*)";\\s*[\\r\\n]*\\s*}#im', $output, -1, PREG_SPLIT_DELIM_CAPTURE); $output = ''; $file = ''; $isfile = false; foreach ($arr as $s) { if ($isfile) { $isfile = false; $file = $s; $relpath = $topath ? PlazartPath::relativePath(dirname($topath), dirname($file)) : JURI::base(true) . '/' . dirname($file); } else { $output .= ($file ? PlazartPath::updateUrl($s, $relpath) : $s) . "\n\n"; $isfile = true; } } // remove the dupliate clearfix at the beggining if not bootstrap.css file if (!preg_match('#bootstrap.less#', $path)) { $arr = preg_split('/[\\r?\\n]{2,}/', $output); // ignore first one, it's clearfix array_shift($arr); $output = implode("\n", $arr); } if ($topath) { $tofile = JPATH_ROOT . '/' . $topath; if (!is_dir(dirname($tofile))) { JFolder::create(dirname($tofile)); } $ret = JFile::write($tofile, $output); @chmod($tofile, 0644); return $ret; } return $output; }