예제 #1
0
 /**
  * Set up groups of files as sources
  * 
  * @param array $options controller and Minify options
  * @return array Minify options
  * 
  */
 public function setupSources($options)
 {
     // PHP insecure by default: realpath() and other FS functions can't handle null bytes.
     if (isset($_GET['files'])) {
         $_GET['files'] = str_replace("", '', (string) $_GET['files']);
     }
     self::_setupDefines();
     if (MINIFY_USE_CACHE) {
         $cacheDir = defined('MINIFY_CACHE_DIR') ? MINIFY_CACHE_DIR : '';
         Minify0_Minify::setCache($cacheDir);
     }
     $options['badRequestHeader'] = 'HTTP/1.0 404 Not Found';
     $options['contentTypeCharset'] = MINIFY_ENCODING;
     // The following restrictions are to limit the URLs that minify will
     // respond to. Ideally there should be only one way to reference a file.
     if (!isset($_GET['files']) || !preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) || strpos($_GET['files'], '//') !== false || strpos($_GET['files'], '\\') !== false || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files'])) {
         return $options;
     }
     $files = explode(',', $_GET['files']);
     if (count($files) > MINIFY_MAX_FILES) {
         return $options;
     }
     // strings for prepending to relative/absolute paths
     $prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) . DIRECTORY_SEPARATOR;
     $prependAbsPaths = $_SERVER['DOCUMENT_ROOT'];
     $goodFiles = array();
     $hasBadSource = false;
     $allowDirs = isset($options['allowDirs']) ? $options['allowDirs'] : MINIFY_BASE_DIR;
     foreach ($files as $file) {
         // prepend appropriate string for abs/rel paths
         $file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file;
         // make sure a real file!
         $file = realpath($file);
         // don't allow unsafe or duplicate files
         if (parent::_fileIsSafe($file, $allowDirs) && !in_array($file, $goodFiles)) {
             $goodFiles[] = $file;
             $srcOptions = array('filepath' => $file);
             $this->sources[] = new Minify_Source($srcOptions);
         } else {
             $hasBadSource = true;
             break;
         }
     }
     if ($hasBadSource) {
         $this->sources = array();
     }
     if (!MINIFY_REWRITE_CSS_URLS) {
         $options['rewriteCssUris'] = false;
     }
     return $options;
 }
 /**
  * Runs minify
  *
  * @param string|null $file
  *
  * @return void
  */
 function process($file = NULL, $quiet = false)
 {
     /**
      * Check for rewrite test request
      */
     $rewrite_marker = 'rewrite_test.css';
     if (substr($file, strlen($file) - strlen($rewrite_marker)) == $rewrite_marker) {
         echo 'Minify OK';
         exit;
     }
     $filelength_test_marker = 'XXX.css';
     if (substr($file, strlen($file) - strlen($filelength_test_marker)) == $filelength_test_marker) {
         $cache = $this->_get_cache();
         header('Content-type: text/css');
         if (!$cache->store(basename($file), array('content' => 'content ok'))) {
             echo 'error storing';
         } else {
             if (function_exists('gzencode') && $this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('browsercache.cssjs.compression')) {
                 if (!$cache->store(basename($file) . '.gzip', array('content' => gzencode('content ok')))) {
                     echo 'error storing';
                     exit;
                 }
             }
             $v = $cache->fetch(basename($file));
             if ($v['content'] == 'content ok') {
                 echo 'content ok';
             } else {
                 echo 'error storing';
             }
         }
         exit;
     }
     // remove querystring
     if (preg_match('~(.+)(\\?x[0-9]{5})$~', $file, $m)) {
         $file = $m[1];
     }
     // remove blog_id
     $levels = '';
     if (defined('W3TC_BLOG_LEVELS')) {
         for ($n = 0; $n < W3TC_BLOG_LEVELS; $n++) {
             $levels .= '[0-9]+\\/';
         }
     }
     if (preg_match('~^(' . $levels . '[0-9]+)\\/(.+)$~', $file, $matches)) {
         $file = $matches[2];
     }
     // normalize according to browsercache
     $file = Dispatcher::requested_minify_filename($this->_config, $file);
     // parse file
     $hash = '';
     $matches = null;
     $location = '';
     $type = '';
     if (preg_match('~^' . MINIFY_AUTO_FILENAME_REGEX . '$~', $file, $matches)) {
         list(, $hash, $type) = $matches;
     } elseif (preg_match('~^' . MINIFY_MANUAL_FILENAME_REGEX . '$~', $file, $matches)) {
         list(, $theme, $template, $location, , , $type) = $matches;
     } else {
         return $this->finish_with_error(sprintf('Bad file param format: "%s"', $file), $quiet, false);
     }
     /**
      * Set cache engine
      */
     $cache = $this->_get_cache();
     \Minify0_Minify::setCache($cache);
     /**
      * Set cache ID
      */
     $cache_id = $this->get_cache_id($file);
     \Minify0_Minify::setCacheId($file);
     /**
      * Set logger
      */
     \Minify_Logger::setLogger(array($this, 'debug_error'));
     /**
      * Set options
      */
     $browsercache = $this->_config->get_boolean('browsercache.enabled');
     $serve_options = array_merge($this->_config->get_array('minify.options'), array('debug' => $this->_config->get_boolean('minify.debug'), 'maxAge' => $this->_config->get_integer('browsercache.cssjs.lifetime'), 'encodeOutput' => $browsercache && !defined('W3TC_PAGECACHE_OUTPUT_COMPRESSION_OFF') && !$quiet && $this->_config->get_boolean('browsercache.cssjs.compression'), 'bubbleCssImports' => $this->_config->get_string('minify.css.imports') == 'bubble', 'processCssImports' => $this->_config->get_string('minify.css.imports') == 'process', 'cacheHeaders' => array('use_etag' => $browsercache && $this->_config->get_boolean('browsercache.cssjs.etag'), 'expires_enabled' => $browsercache && $this->_config->get_boolean('browsercache.cssjs.expires'), 'cacheheaders_enabled' => $browsercache && $this->_config->get_boolean('browsercache.cssjs.cache.control'), 'cacheheaders' => $this->_config->get_string('browsercache.cssjs.cache.policy')), 'quiet' => $quiet));
     /**
      * Set sources
      */
     if ($hash) {
         $_GET['f_array'] = $this->minify_filename_to_filenames_for_minification($hash, $type);
         $_GET['ext'] = $type;
     } else {
         $_GET['g'] = $location;
         $serve_options['minApp']['groups'] = $this->get_groups($theme, $template, $type);
     }
     /**
      * Set minifier
      */
     $w3_minifier = Dispatcher::component('Minify_ContentMinifier');
     if ($type == 'js') {
         $minifier_type = 'application/x-javascript';
         switch (true) {
             case ($hash || $location == 'include') && $this->_config->get_boolean('minify.js.combine.header'):
             case $location == 'include-body' && $this->_config->get_boolean('minify.js.combine.body'):
             case $location == 'include-footer' && $this->_config->get_boolean('minify.js.combine.footer'):
                 $engine = 'combinejs';
                 break;
             default:
                 $engine = $this->_config->get_string('minify.js.engine');
                 if (!$w3_minifier->exists($engine) || !$w3_minifier->available($engine)) {
                     $engine = 'js';
                 }
                 break;
         }
     } elseif ($type == 'css') {
         $minifier_type = 'text/css';
         if (($hash || $location == 'include') && $this->_config->get_boolean('minify.css.combine')) {
             $engine = 'combinecss';
         } else {
             $engine = $this->_config->get_string('minify.css.engine');
             if (!$w3_minifier->exists($engine) || !$w3_minifier->available($engine)) {
                 $engine = 'css';
             }
         }
     }
     /**
      * Initialize minifier
      */
     $w3_minifier->init($engine);
     $serve_options['minifiers'][$minifier_type] = $w3_minifier->get_minifier($engine);
     $serve_options['minifierOptions'][$minifier_type] = $w3_minifier->get_options($engine);
     /**
      * Send X-Powered-By header
      */
     if (!$quiet && $browsercache && $this->_config->get_boolean('browsercache.cssjs.w3tc')) {
         @header('X-Powered-By: ' . Util_Environment::w3tc_header());
     }
     if (empty($_GET['f_array']) && empty($_GET['g'])) {
         return $this->finish_with_error('Nothing to minify', $quiet, false);
     }
     /**
      * Minify!
      */
     $return = array();
     try {
         $return = \Minify0_Minify::serve('MinApp', $serve_options);
     } catch (\Exception $exception) {
         return $this->finish_with_error($exception->getMessage(), $quiet);
     }
     if (!is_null(\Minify0_Minify::$recoverableError)) {
         $this->_handle_error(\Minify0_Minify::$recoverableError);
     }
     $state = Dispatcher::config_state_master();
     if (!$this->_error_occurred && $state->get_boolean('minify.show_note_minify_error')) {
         $error_file = $state->get_string('minify.error.file');
         if ($error_file == $file) {
             $state->set('minify.show_note_minify_error', false);
             $state->save();
         }
     }
     return $return;
 }