/** * This function generates a new .js file from the existing files (if anything new happen to them or does not * exist). The name of the new file will be returned. * * @api * * @param array $files * * @return string|false false on error or nothing */ public static function combine(array $files) { if (empty($files)) { return false; } $target = self::getTargetPath(); $source = self::getSourcePath(); // identify file combinations by hash $jsHash = md5(serialize($files)); $targetfile = $target . $jsHash . '.js'; // check if any source file was modified $needUpdate = false; if (file_exists($targetfile)) { $hashtime = filemtime($targetfile); foreach ($files as $file) { if (substr($file['name'], 0, 1) === '/') { $filename = $file['name']; } elseif ($file['relative']) { // relative to public/js $filename = $target . $file['name'] . '.js'; } else { // use javascript folder $filename = $source . $file['name'] . '.js.tpl'; } if ($hashtime < filemtime($filename)) { $needUpdate = true; break; } } } else { // file does not exist, so we need an update anyway $needUpdate = true; } // we can abort if no update is required if ($needUpdate === false) { return $jsHash; } // make sure, that the target directory exists if (!is_dir($target)) { FileUtil::makedir($target); } // combine file contents $content = ''; foreach ($files as $file) { try { if (substr($file['name'], 0, 1) === '/') { if (strpos($file['name'], '.tpl') > 0) { $nextcontent = JavascriptTemplate::getInstance()->fetch($file['name']); } else { $nextcontent = file_get_contents($file['name']); } } elseif ($file['relative']) { $nextcontent = file_get_contents($target . $file['name'] . '.js'); } else { $nextcontent = JavascriptTemplate::getInstance()->fetch($source . $file['name'] . '.js.tpl'); } // do not double minify if (strpos($file['name'], '.min') > 0 || strpos($file['name'], '.pack') > 0 || !method_exists('\\JShrink\\Minifier', 'minify')) { $content .= $nextcontent . "\n"; } else { $content .= \JShrink\Minifier::minify($nextcontent) . "\n"; } } catch (\ErrorException $exception) { Logger::getInstance()->exception($exception); } } // foreach file // write minified version $success = file_put_contents($targetfile, $content); // adjust file permissions for webserver if ($success) { chmod($targetfile, Config::getDetail('smarty', 'file_perms', self::$defaultConfig)); } // foreach scssFiles return $jsHash; }
/** * This function is the final step to render a website, it passes the final arguments to the template, including * all error messages, gathered so far. And finally flushes the website content. * * @api */ public function display() { // minify js $jsFile = template\JavascriptTemplate::combine($this->jsFiles); if ($jsFile !== false) { $this->assign('customjsfile', [$jsFile]); } else { $this->assign('customjsfile', []); } // minify css $cssFile = template\CssTemplate::combine($this->cssFiles); if ($cssFile !== false) { $this->assign('customcssfile', [$cssFile]); } else { $this->assign('customcssfile', []); } // this code is not safe for use in different tabs foreach (Session::getErrorMsg() as $error) { $this->append('errors', ($error['field'] ? '"' . $error['field'] . '" - ' : '') . $error['content']); } foreach (Session::getSuccessMsg() as $success) { $this->append('success', $success); } // we need a relative dir from smarty templates template\HtmlTemplate::getInstance()->display('layout.tpl'); // after we've displayed them, we may reset them Session::resetErrorMsg(); Session::resetSuccessMsg(); }