mirror of
https://github.com/mrclay/minify.git
synced 2025-08-13 09:34:54 +02:00
13
HISTORY.md
13
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)
|
||||
|
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Sets up autoloader for Minify
|
||||
*
|
||||
* @package Minify
|
||||
* Sets up autoloading and returns the Minify\App
|
||||
*/
|
||||
|
||||
call_user_func(function () {
|
||||
@@ -15,3 +13,5 @@ call_user_func(function () {
|
||||
}
|
||||
require $file;
|
||||
});
|
||||
|
||||
return new \Minify\App(__DIR__);
|
||||
|
@@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
// check for auto-encoding
|
||||
$encodeOutput = (function_exists('gzdeflate')
|
||||
&& !ini_get('zlib.output_compression'));
|
||||
$app = (require __DIR__ . '/../bootstrap.php');
|
||||
/* @var \Minify\App $app */
|
||||
|
||||
$config = $app->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.
|
||||
</p>
|
||||
|
||||
<?php if ($cachePathCode): ?>
|
||||
<p class=topNote><strong>Note:</strong> <code><?php echo
|
||||
htmlspecialchars($detectedTmp); ?></code> was discovered as a usable temp directory.<br>To
|
||||
slightly improve performance you can hardcode this in /min/config.php:
|
||||
<code><?php echo htmlspecialchars($cachePathCode); ?></code></p>
|
||||
<?php endIf; ?>
|
||||
|
||||
<p id=minRewriteFailed class="hide"><strong>Note:</strong> Your webserver does not seem to
|
||||
support mod_rewrite (used in /min/.htaccess). Your Minify URIs will contain "?", which
|
||||
<a href="http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/"
|
||||
@@ -106,7 +95,7 @@ and click [Update].</p>
|
||||
|
||||
<div id=bmUris></div>
|
||||
|
||||
<p><button class="btn btn-primary" id=update class=hide>Update</button></p>
|
||||
<p><button class="btn btn-primary hide" id=update>Update</button></p>
|
||||
|
||||
<div id=results class=hide>
|
||||
|
||||
@@ -218,26 +207,8 @@ by Minify. E.g. <code>@import "<span class=minRoot>/min/?</span>g=css2";</code><
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
|
||||
if (!isset($min_cachePath)) {
|
||||
$min_cachePath = '';
|
||||
}
|
||||
if (is_string($min_cachePath)) {
|
||||
$cache = new Minify_Cache_File($min_cachePath, $min_cacheFileLocking);
|
||||
} else {
|
||||
$cache = $min_cachePath;
|
||||
}
|
||||
|
||||
$env = new Minify_Env();
|
||||
|
||||
$sourceFactory = new Minify_Source_Factory($env, array(
|
||||
'uploaderHoursBehind' => $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,
|
||||
));
|
||||
|
@@ -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)
|
||||
|
@@ -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": {
|
||||
|
13
config.php
13
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');
|
||||
|
@@ -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'),
|
||||
);
|
126
index.php
126
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 = '<p>No "f" or "g" parameters were detected.</p>';
|
||||
$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();
|
||||
|
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* DooDigestAuth class file.
|
||||
*
|
||||
* @author Leng Sheng Hong <darkredz@gmail.com>
|
||||
* @link http://www.doophp.com/
|
||||
* @copyright Copyright © 2009 Leng Sheng Hong
|
||||
* @license http://www.doophp.com/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles HTTP digest authentication
|
||||
*
|
||||
* <p>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.</p>
|
||||
* <code>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]</code>
|
||||
*
|
||||
* <p>This class is tested under Apache 2.2 and Cherokee web server. It should work in both mod_php and cgi mode.</p>
|
||||
*
|
||||
* @author Leng Sheng Hong <darkredz@gmail.com>
|
||||
* @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.
|
||||
*
|
||||
* <p>HTTP Digest Authentication doesn't work with PHP in CGI mode,
|
||||
* you have to add this into your .htaccess <code>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]</code></p>
|
||||
*
|
||||
* @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("<script>window.location.href = '$fail_url'</script>");
|
||||
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("<script>window.location.href = '$fail_url'</script>");
|
||||
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("<script>window.location.href = '$fail_url'</script>");
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@@ -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,
|
||||
@@ -689,11 +702,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;
|
||||
}
|
||||
|
||||
@@ -704,11 +716,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;
|
||||
}
|
||||
}
|
||||
|
258
lib/Minify/App.php
Normal file
258
lib/Minify/App.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
namespace Minify;
|
||||
|
||||
use Props\Container;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @property \Minify_CacheInterface $cache
|
||||
* @property \Minify\Config $config
|
||||
* @property string $configPath
|
||||
* @property \Minify_ControllerInterface $controller
|
||||
* @property string $dir
|
||||
* @property string $docRoot
|
||||
* @property \Minify_Env $env
|
||||
* @property \Monolog\Handler\ErrorLogHandler $errorLogHandler
|
||||
* @property array $groupsConfig
|
||||
* @property string $groupsConfigPath
|
||||
* @property \Psr\Log\LoggerInterface $logger
|
||||
* @property \Minify $minify
|
||||
* @property array $serveOptions
|
||||
* @property \Minify_Source_Factory $sourceFactory
|
||||
* @property array $sourceFactoryOptions
|
||||
*/
|
||||
class App extends Container {
|
||||
|
||||
public function __construct($dir)
|
||||
{
|
||||
$that = $this;
|
||||
|
||||
$this->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 = '<p>No "f" or "g" parameters were detected.</p>';
|
||||
$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;
|
||||
}
|
||||
}
|
@@ -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 <pmjones@solarphp.com>
|
||||
* @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 <pmjones@solarphp.com>
|
||||
* @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;
|
||||
}
|
||||
|
73
lib/Minify/Config.php
Normal file
73
lib/Minify/Config.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Minify;
|
||||
|
||||
use Minify_CacheInterface;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $enableBuilder = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $concatOnly = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $builderPassword = 'admin';
|
||||
|
||||
/**
|
||||
* @var bool|object
|
||||
*/
|
||||
public $errorLogger = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $allowDebugFlag = false;
|
||||
|
||||
/**
|
||||
* @var string|Minify_CacheInterface
|
||||
*/
|
||||
public $cachePath = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $documentRoot = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $cacheFileLocking = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $serveOptions = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $symlinks = array();
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $uploaderHoursBehind = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $envArgs = array();
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
public $factories = array();
|
||||
}
|
@@ -4,6 +4,9 @@
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Base class for Minify controller
|
||||
*
|
||||
@@ -24,14 +27,24 @@ abstract class Minify_Controller_Base implements Minify_ControllerInterface {
|
||||
*/
|
||||
protected $sourceFactory;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @param Minify_Env $env
|
||||
* @param Minify_Source_Factory $sourceFactory
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(Minify_Env $env, Minify_Source_Factory $sourceFactory)
|
||||
public function __construct(Minify_Env $env, Minify_Source_Factory $sourceFactory, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
interface Minify_ControllerInterface {
|
||||
|
||||
/**
|
||||
|
@@ -23,6 +23,7 @@ class Minify_Env {
|
||||
$options = array_merge(array(
|
||||
'server' => $_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;
|
||||
|
||||
/**
|
||||
|
@@ -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) {
|
||||
$source = $factory->makeSource($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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_Loader
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class autoloader
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
* @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();
|
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Minify_Logger
|
||||
* @package Minify
|
||||
*/
|
||||
|
||||
/**
|
||||
* Message logging class
|
||||
*
|
||||
* @package Minify
|
||||
* @author Stephen Clay <steve@mrclay.org>
|
||||
*
|
||||
* @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;
|
||||
}
|
25
lib/Minify/Logger/LegacyHandler.php
Normal file
25
lib/Minify/Logger/LegacyHandler.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Minify\Logger;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
|
||||
class LegacyHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $obj;
|
||||
|
||||
public function __construct($obj)
|
||||
{
|
||||
if (!is_callable(array($obj, 'log'))) {
|
||||
throw new \InvalidArgumentException('$obj must have a public log() method');
|
||||
}
|
||||
$this->obj = $obj;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function write(array $record)
|
||||
{
|
||||
$this->obj->log((string)$record['formatted']);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
@@ -1,26 +1,29 @@
|
||||
<?php
|
||||
die('Disabled: use this only for testing');
|
||||
|
||||
require __DIR__ . '/../../bootstrap.php';
|
||||
$app = (require __DIR__ . '/../../bootstrap.php');
|
||||
/* @var \Minify\App $app */
|
||||
|
||||
function getPost($key) {
|
||||
return get_magic_quotes_gpc()
|
||||
? stripslashes($_POST[$key])
|
||||
: $_POST[$key];
|
||||
// use FirePHP if not already setup
|
||||
if (!$app->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(
|
||||
'@(<head\\b[^>]*>)@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 {
|
||||
|
@@ -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');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html><head><title>Minify URL</title></head>
|
||||
@@ -146,7 +147,7 @@ $ua = get_magic_quotes_gpc()
|
||||
The fetched resource Content-Type will determine the minifier used.</p>
|
||||
|
||||
<form action="?2" method="post">
|
||||
<p><label>URL: <input type="text" name="url" size="60"></label></p>
|
||||
<p><label>URL: <input type="text" name="url" value="https://code.jquery.com/jquery-2.2.1.js" size="60"></label></p>
|
||||
<p><input type="submit" value="Fetch and minify"></p>
|
||||
|
||||
<fieldset><legend>HTML options</legend>
|
||||
|
@@ -1,51 +1,39 @@
|
||||
<?php
|
||||
die('Disabled: use this only for testing');
|
||||
|
||||
require __DIR__ . '/../../bootstrap.php';
|
||||
$app = (require __DIR__ . '/../../bootstrap.php');
|
||||
/* @var \Minify\App $app */
|
||||
|
||||
$env = $app->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 "<input type='text' name='{$name}' value='{$val}' size='{$size}' />";
|
||||
}
|
||||
|
||||
// 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 "<input type='text' name='{$name}' value='" . h($val) . "' size='{$size}' />";
|
||||
}
|
||||
|
||||
$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 = "<hr /><pre><code>" . h($css) . '</code></pre>';
|
||||
}
|
||||
@@ -57,7 +45,7 @@ if (isset($_POST['css'])) {
|
||||
<div><label>document root: <?php echo getInput('docRoot', $defaultDocRoot); ?></label></div>
|
||||
<div><label>symlink: <?php echo getInput('symLink', $defaultSymLink); ?> => <?php echo getInput('symTarget', $defaultSymTarget); ?></label></div>
|
||||
<div><label>current directory: <?php echo getInput('currentDir', $defaultCurrentDir); ?></label></div>
|
||||
<p><label>input CSS: <textarea name="css" cols="80" rows="5"><?php echo h(getPost('css', $defaultCss)); ?></textarea></label></p>
|
||||
<p><label>input CSS: <textarea name="css" cols="80" rows="5"><?php echo h($env->post('css', $defaultCss)); ?></textarea></label></p>
|
||||
<p><input type="submit" value="rewrite()" /></p>
|
||||
</form>
|
||||
<?php echo $out; ?>
|
||||
|
@@ -16,6 +16,7 @@
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
<exclude>tests/JsClosureCompilerTest.php</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
|
@@ -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');
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user