Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Data URIs to be automatically embedded into the cached #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 139 additions & 3 deletions views/helpers/asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function __process($type, $assets) {

//check if the cached file exists
$scripts = Set::extract('/script', $assets);
$fileName = $folder->find($this->__generateFileName($scripts) . '_([0-9]{10}).' . $type);
$fileName = $folder->find($this->__generateFileName($scripts, $type) . '_([0-9]{10}).' . $type);
if ($fileName) {
//take the first file...really should only be one.
$fileName = $fileName[0];
Expand Down Expand Up @@ -309,6 +309,14 @@ function __process($type, $assets) {
$buffer = $this->__preprocessCss($asset, $buffer);
}

// Replace with Data Uri
if (self::__dataURIsupported())
{
$w = '[ \t\r\n\f]*';
$quote = '["\']?';
$css_uri = '(url\('.$w.$quote.')([^\)"\']+)('.$quote.$w.'\))'.$w.'/\*DATA_URI\*/';
$buffer = preg_replace_callback('|'.$css_uri.'|', 'AssetHelper::__replaceWithDataUri', $buffer);
}
$tidy->parse($buffer);
$buffer = $tidy->print->plain();
break;
Expand All @@ -323,7 +331,7 @@ function __process($type, $assets) {
}

//write the file
$fileName = $this->__generateFileName($scripts) . '_' . $ts . '.' . $type;
$fileName = $this->__generateFileName($scripts, $type) . '_' . $ts . '.' . $type;
$file = new File($this->paths['wwwRoot'] . $this->options['cachePaths'][$type] . DS . $fileName);
$file->write(trim($scriptBuffer));
}
Expand Down Expand Up @@ -405,16 +413,20 @@ function __findFile(&$asset, $type) {
* Generate the cached filename.
*
* @param array $names an array of the original file names
* @param string $type css or js
* @return string
* @access private
*/
function __generateFileName($names) {
function __generateFileName($names, $type) {
$fileName = Sanitize::paranoid(str_replace('/', '-', implode('_', $names)), array('_', '-'));

if ($this->options['md5FileName']) {
$fileName = md5($fileName);
}

if (self::__dataURIsupported() && $type == 'css')
$fileName .= '_embedded';

return $fileName;
}

Expand All @@ -428,5 +440,129 @@ function __getPath($type) {

return false;
}

/**
*
* Detect browser and version
* @param unknown_type $user_agent
* @return number|multitype:string number browser and version
*/
private static function __detect_browser ( $user_agent = '' )
{
if (! function_exists ( 'stripos' )) {
function stripos ( $haystack , $needle , $offset = 0 ) {
return strpos ( strtolower ( $haystack ), strtolower ( $needle ), $offset );
}
}
$user_agent = empty( $user_agent ) ? $_SERVER [ 'HTTP_USER_AGENT' ] : $user_agent ;
$browser = array( 'name' => 'default' , 'ver' => 0 );
if ( stripos ( $user_agent , 'Opera' ) !== false ) {
$browser [ 'name' ] = 'opera' ;
if( stripos ( $user_agent , 'Version' ) !== false ) {
# Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.2.15 Version/10.00
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'version/' , strtolower ( $user_agent ))))));
}
else {
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , substr ( $user_agent , ( stripos ( $user_agent , 'opera' ) + strlen ( 'opera' ) + 1 )))));
}
}
elseif ( stripos ( $user_agent , 'MSIE' ) !== false ) {
$browser [ 'name' ] = 'ie' ;
$browser [ 'ver' ] = rtrim ( current ( explode ( ' ' , trim ( end ( explode ( 'msie' , strtolower ( $user_agent )))))), ';' );
}
## Webkit (Safari/Chrome)
elseif ( stripos ( $user_agent , 'AppleWebKit' ) !== false ) {
$browser [ 'name' ] = 'applewebkit' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , substr ( $user_agent , ( stripos ( $user_agent , 'applewebkit' ) + strlen ( 'AppleWebKit' ) + 1 )))));
}
## Gecko/Netscape/Firefox/Flock/Mozilla/Camino/SeaMonkey
elseif ( stripos ( $user_agent , 'Gecko' ) !== false && stripos ( $user_agent , 'like Gecko' ) === false ) {
if ( stripos ( $user_agent , 'Navigator' ) !== false ) {
##Netscape 9+
$browser [ 'name' ] = 'netscape' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'navigator/' , strtolower ( $user_agent ))))));
}
elseif ( stripos ( $user_agent , 'Firefox' ) !== false ) {
## Firefox 0.10 +
$browser [ 'name' ] = 'firefox' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'firefox/' , strtolower ( $user_agent ))))));
}
elseif( stripos ( $user_agent , 'Netscape6' ) !== false ){
#Netscape 6
$browser [ 'name' ] = 'netscape' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'netscape6/' , strtolower ( $user_agent ))))));
}
elseif( stripos ( $user_agent , 'Netscape' ) !== false ){
## Netscape 7-9
$browser [ 'name' ] = 'netscape' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'netscape/' , strtolower ( $user_agent ))))));
}
}
elseif( stripos ( $user_agent , 'Googlebot' ) !== false ){
## Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
$browser [ 'name' ] = 'googlebot' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'googlebot/' , strtolower ( $user_agent ))))), ';' );
}
elseif( stripos ( $user_agent , 'msnbot' ) !== false ){
## msnbot/1.0 (+http://search.msn.com/msnbot.htm)
$browser [ 'name' ] = 'msnbot' ;
$browser [ 'ver' ] = trim ( current ( explode ( ' ' , end ( explode ( 'msnbot/' , strtolower ( $user_agent ))))), ';' );
}
elseif( stripos ( $user_agent , 'Yahoo! Slurp' ) !== false ){
## Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)
$browser [ 'name' ] = 'yahoo' ;
$browser [ 'ver' ] = 1 ;
}
$browser [ 'ver' ] = (float) $browser [ 'ver' ];
return $browser ;
}

private static $DATA_URI_SUPPORTED = null;

/**
*
* Detect browser data uri support
*/
private static function __dataURIsupported ()
{
if (self::$DATA_URI_SUPPORTED != null)
return self::$DATA_URI_SUPPORTED;
$supported = false ;
$browser = self::__detect_browser ();
if ( $browser [ 'name' ] == 'ie' && $browser [ 'ver' ]> 7.9 ) {
$supported = true ;
}
elseif( $browser [ 'name' ] == 'applewebkit' ) {
$supported = true ;
}
elseif( ( $browser [ 'name' ] == 'firefox' && $browser [ 'ver' ]> 2 ) || ( $browser [ 'name' ] == 'opera' && $browser [ 'ver' ]> 8 ) || ( $browser [ 'name' ] == 'netscape' && $browser [ 'ver' ]> 7 )) {
$supported = true ;
}
self::$DATA_URI_SUPPORTED == $supported;
return $supported ;
}

/**
*
* Function for preg_replace_callback to substitute all URIs with Data URIs containing base 64 encoded file data
* If file cannot be found or mime type cannot be determined the uri string is returned.
* @param array $matches
*/
private static function __replaceWithDataUri($matches)
{
$file_loc = APP.DS.WEBROOT_DIR.$matches[2];
$filename = realpath($file_loc);

if (!file_exists($filename))
return ($matches[0]);

$imagetype = exif_imagetype($filename);
if ($imagetype === false)
return ($matches[0]);
$mime = image_type_to_mime_type($imagetype);

$data_uri = "data:$mime;base64,".base64_encode(file_get_contents($filename));
return $matches[1].$data_uri.$matches[3];
}
}
?>