* @license PHP License * @package WB * @subpackage service */ WBClass::load( 'WBService' ); /** * Service: deliver JavaScript file(s) * * @version 1.3.1 * @package WB * @subpackage service */ class WBService_JavaScript extends WBService { /** * my part * @var string */ protected $part = ''; /** * decide whether to start locale tools * @var bool */ protected $useI18n = false; /** * decide whether to start WBConfig * @var bool */ protected $useConfig = false; /** * Display * * @param int $status * @param mixed $data to be send * @param string $checksum * @return bool true */ public function run(&$status, &$data, &$checksum = null) { // make session read only to avoid blocking further requests $this->sess->close(); $js = $this->part; if (!empty($this->path)) { $js .= '/' . implode('/', $this->path); } WBClass::load('WBHtml_JS','WBException_Argument'); // find location of JavaScript file $file = ''; $type = WBHtml_JS::TYPE_JS; if (empty($js)) { // cache for more than a year: 60 seconds × 60 minutes × 24 hours × 365 days = 31536000 seconds. $this->res->setMaxAge(31536000); $bulk = $this->req->get('bulk', ''); if (empty($bulk)) { $file = WBHtml_JS::getBulkPath($this->req->get('cs')); } else { $conf = WBClass::create('WBConfig'); if ($conf->load('site/javascript/' . $bulk, true)) { $list = array(); $inc = $conf->get('javascript/include', array()); foreach ($inc as $i) { $list[] = array( 'type' => 'file', 'load' => $i ); } $file = WBHtml_JS::makeBulk('bulk-' . $bulk, $list); } else { $file = ''; } } } else { try { $file = WBHtml_JS::realpath($js, $type); } catch (WBException_Argument $e) { // avoid escape from base/system dir jail $data = <<res->addHeader('Content-Type', 'application/x-javascript; charset=utf-8;'); $status = 403; return true; } } // check for file if (empty($file)) { $data = <<res->addHeader('Content-Type', 'application/x-javascript; charset=utf-8;'); return true; } // send proper header if ($type == WBHtml_JS::TYPE_JS) { $this->res->addHeader('Content-Type', 'application/x-javascript; charset=utf-8;'); // minimize Javascript if (WBParam::get('wb/html/compress', 'minimize') == 'minimize') { $file = $this->minimize($file); } } if ($type == WBHtml_JS::TYPE_CSS) { $this->res->addHeader('Content-Type', 'text/css; charset=utf-8;'); } $checksum = md5_file($file); $data = fopen($file, 'r'); $status = 200; return true; } /** * use JSMin to compress JavaScript * * http://www.crockford.com/javascript/jsmin.html * * @param $file * @return $file */ protected function minimize($file) { $cache = WBParam::get('wb/dir/base') . '/var/cache/javascript/min'; if (!is_dir($cache)) { mkdir($cache, 0777, true); chmod($cache, 0777); } $cache .= '/' . md5($file); if (file_exists($cache) && filemtime($cache) > filemtime($file)) { return $cache; } // load Minify class from resources if (!class_exists('\MatthiasMullie\Minify', false)) { $inc = WBParam::get('wb/dir/system') . '/resource/php/' . 'MatthiasMullie/Minify.php'; include_once $inc; $inc = WBParam::get('wb/dir/system') . '/resource/php/' . 'MatthiasMullie/JS.php'; include_once $inc; $inc = WBParam::get('wb/dir/system') . '/resource/php/' . 'MatthiasMullie/Exception.php'; include_once $inc; } $cnt = file_get_contents($file); $log = array( 'service' => 'JavaScript', 'action' => 'minimize', 'file' => $file, 'size' => strlen($cnt), 'minimized' => '' ); try { $minifier = new \MatthiasMullie\Minify\JS(); $minifier->add($cnt); $min = $minifier->minify(); $log['minimized'] = strlen($min); $this->log->notice($log); } catch (Exception $e) { $log['minimized'] = 'failed'; $this->log->warn($log); $min = <<