1
0
mirror of https://github.com/mrclay/minify.git synced 2025-08-10 16:14:18 +02:00

Controllers now supply all options and are easier to write! serve() returns more useful info and needs only one option array for both controller/minify options.

This commit is contained in:
Steve Clay
2008-03-01 15:08:38 +00:00
parent 7e9bf6d948
commit 381bd8856d
8 changed files with 300 additions and 230 deletions

View File

@@ -7,111 +7,58 @@
* for minification and set options like contentType. It's also responsible
* for loading minifier code upon request.
*/
class Minify_Controller_Base {
abstract class Minify_Controller_Base {
/**
* @var array instances of Minify_Source, which provide content and
* any individual minification needs.
* Setup controller sources
*
* @see Minify_Source
* You must override this method in your subclass controller to set
* $this->sources. If the request is NOT valid, make sure $this->sources
* is left an empty array. Then strip any controller-specific options from
* $options and return it.
*
* @param array $options controller and Minify options
*
* @param array $options Minify options
*/
public $sources = array();
abstract public function setupSources($options);
/**
* @var array options to be read by Minify
* Get default Minify options for this controller.
*
* Any unspecified options will use the default values.
*
* 'minifiers': this is an array with content-types as keys and callbacks as
* values. Specify a custom minifier by setting this option. E.g.:
*
* <code>
* $this->options['minifiers']['application/x-javascript'] =
* array('Minify_Packer', 'minify'); // callback
* </code>
*
* Note that, when providing your own minifier, the controller must be able
* to load its code on demand. @see loadMinifier()
*
* 'perType' : this is an array of options to send to a particular content
* type minifier by using the content-type as key. E.g. To send the CSS
* minifier an option: $options['perType']['text/css']['foo'] = 'bar';
* When the CSS minifier is called, the 2nd argument will be
* array('foo' => 'bar').
*
* 'isPublic' : send "public" instead of "private" in Cache-Control headers,
* allowing shared caches to cache the output. (default true)
*
* 'encodeOutput' : to disable content encoding, set this to false
*
* 'encodeMethod' : generally you should let this be determined by
* HTTP_Encoder (the default null), but you can force a particular encoding
* to be returned, by setting this to 'gzip', 'deflate', 'compress', or ''
* (no encoding)
*
* 'encodeLevel' : level of encoding compression (0 to 9, default 9)
*
* 'contentTypeCharset' : if given, this will be appended to the Content-Type
* header sent, useful mainly for HTML docs.
*
* 'setExpires' : set this to a timestamp or GMT date to have Minify send
* an HTTP Expires header instead of checking for conditional GET.
* E.g. (time() + 86400 * 365) for 1yr (default null)
* This has nothing to do with server-side caching.
*
* 'quiet' : set to true to have Minify not output any content/headers
* (bool, default = false)
* Override in subclass to change defaults
*
* @return array options for Minify
*/
public $minOptions = array();
public function getDefaultMinifyOptions() {
return array(
'isPublic' => true
,'encodeOutput' => true
,'encodeMethod' => null // determine later
,'encodeLevel' => 9
,'perType' => array() // no per-type minifier options
,'contentTypeCharset' => null // leave out of Content-Type header
,'setExpires' => null // use conditional GET
,'quiet' => false // serve() will send headers and output
// if you override this, the response code MUST be directly after
// the first space.
,'badRequestHeader' => 'HTTP/1.0 400 Bad Request'
);
}
/**
* @var bool was the user request valid
* Get default minifiers for this controller.
*
* This must be explicity be set to true to process the request. This should
* be done by the child class constructor.
* Override in subclass to change defaults
*
* @return array minifier callbacks for common types
*/
public $requestIsValid = false;
/**
* Parent constructor for a controller class
*
* If your subclass controller is not happy with the request, it can simply return
* without setting $this->requestIsValid. Minify will not check any other member.
*
* If the request is valid, you must set $this->requestIsValid = true and also call
* the parent constructor, passing along an array of source objects and any Minify
* options:
* <code>
* parent::__construct($sources, $options);
* </code>
*
* This function sets $this->sources and determines $this->options 'contentType' and
* 'lastModifiedTime'.
*
* @param array $sources array of Minify_Source instances
*
* @param array $options options for Minify
*
* @return null
*/
public function __construct($sources, $options = array()) {
if (empty($sources)) {
$this->requestIsValid = false;
}
$this->sources = $sources;
if (! isset($options['contentType'])) {
$options['contentType'] = Minify_Source::getContentType($this->sources);
}
// last modified is needed for caching, even if setExpires is set
if (! isset($options['lastModifiedTime'])) {
$max = 0;
foreach ($sources as $source) {
$max = max($source->lastModified, $max);
}
$options['lastModifiedTime'] = $max;
}
$this->minOptions = $options;
public function getDefaultMinifers() {
$ret[Minify::TYPE_JS] = array('Minify_Javascript', 'minify');
$ret[Minify::TYPE_CSS] = array('Minify_CSS', 'minify');
$ret[Minify::TYPE_HTML] = array('Minify_HTML', 'minify');
return $ret;
}
/**
@@ -124,7 +71,10 @@ class Minify_Controller_Base {
* function will include 'Jimmy/Minifier.php'
*
* If you need code loaded on demand and this doesn't suit you, you'll need
* to override this function by extending the class.
* to override this function in your subclass.
* @see Minify_Controller_Page::loadMinifier()
*
* @param callback $minifierCallback callback of minifier function
*
* @return null
*/
@@ -137,4 +87,58 @@ class Minify_Controller_Base {
require str_replace('_', '/', $minifierCallback[0]) . '.php';
}
}
/**
* @var array instances of Minify_Source, which provide content and
* any individual minification needs.
*
* @see Minify_Source
*/
public $sources = array();
/**
* Mix in default controller options with user-given options
*
* @param array $options user options
*
* @return array mixed options
*/
public final function mixInDefaultOptions($options)
{
$ret = array_merge(
$this->getDefaultMinifyOptions(), $options
);
if (! isset($options['minifiers'])) {
$options['minifiers'] = array();
}
$ret['minifiers'] = array_merge(
$this->getDefaultMinifers(), $options['minifiers']
);
return $ret;
}
/**
* Analyze sources (if there are any) and set $options 'contentType'
* and 'lastModifiedTime' if they already aren't.
*
* @param array $options options for Minify
*
* @return array options for Minify
*/
public final function analyzeSources($options = array()) {
if ($this->sources) {
if (! isset($options['contentType'])) {
$options['contentType'] = Minify_Source::getContentType($this->sources);
}
// last modified is needed for caching, even if setExpires is set
if (! isset($options['lastModifiedTime'])) {
$max = 0;
foreach ($this->sources as $source) {
$max = max($source->lastModified, $max);
}
$options['lastModifiedTime'] = $max;
}
}
return $options;
}
}

View File

@@ -9,9 +9,11 @@ require_once 'Minify/Controller/Base.php';
* <code>
* $dr = $_SERVER['DOCUMENT_ROOT'];
* Minify::serve('Files', array(
* $dr . '/js/jquery.js'
* ,$dr . '/js/plugins.js'
* ,$dr . '/js/site.js'
* 'files' => array(
* $dr . '/js/jquery.js'
* ,$dr . '/js/plugins.js'
* ,$dr . '/js/site.js'
* )
* ));
* </code>
*
@@ -19,28 +21,36 @@ require_once 'Minify/Controller/Base.php';
class Minify_Controller_Files extends Minify_Controller_Base {
/**
* @param array $spec array of full paths of files to be minified
* Set up file sources
*
* @param array $options options to pass to Minify
* @param array $options controller and Minify options
* @return array Minify options
*
* @return null
* Controller options:
*
* 'files': (required) array of complete file paths
*/
public function __construct($spec, $options = array()) {
public function setupSources($options) {
// strip controller options
$files = $options['files'];
unset($options['files']);
$sources = array();
foreach ($spec as $file) {
foreach ($files as $file) {
$file = realpath($file);
if (file_exists($file)) {
$sources[] = new Minify_Source(array(
'filepath' => $file
));
} else {
return;
// file not found
return $options;
}
}
if ($sources) {
$this->requestIsValid = true;
$this->sources = $sources;
}
parent::__construct($sources, $options);
return $options;
}
}

View File

@@ -8,16 +8,11 @@ require_once 'Minify/Controller/Base.php';
*
* <code>
* $dr = $_SERVER['DOCUMENT_ROOT'];
* Minify::serve('Groups', array(
* 'css' => array(
* $dr . '/css/type.css'
* ,$dr . '/css/layout.css'
* )
* ,'js' => array(
* $dr . '/js/jquery.js'
* ,$dr . '/js/plugins.js'
* ,$dr . '/js/site.js'
* )
* Minify::serve('Groups', array(
* 'groups' => array(
* 'css' => array($dr . '/css/type.css', $dr . '/css/layout.css')
* ,'js' => array($dr . '/js/jquery.js', $dr . '/js/site.js')
* )
* ));
* </code>
*
@@ -27,20 +22,28 @@ require_once 'Minify/Controller/Base.php';
class Minify_Controller_Groups extends Minify_Controller_Base {
/**
* @param array $spec associative array of keys to arrays of file paths.
* Set up groups of files as sources
*
* @param array $options optional options to pass to Minify
* @param array $options controller and Minify options
* @return array Minify options
*
* @return null
* Controller options:
*
* 'groups': (required) array mapping PATH_INFO strings to arrays
* of complete file paths. @see Minify_Controller_Groups
*/
public function __construct($spec, $options = array()) {
public function setupSources($options) {
// strip controller options
$groups = $options['groups'];
unset($options['groups']);
$pi = substr($_SERVER['PATH_INFO'], 1);
if (! isset($spec[$pi])) {
if (! isset($groups[$pi])) {
// not a valid group
return;
return $options;
}
$sources = array();
foreach ($spec[$pi] as $file) {
foreach ($groups[$pi] as $file) {
$file = realpath($file);
if (file_exists($file)) {
$sources[] = new Minify_Source(array(
@@ -48,13 +51,13 @@ class Minify_Controller_Groups extends Minify_Controller_Base {
));
} else {
// file doesn't exist
return;
return $options;
}
}
if ($sources) {
$this->requestIsValid = true;
$this->sources = $sources;
}
parent::__construct($sources, $options);
return $options;
}
}

View File

@@ -11,37 +11,47 @@ require_once 'Minify/Controller/Base.php';
class Minify_Controller_Page extends Minify_Controller_Base {
/**
* @param array $spec array of options. You *must* set 'content' and 'id',
* but setting 'lastModifiedTime' is recommeded in order to allow server
* and client-side caching.
* Set up source of HTML content
*
* If you set <code>'minifyAll' => 1</code>, all CSS and Javascript blocks
* will be individually minified.
* @param array $options controller and Minify options
* @return array Minify options
*
* @param array $options optional options to pass to Minify
* Controller options:
*
* @return null
* 'content': (required) HTML markup
*
* 'id': (required) id of page (string for use in server-side caching)
*
* 'lastModifiedTime': timestamp of when this content changed. This
* is recommended to allow both server and client-side caching.
*
* 'minifyAll': should all CSS and Javascript blocks be individually
* minified? (default false)
*/
public function __construct($spec, $options = array()) {
public function setupSources($options) {
// strip controller options
$sourceSpec = array(
'content' => $spec['content']
,'id' => $spec['id']
,'minifier' => array('Minify_HTML', 'minify')
'content' => $options['content']
,'id' => $options['id']
);
if (isset($spec['minifyAll'])) {
unset($options['content'], $options['id']);
if (isset($options['minifyAll'])) {
// this will be the 2nd argument passed to Minify_HTML::minify()
$sourceSpec['minifyOptions'] = array(
'cssMinifier' => array('Minify_CSS', 'minify')
,'jsMinifier' => array('Minify_Javascript', 'minify')
);
$this->_loadCssJsMinifiers = true;
unset($options['minifyAll']);
}
$sources[] = new Minify_Source($sourceSpec);
if (isset($spec['lastModifiedTime'])) {
$options['lastModifiedTime'] = $spec['lastModifiedTime'];
}
$options['contentType'] = 'text/html';
$this->requestIsValid = true;
parent::__construct($sources, $options);
$this->sources[] = new Minify_Source($sourceSpec);
// may not be needed
//$options['minifier'] = array('Minify_HTML', 'minify');
$options['contentType'] = Minify::TYPE_HTML;
return $options;
}
private $_loadCssJsMinifiers = false;