diff --git a/HISTORY.md b/HISTORY.md index 21c3691..90cc7ad 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,12 +1,15 @@ -## 3.0 progress -* Better CSS minification via Túbal Martín's CSSMin -* Docs overhaul -* New API incompatible with the 2.x versions +## Version 3.0.0 (unreleased) +* The project root is now what is deployed as `min` * Installation requires use of Composer to install dependencies +* Removes JSMin+ (unmaintained, high memory usage) +* Removes DooDigestAuth +* Removes Minify_Loader (uses Composer) +* Removes Minify_Logger (uses Monolog) +* The Minify, source, and controller components have changed APIs +* Better CSS minification via Túbal Martín's CSSMin * Add config option for simply concatenating files * Add config option for altering creation of Minify/MinApp objects * Missing spec no longer redirects, instead links to docs -* Removed JSMin+ (unmaintained, high memory usage) ## Version 2.2.1 (2014-10-30) * Builder styled with Bootstrap (thanks to help from acidvertigo) diff --git a/bootstrap.php b/bootstrap.php index a715ffa..d4dda6d 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,8 +1,6 @@ config; // recommend $min_symlinks setting for Apache UserDir $symlinkOption = ''; -if (0 === strpos($_SERVER["SERVER_SOFTWARE"], 'Apache/') - && preg_match('@^/\\~(\\w+)/@', $_SERVER['REQUEST_URI'], $m) +if (0 === strpos($app->env->server("SERVER_SOFTWARE"), 'Apache/') + && preg_match('@^/\\~(\\w+)/@', $app->env->server('REQUEST_URI'), $m) ) { $userDir = DIRECTORY_SEPARATOR . $m[1] . DIRECTORY_SEPARATOR; if (false !== strpos(__FILE__, $userDir)) { @@ -18,24 +19,19 @@ if (0 === strpos($_SERVER["SERVER_SOFTWARE"], 'Apache/') } } -require __DIR__ . '/../bootstrap.php'; -require __DIR__ . '/../config.php'; - -if (! $min_enableBuilder) { +if (!$config->enableBuilder) { header('Content-Type: text/plain'); die('This application is not enabled. See https://github.com/mrclay/minify/blob/master/docs/BuilderApp.wiki.md'); } -if (isset($min_builderPassword) - && is_string($min_builderPassword) - && $min_builderPassword !== '') { - DooDigestAuth::http_auth('Minify Builder', array('admin' => $min_builderPassword)); -} - -$cachePathCode = ''; -if (! isset($min_cachePath) && ! function_exists('sys_get_temp_dir')) { - $detectedTmp = Minify_Cache_File::tmp(); - $cachePathCode = "\$min_cachePath = " . var_export($detectedTmp, 1) . ';'; +if ($config->builderPassword && $config->builderPassword !== '') { + $auth = new Intervention\Httpauth\Httpauth(array( + 'username' => 'admin', + 'password' => $config->builderPassword, + 'type' => 'digest', + 'realm' => 'Minify Builder', + )); + $auth->secure(); } ob_start(); @@ -79,13 +75,6 @@ b {color:#c00} FirePHP console will report the cause of the error.

- -

Note: was discovered as a usable temp directory.
To - slightly improve performance you can hardcode this in /min/config.php: -

- -

Note: Your webserver does not seem to support mod_rewrite (used in /min/.htaccess). Your Minify URIs will contain "?", which

-

+

@@ -218,26 +207,8 @@ by Minify. E.g. @import "/min/?g=css2";< $min_uploaderHoursBehind, -)); - -$controller = new Minify_Controller_Page($env, $sourceFactory); - -$server = new Minify($cache); - -$server->serve($controller, array( +$controller = new Minify_Controller_Page($app->env, $app->sourceFactory); +$minify = $app->minify->serve($controller, array( 'content' => $content, 'id' => __FILE__, 'lastModifiedTime' => max( @@ -247,5 +218,4 @@ $server->serve($controller, array( filemtime(__DIR__ . '/../lib/Minify.php') ), 'minifyAll' => true, - 'encodeOutput' => $encodeOutput, )); diff --git a/builder/ocCheck.php b/builder/ocCheck.php index 799a632..9f8475c 100644 --- a/builder/ocCheck.php +++ b/builder/ocCheck.php @@ -5,18 +5,18 @@ * @package Minify */ -require __DIR__ . '/../bootstrap.php'; +$app = (require __DIR__ . '/../bootstrap.php'); +/* @var \Minify\App $app */ $_oc = ini_get('zlib.output_compression'); // allow access only if builder is enabled -require __DIR__ . '/../config.php'; -if (! $min_enableBuilder) { +if (!$app->config->enableBuilder) { header('Location: /'); exit; } -if (isset($_GET['hello'])) { +if ($app->env->get('hello')) { // echo 'World!' // try to prevent double encoding (may not have an effect) diff --git a/composer.json b/composer.json index 7842db1..8792065 100644 --- a/composer.json +++ b/composer.json @@ -23,10 +23,13 @@ "classmap": ["tests/TestCase.php"] }, "require": { + "php": ">=5.3.0", "ext-pcre": "*", "firephp/firephp-core": "~0.4.0", + "intervention/httpauth": "~2.0", + "monolog/monolog": "~1.1", "mrclay/jsmin-php": "~2", - "php": ">=5.3.0", + "mrclay/props-dic": "^2.2", "tubalmartin/cssmin": "~2.4.8" }, "require-dev": { diff --git a/config.php b/config.php index d731c6f..530a196 100644 --- a/config.php +++ b/config.php @@ -27,12 +27,8 @@ $min_builderPassword = 'admin'; /** - * Set to true to log messages to FirePHP (Firefox Firebug addon). + * Set to true to log messages to FirePHP (Firefox Firebug addon) and PHP's error_log * Set to false for no error logging (Minify may be slightly faster). - * @link http://www.firephp.org/ - * - * If you want to use a custom error logger, set this to your logger - * instance. Your object should have a method log(string $message). */ $min_errorLogger = false; @@ -193,9 +189,6 @@ $min_uploaderHoursBehind = 0; * * You can see the default implementations (and what gets passed in) in index.php. */ -//$min_factories['minify'] = ... a callable -//$min_factories['controller'] = ... a callable +//$min_factories['minify'] = ... a callable accepting a Minify\App object +//$min_factories['controller'] = ... a callable accepting a Minify\App object - -// try to disable output_compression (may not have an effect) -ini_set('zlib.output_compression', '0'); diff --git a/groupsConfig.php b/groupsConfig.php index c4cb4b0..cc80538 100644 --- a/groupsConfig.php +++ b/groupsConfig.php @@ -12,8 +12,8 @@ **/ return array( -// 'testJs' => array('//minify/min/quick-test.js'), -// 'testCss' => array('//minify/min/quick-test.css'), +// 'testJs' => array('//minify/quick-test.js'), +// 'testCss' => array('//minify/quick-test.css'), // 'js' => array('//js/file1.js', '//js/file2.js'), // 'css' => array('//css/file1.css', '//css/file2.css'), -); \ No newline at end of file +); diff --git a/index.php b/index.php index 938a49b..7b58bcc 100644 --- a/index.php +++ b/index.php @@ -7,127 +7,7 @@ * @package Minify */ -require __DIR__ . '/bootstrap.php'; +$app = (require __DIR__ . '/bootstrap.php'); +/* @var \Minify\App $app */ -// set config path defaults -$min_configPaths = array( - 'base' => __DIR__ . '/config.php', - 'test' => __DIR__ . '/config-test.php', - 'groups' => __DIR__ . '/groupsConfig.php', -); - -// check for custom config paths -if (!empty($min_customConfigPaths) && is_array($min_customConfigPaths)) { - $min_configPaths = array_merge($min_configPaths, $min_customConfigPaths); -} - -// load config -require $min_configPaths['base']; - -if (isset($_GET['test'])) { - include $min_configPaths['test']; -} - -// setup factories -$defaultFactories = array( - 'minify' => function (Minify_CacheInterface $cache) { - return new Minify($cache); - }, - 'controller' => function (Minify_Env $env, Minify_Source_Factory $sourceFactory) { - return new Minify_Controller_MinApp($env, $sourceFactory); - }, -); -if (!isset($min_factories)) { - $min_factories = array(); -} -$min_factories = array_merge($defaultFactories, $min_factories); - -// use an environment object to encapsulate all input -$server = $_SERVER; -if ($min_documentRoot) { - $server['DOCUMENT_ROOT'] = $min_documentRoot; -} -$env = new Minify_Env(array( - 'server' => $server, -)); - -// TODO probably should do this elsewhere... -$min_serveOptions['minifierOptions']['text/css']['docRoot'] = $env->getDocRoot(); -$min_serveOptions['minifierOptions']['text/css']['symlinks'] = $min_symlinks; -$min_serveOptions['minApp']['symlinks'] = $min_symlinks; -// auto-add targets to allowDirs -foreach ($min_symlinks as $uri => $target) { - $min_serveOptions['minApp']['allowDirs'][] = $target; -} - -if ($min_allowDebugFlag) { - // TODO get rid of static stuff - $min_serveOptions['debug'] = Minify_DebugDetector::shouldDebugRequest($env); -} - -if (!empty($min_concatOnly)) { - $min_serveOptions['concatOnly'] = true; -} - -if ($min_errorLogger) { - if (true === $min_errorLogger) { - $min_errorLogger = FirePHP::getInstance(true); - } - // TODO get rid of global state - Minify_Logger::setLogger($min_errorLogger); -} - -// check for URI versioning -if (null !== $env->get('v') || preg_match('/&\\d/', $env->server('QUERY_STRING'))) { - $min_serveOptions['maxAge'] = 31536000; -} - -// need groups config? -if (null !== $env->get('g')) { - // we need groups config - $min_serveOptions['minApp']['groups'] = (require $min_configPaths['groups']); -} - -// cache defaults -if (!isset($min_cachePath)) { - $min_cachePath = ''; -} -if (!isset($min_cacheFileLocking)) { - $min_cacheFileLocking = true; -} -if (is_string($min_cachePath)) { - $cache = new Minify_Cache_File($min_cachePath, $min_cacheFileLocking); -} else { - // assume it meets interface. - $cache = $min_cachePath; -} -/* @var Minify_CacheInterface $cache */ - -$minify = call_user_func($min_factories['minify'], $cache); -/* @var Minify $minify */ - -if (!$env->get('f') && $env->get('g') === null) { - // no spec given - $msg = '

No "f" or "g" parameters were detected.

'; - $url = 'https://github.com/mrclay/minify/blob/master/docs/CommonProblems.wiki.md#long-url-parameters-are-ignored'; - $defaults = $minify->getDefaultOptions(); - $minify->errorExit($defaults['badRequestHeader'], $url, $msg); -} - -$sourceFactoryOptions = array(); - -// translate legacy setting to option for source factory -if (isset($min_serveOptions['minApp']['noMinPattern'])) { - $sourceFactoryOptions['noMinPattern'] = $min_serveOptions['minApp']['noMinPattern']; -} - -if (isset($min_serveOptions['minApp']['allowDirs'])) { - $sourceFactoryOptions['allowDirs'] = $min_serveOptions['minApp']['allowDirs']; -} - -$sourceFactory = new Minify_Source_Factory($env, $sourceFactoryOptions, $cache); - -$controller = call_user_func($min_factories['controller'], $env, $sourceFactory); -/* @var Minify_ControllerInterface $controller */ - -$minify->serve($controller, $min_serveOptions); +$app->runServer(); diff --git a/lib/DooDigestAuth.php b/lib/DooDigestAuth.php deleted file mode 100644 index b979009..0000000 --- a/lib/DooDigestAuth.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @link http://www.doophp.com/ - * @copyright Copyright © 2009 Leng Sheng Hong - * @license http://www.doophp.com/license - */ - -/** - * Handles HTTP digest authentication - * - *

HTTP digest authentication can be used with the URI router. - * HTTP digest is much more recommended over the use of HTTP Basic auth which doesn't provide any encryption. - * If you are running PHP on Apache in CGI/FastCGI mode, you would need to - * add the following line to your .htaccess for digest auth to work correctly.

- * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] - * - *

This class is tested under Apache 2.2 and Cherokee web server. It should work in both mod_php and cgi mode.

- * - * @author Leng Sheng Hong - * @version $Id: DooDigestAuth.php 1000 2009-07-7 18:27:22 - * @package doo.auth - * @since 1.0 - */ -class DooDigestAuth{ - - /** - * Authenticate against a list of username and passwords. - * - *

HTTP Digest Authentication doesn't work with PHP in CGI mode, - * you have to add this into your .htaccess RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

- * - * @param string $realm Name of the authentication session - * @param array $users An assoc array of username and password: array('uname1'=>'pwd1', 'uname2'=>'pwd2') - * @param string $fail_msg Message to be displayed if the User cancel the login - * @param string $fail_url URL to be redirect if the User cancel the login - * @return string The username if login success. - */ - public static function http_auth($realm, $users, $fail_msg=NULL, $fail_url=NULL) { - $realm = "Restricted area - $realm"; - - //user => password - //$users = array('admin' => '1234', 'guest' => 'guest'); - if(!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && strpos($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 'Digest')===0){ - $_SERVER['PHP_AUTH_DIGEST'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; - } - - if (empty($_SERVER['PHP_AUTH_DIGEST'])) { - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - header('HTTP/1.1 401 Unauthorized'); - if($fail_msg!=NULL) - die($fail_msg); - if($fail_url!=NULL) - die(""); - exit; - } - - // analyze the PHP_AUTH_DIGEST variable - if (!($data = self::http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])){ - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - header('HTTP/1.1 401 Unauthorized'); - if($fail_msg!=NULL) - die($fail_msg); - if($fail_url!=NULL) - die(""); - exit; - } - - // generate the valid response - $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]); - $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']); - $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); - - if ($data['response'] != $valid_response){ - header('HTTP/1.1 401 Unauthorized'); - header('WWW-Authenticate: Digest realm="'.$realm. - '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); - if($fail_msg!=NULL) - die($fail_msg); - if($fail_url!=NULL) - die(""); - exit; - } - - // ok, valid username & password - return $data['username']; - } - - /** - * Method to parse the http auth header, works with IE. - * - * Internet Explorer returns a qop="xxxxxxxxxxx" in the header instead of qop=xxxxxxxxxxx as most browsers do. - * - * @param string $txt header string to parse - * @return array An assoc array of the digest auth session - */ - private static function http_digest_parse($txt) - { - $res = preg_match("/username=\"([^\"]+)\"/i", $txt, $match); - $data['username'] = (isset($match[1]))?$match[1]:null; - $res = preg_match('/nonce=\"([^\"]+)\"/i', $txt, $match); - $data['nonce'] = $match[1]; - $res = preg_match('/nc=([0-9]+)/i', $txt, $match); - $data['nc'] = $match[1]; - $res = preg_match('/cnonce=\"([^\"]+)\"/i', $txt, $match); - $data['cnonce'] = $match[1]; - $res = preg_match('/qop=([^,]+)/i', $txt, $match); - $data['qop'] = str_replace('"','',$match[1]); - $res = preg_match('/uri=\"([^\"]+)\"/i', $txt, $match); - $data['uri'] = $match[1]; - $res = preg_match('/response=\"([^\"]+)\"/i', $txt, $match); - $data['response'] = $match[1]; - - return $data; - } - -} diff --git a/lib/Minify.php b/lib/Minify.php index 8ecc4d8..4909dca 100644 --- a/lib/Minify.php +++ b/lib/Minify.php @@ -4,6 +4,8 @@ * @package Minify */ +use Psr\Log\LoggerInterface; + /** * Minify - Combines, minifies, and caches JavaScript and CSS files on demand. * @@ -64,10 +66,17 @@ class Minify { protected $options = null; /** - * @param Minify_CacheInterface $cache + * @var LoggerInterface|null */ - public function __construct(Minify_CacheInterface $cache) { + protected $logger = null; + + /** + * @param Minify_CacheInterface $cache + * @param LoggerInterface $logger + */ + public function __construct(Minify_CacheInterface $cache, LoggerInterface $logger = null) { $this->cache = $cache; + $this->logger = $logger; } /** @@ -209,6 +218,10 @@ class Minify { $this->selectionId = $config->getSelectionId(); $this->options = $this->analyzeSources($config->getOptions()); + if (!$this->options['quiet'] && !headers_sent()) { + ini_set('zlib.output_compression', '0'); + } + // check request validity if (!$this->sources) { // invalid request! @@ -321,7 +334,7 @@ class Minify { try { $content = $this->combineMinify(); } catch (Exception $e) { - $this->controller->log($e->getMessage()); + $this->logger && $this->logger->critical($e->getMessage()); if (! $this->options['quiet']) { $this->errorExit($this->options['errorHeader'], self::URL_DEBUG); } @@ -338,7 +351,7 @@ class Minify { try { $content = $this->combineMinify(); } catch (Exception $e) { - $this->controller->log($e->getMessage()); + $this->logger && $this->logger->critical($e->getMessage()); if (! $this->options['quiet']) { $this->errorExit($this->options['errorHeader'], self::URL_DEBUG); } @@ -413,7 +426,7 @@ class Minify { $sourceFactory = new Minify_Source_Factory($env, array( 'checkAllowDirs' => false, ), $this->cache); - $controller = new Minify_Controller_Files($env, $sourceFactory); + $controller = new Minify_Controller_Files($env, $sourceFactory, $this->logger); $options = array_merge($options, array( 'files' => (array)$sources, @@ -675,11 +688,10 @@ class Minify { if (!empty($options['contentType'])) { // just verify sources have null content type or match the options if ($sourceType !== null && $sourceType !== $options['contentType']) { - // TODO better logging - Minify_Logger::log('ContentType mismatch'); + + $this->logger && $this->logger->warning('ContentType mismatch'); $this->sources = array(); - return $options; } @@ -690,11 +702,9 @@ class Minify { $type = $sourceType; } elseif ($sourceType !== $type) { - // TODO better logging - Minify_Logger::log('ContentType mismatch'); + $this->logger && $this->logger->warning('ContentType mismatch'); $this->sources = array(); - return $options; } } diff --git a/lib/Minify/App.php b/lib/Minify/App.php new file mode 100644 index 0000000..f018460 --- /dev/null +++ b/lib/Minify/App.php @@ -0,0 +1,258 @@ +dir = rtrim($dir, '/\\'); + + $this->cache = function (App $app) use ($that) { + $config = $app->config; + + if ($config->cachePath instanceof \Minify_CacheInterface) { + return $config->cachePath; + } + + if (!$config->cachePath || is_string($config->cachePath)) { + return new \Minify_Cache_File($config->cachePath, $config->cacheFileLocking, $app->logger); + } + + $type = $that->typeOf($config->cachePath); + throw new \RuntimeException('$min_cachePath must be a path or implement Minify_CacheInterface.' + . " Given $type"); + }; + + $this->config = function (App $app) { + $config = (require $app->configPath); + + if ($config instanceof \Minify\Config) { + return $config; + } + + // copy from vars into properties + + $config = new \Minify\Config(); + + $propNames = array_keys(get_object_vars($config)); + + $varNames = array_map(function ($name) { + return "min_$name"; + }, $propNames); + + $vars = compact($varNames); + + foreach ($varNames as $varName) { + if (isset($vars[$varName])) { + $config->{substr($varName, 4)} = $vars[$varName]; + } + } + + return $config; + }; + + $this->configPath = "{$this->dir}/config.php"; + + $this->controller = function (App $app) use ($that) { + $config = $app->config; + + if (empty($config->factories['controller'])) { + $ctrl = new \Minify_Controller_MinApp($app->env, $app->sourceFactory, $app->logger); + } else { + $ctrl = call_user_func($config->factories['controller'], $app); + } + + if ($ctrl instanceof \Minify_ControllerInterface) { + return $ctrl; + } + + $type = $that->typeOf($ctrl); + throw new \RuntimeException('$min_factories["controller"] callable must return an implementation' + ." of Minify_CacheInterface. Returned $type"); + }; + + $this->docRoot = function (App $app) { + $config = $app->config; + if (empty($config->documentRoot)) { + return $app->env->getDocRoot(); + } + return rtrim($config->documentRoot, '/\\'); + }; + + $this->env = function (App $app) { + $config = $app->config; + $envArgs = empty($config->envArgs) ? array() : $config->envArgs; + return new \Minify_Env($envArgs); + }; + + $this->errorLogHandler = function (App $app) { + $format = "%channel%.%level_name%: %message% %context% %extra%"; + $handler = new \Monolog\Handler\ErrorLogHandler(); + $handler->setFormatter(new \Monolog\Formatter\LineFormatter($format)); + return $handler; + }; + + $this->groupsConfig = function (App $app) { + return (require $app->groupsConfigPath); + }; + + $this->groupsConfigPath = "{$this->dir}/groupsConfig.php"; + + $this->logger = function (App $app) use ($that) { + $value = $app->config->errorLogger; + + if ($value instanceof \Psr\Log\LoggerInterface) { + return $value; + } + + $logger = new \Monolog\Logger('minify'); + + if (!$value) { + return $logger; + } + + if ($value === true || $value instanceof \FirePHP) { + $logger->pushHandler($app->errorLogHandler); + $logger->pushHandler(new \Monolog\Handler\FirePHPHandler()); + return $logger; + } + + if ($value instanceof \Monolog\Handler\HandlerInterface) { + $logger->pushHandler($value); + return $logger; + } + + // BC + if (is_object($value) && is_callable(array($value, 'log'))) { + $handler = new \Minify\Logger\LegacyHandler($value); + $logger->pushHandler($handler); + return $logger; + } + + $type = $that->typeOf($value); + throw new \RuntimeException('If set, $min_errorLogger must be a PSR-3 logger or a Monolog handler.' + ." Given $type"); + }; + + $this->minify = function (App $app) use ($that) { + $config = $app->config; + + if (empty($config->factories['minify'])) { + return new \Minify($app->cache, $app->logger); + } + + $minify = call_user_func($config->factories['minify'], $app); + if ($minify instanceof \Minify) { + return $minify; + } + + $type = $that->typeOf($minify); + throw new \RuntimeException('$min_factories["minify"] callable must return a Minify object.' + ." Returned $type"); + }; + + $this->serveOptions = function (App $app) { + $config = $app->config; + $env = $app->env; + + $ret = $config->serveOptions; + + $ret['minifierOptions']['text/css']['docRoot'] = $app->docRoot; + $ret['minifierOptions']['text/css']['symlinks'] = $config->symlinks; + $ret['minApp']['symlinks'] = $config->symlinks; + + // auto-add targets to allowDirs + foreach ($config->symlinks as $uri => $target) { + $ret['minApp']['allowDirs'][] = $target; + } + + if ($config->allowDebugFlag) { + $ret['debug'] = \Minify_DebugDetector::shouldDebugRequest($env); + } + + if ($config->concatOnly) { + $ret['concatOnly'] = true; + } + + // check for URI versioning + if ($env->get('v') !== null || preg_match('/&\\d/', $app->env->server('QUERY_STRING'))) { + $ret['maxAge'] = 31536000; + } + + // need groups config? + if ($env->get('g') !== null) { + $ret['minApp']['groups'] = $app->groupsConfig; + } + + return $ret; + }; + + $this->sourceFactory = function (App $app) { + return new \Minify_Source_Factory($app->env, $app->sourceFactoryOptions, $app->cache); + }; + + $this->sourceFactoryOptions = function (App $app) { + $serveOptions = $app->serveOptions; + $ret = array(); + + // translate legacy setting to option for source factory + if (isset($serveOptions['minApp']['noMinPattern'])) { + $ret['noMinPattern'] = $serveOptions['minApp']['noMinPattern']; + } + + if (isset($serveOptions['minApp']['allowDirs'])) { + $ret['allowDirs'] = $serveOptions['minApp']['allowDirs']; + } + + if (is_numeric($app->config->uploaderHoursBehind)) { + $ret['uploaderHoursBehind'] = $app->config->uploaderHoursBehind; + } + + return $ret; + }; + } + + public function runServer() { + if (!$this->env->get('f') && $this->env->get('g') === null) { + // no spec given + $msg = '

No "f" or "g" parameters were detected.

'; + $url = 'https://github.com/mrclay/minify/blob/master/docs/CommonProblems.wiki.md#long-url-parameters-are-ignored'; + $defaults = $this->minify->getDefaultOptions(); + $this->minify->errorExit($defaults['badRequestHeader'], $url, $msg); + } + + $this->minify->serve($this->controller, $this->serveOptions); + } + + /** + * @param mixed $var + * @return string + */ + private function typeOf($var) { + $type = gettype($var); + return $type === 'object' ? get_class($var) : $type; + } +} diff --git a/lib/Minify/Cache/File.php b/lib/Minify/Cache/File.php index d4b6f42..cb3a082 100644 --- a/lib/Minify/Cache/File.php +++ b/lib/Minify/Cache/File.php @@ -4,15 +4,42 @@ * @package Minify */ +use Psr\Log\LoggerInterface; + class Minify_Cache_File implements Minify_CacheInterface { - public function __construct($path = '', $fileLocking = false) + /** + * @var string + */ + private $path; + + /** + * @var bool + */ + private $locking; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param string $path + * @param bool $fileLocking + * @param LoggerInterface $logger + */ + public function __construct($path = '', $fileLocking = false, LoggerInterface $logger = null) { if (! $path) { - $path = self::tmp(); + $path = sys_get_temp_dir(); } - $this->_locking = $fileLocking; - $this->_path = $path; + $this->locking = $fileLocking; + $this->path = $path; + + if (!$logger) { + $logger = new \Monolog\Logger('minify'); + } + $this->logger = $logger; } /** @@ -26,18 +53,17 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function store($id, $data) { - $flag = $this->_locking + $flag = $this->locking ? LOCK_EX : null; - $file = $this->_path . '/' . $id; + $file = $this->path . '/' . $id; if (! @file_put_contents($file, $data, $flag)) { - $this->_log("Minify_Cache_File: Write failed to '$file'"); + $this->logger->warning("Minify_Cache_File: Write failed to '$file'"); } // write control if ($data !== $this->fetch($id)) { @unlink($file); - $this->_log("Minify_Cache_File: Post-write read failed for '$file'"); - + $this->logger->warning("Minify_Cache_File: Post-write read failed for '$file'"); return false; } @@ -53,7 +79,7 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function getSize($id) { - return filesize($this->_path . '/' . $id); + return filesize($this->path . '/' . $id); } /** @@ -67,7 +93,7 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function isValid($id, $srcMtime) { - $file = $this->_path . '/' . $id; + $file = $this->path . '/' . $id; return (is_file($file) && (filemtime($file) >= $srcMtime)); } @@ -79,14 +105,14 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function display($id) { - if ($this->_locking) { - $fp = fopen($this->_path . '/' . $id, 'rb'); + if ($this->locking) { + $fp = fopen($this->path . '/' . $id, 'rb'); flock($fp, LOCK_SH); fpassthru($fp); flock($fp, LOCK_UN); fclose($fp); } else { - readfile($this->_path . '/' . $id); + readfile($this->path . '/' . $id); } } @@ -99,8 +125,8 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function fetch($id) { - if ($this->_locking) { - $fp = fopen($this->_path . '/' . $id, 'rb'); + if ($this->locking) { + $fp = fopen($this->path . '/' . $id, 'rb'); if (!$fp) { return false; } @@ -111,7 +137,7 @@ class Minify_Cache_File implements Minify_CacheInterface { return $ret; } else { - return file_get_contents($this->_path . '/' . $id); + return file_get_contents($this->path . '/' . $id); } } @@ -122,81 +148,30 @@ class Minify_Cache_File implements Minify_CacheInterface { */ public function getPath() { - return $this->_path; + return $this->path; } /** * Get a usable temp directory * - * Adapted from Solar/Dir.php - * @author Paul M. Jones - * @license http://opensource.org/licenses/bsd-license.php BSD - * @link http://solarphp.com/trac/core/browser/trunk/Solar/Dir.php - * * @return string + * @deprecated */ public static function tmp() { - static $tmp = null; - if (! $tmp) { - $tmp = function_exists('sys_get_temp_dir') - ? sys_get_temp_dir() - : self::_tmp(); - $tmp = rtrim($tmp, DIRECTORY_SEPARATOR); - } - - return $tmp; - } - - /** - * Returns the OS-specific directory for temporary files - * - * @author Paul M. Jones - * @license http://opensource.org/licenses/bsd-license.php BSD - * @link http://solarphp.com/trac/core/browser/trunk/Solar/Dir.php - * - * @return string - */ - protected static function _tmp() - { - // non-Windows system? - if (strtolower(substr(PHP_OS, 0, 3)) != 'win') { - $tmp = empty($_ENV['TMPDIR']) ? getenv('TMPDIR') : $_ENV['TMPDIR']; - if ($tmp) { - return $tmp; - } else { - return '/tmp'; - } - } - // Windows 'TEMP' - $tmp = empty($_ENV['TEMP']) ? getenv('TEMP') : $_ENV['TEMP']; - if ($tmp) { - return $tmp; - } - // Windows 'TMP' - $tmp = empty($_ENV['TMP']) ? getenv('TMP') : $_ENV['TMP']; - if ($tmp) { - return $tmp; - } - // Windows 'windir' - $tmp = empty($_ENV['windir']) ? getenv('windir') : $_ENV['windir']; - if ($tmp) { - return $tmp; - } - // final fallback for Windows - return getenv('SystemRoot') . '\\temp'; + trigger_error(__METHOD__ . ' is deprecated in Minfy 3.0', E_USER_DEPRECATED); + return sys_get_temp_dir(); } /** * Send message to the Minify logger * @param string $msg * @return null + * @deprecated Use $this->logger */ protected function _log($msg) { - Minify_Logger::log($msg); + trigger_error(__METHOD__ . ' is deprecated in Minify 3.0.', E_USER_DEPRECATED); + $this->logger->warning($msg); } - - private $_path = null; - private $_locking = null; } diff --git a/lib/Minify/Config.php b/lib/Minify/Config.php new file mode 100644 index 0000000..9f1e8b8 --- /dev/null +++ b/lib/Minify/Config.php @@ -0,0 +1,73 @@ +env = $env; $this->sourceFactory = $sourceFactory; + if (!$logger) { + $logger = new Logger('minify'); + } + $this->logger = $logger; } /** @@ -49,9 +62,11 @@ abstract class Minify_Controller_Base implements Minify_ControllerInterface { * @param string $msg * * @return null + * @deprecated use $this->logger */ public function log($msg) { - Minify_Logger::log($msg); + trigger_error(__METHOD__ . ' is deprecated in Minify 3.0.', E_USER_DEPRECATED); + $this->logger->info($msg); } } diff --git a/lib/Minify/Controller/Files.php b/lib/Minify/Controller/Files.php index d687305..da22bd3 100644 --- a/lib/Minify/Controller/Files.php +++ b/lib/Minify/Controller/Files.php @@ -4,6 +4,9 @@ * @package Minify */ +use Psr\Log\LoggerInterface; +use Monolog\Logger; + /** * Controller class for minifying a set of files * @@ -28,16 +31,6 @@ */ class Minify_Controller_Files extends Minify_Controller_Base { - /** - * @param Minify_Env $env Environment - * @param Minify_Source_Factory $sourceFactory Source factory. If you need to serve files from any path, this - * component must have its "checkAllowDirs" option set to false. - */ - public function __construct(Minify_Env $env, Minify_Source_Factory $sourceFactory) - { - parent::__construct($env, $sourceFactory); - } - /** * Set up file sources * @@ -62,16 +55,10 @@ class Minify_Controller_Files extends Minify_Controller_Base { $sources = array(); foreach ($files as $file) { - if ($file instanceof Minify_SourceInterface) { - $sources[] = $file; - continue; - } try { - $sources[] = $this->sourceFactory->makeSource(array( - 'filepath' => $file, - )); + $sources[] = $this->sourceFactory->makeSource($file); } catch (Minify_Source_FactoryException $e) { - $this->log($e->getMessage()); + $this->logger->error($e->getMessage()); return new Minify_ServeConfiguration($options); } diff --git a/lib/Minify/Controller/Groups.php b/lib/Minify/Controller/Groups.php index e911b88..5c415e0 100644 --- a/lib/Minify/Controller/Groups.php +++ b/lib/Minify/Controller/Groups.php @@ -51,7 +51,7 @@ class Minify_Controller_Groups extends Minify_Controller_Files { ); if (false === $pathInfo || ! isset($groups[$pathInfo])) { // no PATH_INFO or not a valid group - $this->log("Missing PATH_INFO or no group set for \"$pathInfo\""); + $this->logger->info("Missing PATH_INFO or no group set for \"$pathInfo\""); return new Minify_ServeConfiguration($options); } diff --git a/lib/Minify/Controller/MinApp.php b/lib/Minify/Controller/MinApp.php index 6517e8a..9ce168c 100644 --- a/lib/Minify/Controller/MinApp.php +++ b/lib/Minify/Controller/MinApp.php @@ -58,13 +58,13 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { $selectionId .= 'g=' . $get['g']; $keys = explode(',', $get['g']); if ($keys != array_unique($keys)) { - $this->log("Duplicate group key found."); + $this->logger->info("Duplicate group key found."); return new Minify_ServeConfiguration($options); } foreach ($keys as $key) { if (! isset($localOptions['groups'][$key])) { - $this->log("A group configuration for \"{$key}\" was not found"); + $this->logger->info("A group configuration for \"{$key}\" was not found"); return new Minify_ServeConfiguration($options); } @@ -76,23 +76,17 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { $files = (array)$files; } foreach ($files as $file) { - if ($file instanceof Minify_SourceInterface) { - $sources[] = $file; - continue; - } try { - $source = $this->sourceFactory->makeSource(array( - 'filepath' => $file, - )); + $source = $this->sourceFactory->makeSource($file); $sources[] = $source; } catch (Minify_Source_FactoryException $e) { - $this->log($e->getMessage()); + $this->logger->error($e->getMessage()); if (null === $firstMissingResource) { $firstMissingResource = basename($file); continue; } else { $secondMissingResource = basename($file); - $this->log("More than one file was missing: '$firstMissingResource', '$secondMissingResource'"); + $this->logger->info("More than one file was missing: '$firstMissingResource', '$secondMissingResource'"); return new Minify_ServeConfiguration($options); } @@ -112,14 +106,14 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { // no "\" || strpos($get['f'], '\\') !== false ) { - $this->log("GET param 'f' was invalid"); + $this->logger->info("GET param 'f' was invalid"); return new Minify_ServeConfiguration($options); } $ext = ".{$m[1]}"; $files = explode(',', $get['f']); if ($files != array_unique($files)) { - $this->log("Duplicate files were specified"); + $this->logger->info("Duplicate files were specified"); return new Minify_ServeConfiguration($options); } @@ -131,7 +125,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { // valid base $base = "/{$get['b']}/"; } else { - $this->log("GET param 'b' was invalid"); + $this->logger->info("GET param 'b' was invalid"); return new Minify_ServeConfiguration($options); } @@ -153,19 +147,17 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { } try { - $source = $this->sourceFactory->makeSource(array( - 'filepath' => $path, - )); + $source = $this->sourceFactory->makeSource($path); $sources[] = $source; $basenames[] = basename($path, $ext); } catch (Minify_Source_FactoryException $e) { - $this->log($e->getMessage()); + $this->logger->error($e->getMessage()); if (null === $firstMissingResource) { $firstMissingResource = $uri; continue; } else { $secondMissingResource = $uri; - $this->log("More than one file was missing: '$firstMissingResource', '$secondMissingResource`'"); + $this->logger->info("More than one file was missing: '$firstMissingResource', '$secondMissingResource`'"); return new Minify_ServeConfiguration($options); } @@ -178,7 +170,7 @@ class Minify_Controller_MinApp extends Minify_Controller_Base { } if (!$sources) { - $this->log("No sources to serve"); + $this->logger->info("No sources to serve"); return new Minify_ServeConfiguration($options); } diff --git a/lib/Minify/ControllerInterface.php b/lib/Minify/ControllerInterface.php index 3ef1684..3828875 100644 --- a/lib/Minify/ControllerInterface.php +++ b/lib/Minify/ControllerInterface.php @@ -1,5 +1,7 @@ $_SERVER, 'get' => $_GET, + 'post' => $_POST, 'cookie' => $_COOKIE, ), $options); @@ -33,6 +34,7 @@ class Minify_Env { $this->server['DOCUMENT_ROOT'] = rtrim($this->server['DOCUMENT_ROOT'], '/\\'); } $this->get = $options['get']; + $this->post = $options['post']; $this->cookie = $options['cookie']; } @@ -47,30 +49,36 @@ class Minify_Env { : null; } - public function cookie($key = null) + public function cookie($key = null, $default = null) { if (null === $key) { return $this->cookie; } - return isset($this->cookie[$key]) - ? $this->cookie[$key] - : null; + return isset($this->cookie[$key]) ? $this->cookie[$key] : $default; } - public function get($key = null) + public function get($key = null, $default = null) { if (null === $key) { return $this->get; } - return isset($this->get[$key]) - ? $this->get[$key] - : null; + return isset($this->get[$key]) ? $this->get[$key] : $default; + } + + public function post($key = null, $default = null) + { + if (null === $key) { + return $this->post; + } + + return isset($this->post[$key]) ? $this->post[$key] : $default; } protected $server = null; protected $get = null; + protected $post = null; protected $cookie = null; /** diff --git a/lib/Minify/HTML/Helper.php b/lib/Minify/HTML/Helper.php index 5be4300..c67d891 100644 --- a/lib/Minify/HTML/Helper.php +++ b/lib/Minify/HTML/Helper.php @@ -31,17 +31,19 @@ class Minify_HTML_Helper { public static function getUri($keyOrFiles, $opts = array()) { $opts = array_merge(array( // default options - 'farExpires' => true - ,'debug' => false - ,'charset' => 'UTF-8' - ,'minAppUri' => '/min' - ,'rewriteWorks' => true - ,'groupsConfigFile' => '' + 'farExpires' => true, + 'debug' => false, + 'charset' => 'UTF-8', + 'minAppUri' => '/min', + 'rewriteWorks' => true, + 'groupsConfigFile' => self::app()->groupsConfigPath, ), $opts); + $h = new self; $h->minAppUri = $opts['minAppUri']; $h->rewriteWorks = $opts['rewriteWorks']; $h->groupsConfigFile = $opts['groupsConfigFile']; + if (is_array($keyOrFiles)) { $h->setFiles($keyOrFiles, $opts['farExpires']); } else { @@ -98,7 +100,7 @@ class Minify_HTML_Helper { $file = substr($file, 2); } elseif (0 === strpos($file, '/') || 1 === strpos($file, ':\\')) { - $file = substr($file, strlen($_SERVER['DOCUMENT_ROOT']) + 1); + $file = substr($file, strlen(self::app()->env->getDocRoot()) + 1); } $file = strtr($file, '\\', '/'); $files[$k] = $file; @@ -117,7 +119,7 @@ class Minify_HTML_Helper { $this->_groupKey = $key; if ($checkLastModified) { if (! $this->groupsConfigFile) { - $this->groupsConfigFile = dirname(dirname(dirname(__DIR__))) . '/groupsConfig.php'; + $this->groupsConfigFile = self::app()->groupsConfigPath; } if (is_file($this->groupsConfigFile)) { $gc = (require $this->groupsConfigFile); @@ -145,23 +147,35 @@ class Minify_HTML_Helper { public static function getLastModified($sources, $lastModified = 0) { $max = $lastModified; + $factory = self::app()->sourceFactory; + /** @var Minify_Source $source */ foreach ((array)$sources as $source) { - if ($source instanceof Minify_Source) { - $max = max($max, $source->getLastModified()); - } elseif (is_string($source)) { - if (0 === strpos($source, '//')) { - $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1); - } - if (is_file($source)) { - $max = max($max, filemtime($source)); - } - } + $source = $factory->makeSource($source); + $max = max($max, $source->getLastModified()); } return $max; } + /** + * @param \Minify\App $app + * @return \Minify\App + * @internal + */ + public static function app(\Minify\App $app = null) + { + static $cached; + if ($app) { + $cached = $app; + return $app; + } + if ($cached === null) { + $cached = (require __DIR__ . '/../../../bootstrap.php'); + } + return $cached; + } + protected $_groupKey = null; // if present, URI will be like g=... protected $_filePaths = array(); protected $_lastModified = null; diff --git a/lib/Minify/Loader.php b/lib/Minify/Loader.php deleted file mode 100644 index b1df1fd..0000000 --- a/lib/Minify/Loader.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @deprecated Use Composer (/vendor/autoload.php) - */ -class Minify_Loader { - public function loadClass($class) - { - $file = dirname(__DIR__) . DIRECTORY_SEPARATOR; - $file .= strtr($class, "\\_", DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR) . '.php'; - if (is_readable($file)) { - require $file; - - return; - } - - $map = array( - 'JavascriptPacker' => 'class.JavaScriptPacker.php', - ); - - if (!isset($map[$class])) { - return; - } - - @include $map[$class]; - } - - public static function register() - { - $inst = new self(); - spl_autoload_register(array($inst, 'loadClass')); - - return $inst; - } -} - -return Minify_Loader::register(); diff --git a/lib/Minify/Logger.php b/lib/Minify/Logger.php deleted file mode 100644 index 5a9e931..0000000 --- a/lib/Minify/Logger.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * @todo lose this singleton! pass log object in Minify::serve and distribute to others - */ -class Minify_Logger { - - /** - * Set logger object. - * - * The object should have a method "log" that accepts a value as 1st argument and - * an optional string label as the 2nd. - * - * @param mixed $obj or a "falsey" value to disable - * @return null - */ - public static function setLogger($obj = null) { - self::$_logger = $obj - ? $obj - : null; - } - - /** - * Pass a message to the logger (if set) - * - * @param string $msg message to log - * @return null - */ - public static function log($msg, $label = 'Minify') { - if (! self::$_logger) return; - self::$_logger->log($msg, $label); - } - - /** - * @var mixed logger object (like FirePHP) or null (i.e. no logger available) - */ - private static $_logger = null; -} diff --git a/lib/Minify/Logger/LegacyHandler.php b/lib/Minify/Logger/LegacyHandler.php new file mode 100644 index 0000000..07f9991 --- /dev/null +++ b/lib/Minify/Logger/LegacyHandler.php @@ -0,0 +1,25 @@ +obj = $obj; + parent::__construct(); + } + + protected function write(array $record) + { + $this->obj->log((string)$record['formatted']); + } +} diff --git a/lib/Minify/Source/Factory.php b/lib/Minify/Source/Factory.php index c65ce6d..4e58b2d 100644 --- a/lib/Minify/Source/Factory.php +++ b/lib/Minify/Source/Factory.php @@ -133,12 +133,16 @@ class Minify_Source_Factory { */ public function makeSource($spec) { - $source = null; - - if ($spec instanceof Minify_SourceInterface) { - $source = $spec; + if (is_string($spec)) { + $spec = array( + 'filepath' => $spec, + ); + } elseif ($spec instanceof Minify_SourceInterface) { + return $spec; } + $source = null; + if (empty($spec['filepath'])) { // not much we can check return new Minify_Source($spec); diff --git a/min_extras/tools/minifyTextarea.php b/min_extras/tools/minifyTextarea.php index 8194fc8..fbdfcef 100644 --- a/min_extras/tools/minifyTextarea.php +++ b/min_extras/tools/minifyTextarea.php @@ -1,26 +1,29 @@ config->errorLogger) { + $app->config->errorLogger = true; } +$app->cache = new Minify_Cache_Null(); + +$env = $app->env; + function h($txt) { return htmlspecialchars($txt, ENT_QUOTES, 'UTF-8'); } -if (isset($_POST['textIn'])) { - require '../config.php'; - $textIn = str_replace("\r\n", "\n", getPost('textIn')); +if ($env->post('textIn')) { + $textIn = str_replace("\r\n", "\n", $env->post('textIn')); } -if (isset($_POST['method']) && $_POST['method'] === 'Minify and serve') { +if ($env->post('method') === 'Minify and serve') { - $base = trim(getPost('base')); + $base = trim($env->post('base')); if ($base) { $textIn = preg_replace( '@(]*>)@i' @@ -38,16 +41,12 @@ if (isset($_POST['method']) && $_POST['method'] === 'Minify and serve') { $sourceSpec['minifyOptions']['cssMinifier'] = array('Minify_CSSmin', 'minify'); } $source = new Minify_Source($sourceSpec); - Minify_Logger::setLogger(FirePHP::getInstance(true)); - - $env = new Minify_Env(); - $controller = new Minify_Controller_Files($env, new Minify_Source_Factory($env)); - $minify = new Minify(new Minify_Cache_Null()); + $controller = new Minify_Controller_Files($env, $app->sourceFactory, $app->logger); try { - $minify->serve($controller, array( - 'files' => $source - ,'contentType' => Minify::TYPE_HTML + $app->minify->serve($controller, array( + 'files' => $source, + 'contentType' => Minify::TYPE_HTML, )); } catch (Exception $e) { echo h($e->getMessage()); @@ -58,16 +57,16 @@ if (isset($_POST['method']) && $_POST['method'] === 'Minify and serve') { $tpl = array(); $tpl['classes'] = array('Minify_HTML', 'JSMin\\JSMin', 'Minify_CSS'); -if (isset($_POST['method']) && in_array($_POST['method'], $tpl['classes'])) { +if (in_array($env->post('method'), $tpl['classes'])) { $args = array($textIn); - if ($_POST['method'] === 'Minify_HTML') { + if ($env->post('method') === 'Minify_HTML') { $args[] = array( 'cssMinifier' => array('Minify_CSSmin', 'minify') ,'jsMinifier' => array('JSMin\\JSMin', 'minify') ); } - $func = array($_POST['method'], 'minify'); + $func = array($env->post('method'), 'minify'); $tpl['inBytes'] = strlen($textIn); $startTime = microtime(true); try { diff --git a/min_extras/tools/minifyUrl.php b/min_extras/tools/minifyUrl.php index 97f6319..a2629e6 100644 --- a/min_extras/tools/minifyUrl.php +++ b/min_extras/tools/minifyUrl.php @@ -5,7 +5,12 @@ die('Disabled: use this only for testing'); * Fetch and minify a URL (auto-detect HTML/JS/CSS) */ -require __DIR__ . '/../../bootstrap.php'; +$app = (require __DIR__ . '/../../bootstrap.php'); +/* @var \Minify\App $app */ + +$app->cache = new Minify_Cache_Null(); + +$env = $app->env; function getPost($key) { if (! isset($_POST[$key])) { @@ -47,9 +52,9 @@ if (isset($_POST['url'])) { require '../config.php'; - $url = trim(getPost('url')); - $ua = trim(getPost('ua')); - $cook = trim(getPost('cook')); + $url = trim($env->post('url')); + $ua = trim($env->post('ua')); + $cook = trim($env->post('cook')); if (! preg_match('@^https?://@', $url)) { die('HTTP(s) only.'); @@ -98,10 +103,10 @@ if (isset($_POST['url'])) { $sourceSpec['contentType'] = $type['minify']; if ($type['minify'] === 'text/html') { - if (isset($_POST['minJs'])) { + if ($env->post('minJs')) { $sourceSpec['minifyOptions']['jsMinifier'] = array('JSMin\\JSMin', 'minify'); } - if (isset($_POST['minCss'])) { + if ($env->post('minCss')) { $sourceSpec['minifyOptions']['cssMinifier'] = array('Minify_CSSmin', 'minify'); } } @@ -109,7 +114,7 @@ if (isset($_POST['url'])) { $source = new Minify_Source($sourceSpec); $sendType = 'text/plain'; - if ($type['minify'] === 'text/html' && ! isset($_POST['asText'])) { + if ($type['minify'] === 'text/html' && $env->post('asText') === null) { $sendType = $type['sent']; } if ($type['charset']) { @@ -119,10 +124,8 @@ if (isset($_POST['url'])) { // using combine instead of serve because it allows us to specify a // Content-Type like application/xhtml+xml IF we need to - $minify = new Minify(new Minify_Cache_Null()); - try { - echo $minify->combine(array($source)); + echo $app->minify->combine(array($source)); } catch (Exception $e) { header('Content-Type: text/html;charset=utf-8'); echo htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); @@ -132,9 +135,7 @@ if (isset($_POST['url'])) { header('Content-Type: text/html; charset=utf-8'); -$ua = get_magic_quotes_gpc() - ? stripslashes($_SERVER['HTTP_USER_AGENT']) - : $_SERVER['HTTP_USER_AGENT']; +$ua = $env->server('HTTP_USER_AGENT'); ?> Minify URL @@ -146,7 +147,7 @@ $ua = get_magic_quotes_gpc() The fetched resource Content-Type will determine the minifier used.

-

+

HTML options diff --git a/min_extras/tools/testRewriteUri.php b/min_extras/tools/testRewriteUri.php index 2d46b8c..f2f0011 100644 --- a/min_extras/tools/testRewriteUri.php +++ b/min_extras/tools/testRewriteUri.php @@ -1,51 +1,39 @@ env; header('Content-Type: text/html;charset=utf-8'); function h($str) { return htmlspecialchars($str, ENT_QUOTES); } -function getPost($name, $default = '') { return isset($_POST[$name]) ? $_POST[$name] : $default; } - function getInput($name, $default = '', $size = 50) { - $val = h(isset($_POST[$name]) ? $_POST[$name] : $default); - return ""; -} - -// validate user POST (no arrays and fix slashes) -if (! empty($_POST)) { - foreach ($_POST as $name => $val) { - if (! is_string($val)) { - unset($_POST[$name]); - continue; - } - if (get_magic_quotes_gpc()) { - $_POST[$name] = stripslashes($val); - } - } + global $env; + $val = $env->post($name, $default); + return ""; } $defaultCurrentDir = __DIR__; -$defaultDocRoot = realpath($_SERVER['DOCUMENT_ROOT']); +$defaultDocRoot = realpath($env->getDocRoot()); $defaultSymLink = '//symlinkPath'; $defaultSymTarget = ($defaultCurrentDir[0] === '/') ? '/tmp' : 'C:\\WINDOWS\\Temp'; $defaultCss = "url(hello.gif)\nurl(../hello.gif)\nurl(../../hello.gif)\nurl(up/hello.gif)"; $out = ''; -if (isset($_POST['css'])) { - require '../config.php'; +if ($env->post('css')) { $symlinks = array(); - if ('' !== ($target = getPost('symTarget'))) { - $symlinks[getPost('symLink')] = $target; + if ('' !== ($target = $env->post('symTarget'))) { + $symlinks[$env->post('symLink')] = $target; } $css = Minify_CSS_UriRewriter::rewrite( - getPost('css') - , getPost('currentDir') - , getPost('docRoot') - , $symlinks + $env->post('css'), + $env->post('currentDir'), + $env->post('docRoot'), + $symlinks ); $out = "
" . h($css) . '
'; } @@ -57,7 +45,7 @@ if (isset($_POST['css'])) {
-

+

diff --git a/phpunit.xml b/phpunit.xml index b11ab15..b6c77a5 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,6 +16,7 @@ tests + tests/JsClosureCompilerTest.php diff --git a/tests/JsClosureCompilerTest.php b/tests/JsClosureCompilerTest.php index 5b43964..380958f 100644 --- a/tests/JsClosureCompilerTest.php +++ b/tests/JsClosureCompilerTest.php @@ -51,7 +51,7 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase { $src = "(function(){})();"; $minOutput = $this->compile($src, array( - Minify_JS_ClosureCompiler::OPTION_MAX_BYTES => 0 + Minify_JS_ClosureCompiler::OPTION_MAX_BYTES => 0, )); $this->assertSame($src, $minOutput, 'With no limit set, it should compile properly'); @@ -65,7 +65,7 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase $e = null; try { $this->compile($src, array( - Minify_JS_ClosureCompiler::OPTION_MAX_BYTES => $allowedBytes + Minify_JS_ClosureCompiler::OPTION_MAX_BYTES => $allowedBytes, )); } catch (Minify_JS_ClosureCompiler_Exception $e) { } @@ -78,10 +78,14 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase // Test additional options passed to HTTP request public function test6() { - $ecmascript5 = "[1,].length;"; + $ecmascript3 = "[1,].length;"; $e = null; try { - $this->compile($ecmascript5); + $this->compile($ecmascript3, array( + Minify_JS_ClosureCompiler::OPTION_ADDITIONAL_OPTIONS => array( + 'language' => 'ECMASCRIPT3', + ), + )); } catch (Minify_JS_ClosureCompiler_Exception $e) { } $this->assertInstanceOf('Minify_JS_ClosureCompiler_Exception', $e, 'Throws Minify_JS_ClosureCompiler_Exception'); @@ -94,8 +98,8 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase $minExpected = '1;'; $minOutput = $this->compile($ecmascript5, array( Minify_JS_ClosureCompiler::OPTION_ADDITIONAL_OPTIONS => array( - 'language' => 'ECMASCRIPT5' - ) + 'language' => 'ECMASCRIPT5', + ), )); $this->assertSame($minExpected, $minOutput, 'Language option should make it compile'); } diff --git a/utils.php b/utils.php index d3b8023..46e29d7 100644 --- a/utils.php +++ b/utils.php @@ -56,7 +56,7 @@ function Minify_mtime($keysAndFiles, $groupsConfigFile = null) { $gc = null; if (! $groupsConfigFile) { - $groupsConfigFile = __DIR__ . '/groupsConfig.php'; + $groupsConfigFile = Minify_HTML_Helper::app()->groupsConfigPath; } $sources = array(); foreach ($keysAndFiles as $keyOrFile) {