188 lines
5.3 KiB
PHP
188 lines
5.3 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Class Minify_Source
|
||
|
* @package Minify
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* A content source to be minified by Minify.
|
||
|
*
|
||
|
* This allows per-source minification options and the mixing of files with
|
||
|
* content from other sources.
|
||
|
*
|
||
|
* @package Minify
|
||
|
* @author Stephen Clay <steve@mrclay.org>
|
||
|
*/
|
||
|
class Minify_Source {
|
||
|
|
||
|
/**
|
||
|
* @var int time of last modification
|
||
|
*/
|
||
|
public $lastModified = null;
|
||
|
|
||
|
/**
|
||
|
* @var callback minifier function specifically for this source.
|
||
|
*/
|
||
|
public $minifier = null;
|
||
|
|
||
|
/**
|
||
|
* @var array minification options specific to this source.
|
||
|
*/
|
||
|
public $minifyOptions = null;
|
||
|
|
||
|
/**
|
||
|
* @var string full path of file
|
||
|
*/
|
||
|
public $filepath = null;
|
||
|
|
||
|
/**
|
||
|
* @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*)
|
||
|
*/
|
||
|
public $contentType = null;
|
||
|
|
||
|
/**
|
||
|
* Create a Minify_Source
|
||
|
*
|
||
|
* In the $spec array(), you can either provide a 'filepath' to an existing
|
||
|
* file (existence will not be checked!) or give 'id' (unique string for
|
||
|
* the content), 'content' (the string content) and 'lastModified'
|
||
|
* (unixtime of last update).
|
||
|
*
|
||
|
* As a shortcut, the controller will replace "//" at the beginning
|
||
|
* of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'.
|
||
|
*
|
||
|
* @param array $spec options
|
||
|
*/
|
||
|
public function __construct($spec)
|
||
|
{
|
||
|
if (isset($spec['filepath'])) {
|
||
|
if (0 === strpos($spec['filepath'], '//')) {
|
||
|
$spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1);
|
||
|
}
|
||
|
$segments = explode('.', $spec['filepath']);
|
||
|
$ext = strtolower(array_pop($segments));
|
||
|
switch ($ext) {
|
||
|
case 'js' : $this->contentType = 'application/x-javascript';
|
||
|
break;
|
||
|
case 'css' : $this->contentType = 'text/css';
|
||
|
break;
|
||
|
case 'htm' : // fallthrough
|
||
|
case 'html' : $this->contentType = 'text/html';
|
||
|
break;
|
||
|
}
|
||
|
$this->filepath = $spec['filepath'];
|
||
|
$this->_id = $spec['filepath'];
|
||
|
$this->lastModified = filemtime($spec['filepath'])
|
||
|
// offset for Windows uploaders with out of sync clocks
|
||
|
+ round(Minify::$uploaderHoursBehind * 3600);
|
||
|
} elseif (isset($spec['id'])) {
|
||
|
$this->_id = 'id::' . $spec['id'];
|
||
|
if (isset($spec['content'])) {
|
||
|
$this->_content = $spec['content'];
|
||
|
} else {
|
||
|
$this->_getContentFunc = $spec['getContentFunc'];
|
||
|
}
|
||
|
$this->lastModified = isset($spec['lastModified'])
|
||
|
? $spec['lastModified']
|
||
|
: time();
|
||
|
}
|
||
|
if (isset($spec['contentType'])) {
|
||
|
$this->contentType = $spec['contentType'];
|
||
|
}
|
||
|
if (isset($spec['minifier'])) {
|
||
|
$this->minifier = $spec['minifier'];
|
||
|
}
|
||
|
if (isset($spec['minifyOptions'])) {
|
||
|
$this->minifyOptions = $spec['minifyOptions'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get content
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getContent()
|
||
|
{
|
||
|
$content = (null !== $this->filepath)
|
||
|
? file_get_contents($this->filepath)
|
||
|
: ((null !== $this->_content)
|
||
|
? $this->_content
|
||
|
: call_user_func($this->_getContentFunc, $this->_id)
|
||
|
);
|
||
|
// remove UTF-8 BOM if present
|
||
|
return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3))
|
||
|
? substr($content, 3)
|
||
|
: $content;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get id
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getId()
|
||
|
{
|
||
|
return $this->_id;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Verifies a single minification call can handle all sources
|
||
|
*
|
||
|
* @param array $sources Minify_Source instances
|
||
|
*
|
||
|
* @return bool true iff there no sources with specific minifier preferences.
|
||
|
*/
|
||
|
public static function haveNoMinifyPrefs($sources)
|
||
|
{
|
||
|
foreach ($sources as $source) {
|
||
|
if (null !== $source->minifier
|
||
|
|| null !== $source->minifyOptions) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get unique string for a set of sources
|
||
|
*
|
||
|
* @param array $sources Minify_Source instances
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function getDigest($sources)
|
||
|
{
|
||
|
foreach ($sources as $source) {
|
||
|
$info[] = array(
|
||
|
$source->_id, $source->minifier, $source->minifyOptions
|
||
|
);
|
||
|
}
|
||
|
return md5(serialize($info));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get content type from a group of sources
|
||
|
*
|
||
|
* This is called if the user doesn't pass in a 'contentType' options
|
||
|
*
|
||
|
* @param array $sources Minify_Source instances
|
||
|
*
|
||
|
* @return string content type. e.g. 'text/css'
|
||
|
*/
|
||
|
public static function getContentType($sources)
|
||
|
{
|
||
|
foreach ($sources as $source) {
|
||
|
if ($source->contentType !== null) {
|
||
|
return $source->contentType;
|
||
|
}
|
||
|
}
|
||
|
return 'text/plain';
|
||
|
}
|
||
|
|
||
|
protected $_content = null;
|
||
|
protected $_getContentFunc = null;
|
||
|
protected $_id = null;
|
||
|
}
|
||
|
|