Skip to content

Instantly share code, notes, and snippets.

@daohoangson
Created January 18, 2014 04:55
Show Gist options
  • Save daohoangson/8486421 to your computer and use it in GitHub Desktop.
Save daohoangson/8486421 to your computer and use it in GitHub Desktop.
<?php
class bdCache_Css
{
public static function save($parameters, $css)
{
$css = utf8_trim($css);
if (empty($css))
{
return false;
}
$filePath = self::getCssFilePath($parameters);
$requestPaths = XenForo_Application::get('requestPaths');
$requestBeforeBasePath = substr($requestPaths['fullBasePath'], 0, -1 * strlen($requestPaths['basePath']));
if (!bdCache_File::existsAndNotEmpty($filePath))
{
$dirPath = dirname($filePath);
XenForo_Helper_File::createDirectory($dirPath, true);
// fix url('...')
$offset = 0;
$i = 0;
while (true)
{
$strpos = strpos($css, 'url(', $offset);
if ($strpos === false)
{
break;
// while(true)
}
$offset = $strpos + 1;
$insertOffset = 4;
$firstChars = substr($css, $strpos + $insertOffset, 9);
$veryFirstChar = substr($firstChars, 0, 1);
if ($veryFirstChar === "'" OR $veryFirstChar === '"')
{
$firstChars = substr($firstChars, 1);
$insertOffset++;
}
if (strpos($firstChars, 'http://') === 0)
{
// do nothing
}
elseif (strpos($firstChars, 'https://') === 0)
{
// do nothing
}
elseif (substr($firstChars, 0, 2) === '//')
{
// do nothing
}
elseif (substr($firstChars, 0, 1) === '/')
{
// append the host name
$css = substr_replace($css, $requestBeforeBasePath, $strpos + $insertOffset, 0);
}
else
{
// adjust url to make it valid
$css = substr_replace($css, $requestPaths['fullBasePath'], $strpos + $insertOffset, 0);
}
}
$css .= call_user_func_array('sprintf', array(
'/* CSS saved with [bd] Cache (%s) */',
$requestPaths['fullUri'],
$parameters,
));
file_put_contents($filePath, $css);
XenForo_Helper_File::makeWritableByFtpUser($filePath);
}
}
public static function redirect($parameters)
{
$filePath = self::getCssFilePath($parameters);
if (bdCache_File::existsAndNotEmpty($filePath))
{
$url = XenForo_Link::convertUriToAbsoluteUri(self::getCssUrl($parameters), true);
header('HTTP/1.1 301 Moved Permanently');
header(sprintf('Location: %s', $url));
exit();
}
}
public static function replaceCssUrls(&$content)
{
if (!bdCache_Option::get('cssToFile'))
{
return true;
}
$offset = 0;
$begin = '"css.php?';
$beginLength = strlen($begin);
$failed = 0;
while (true)
{
$beginStrpos = strpos($content, $begin, $offset);
if ($beginStrpos === false)
{
break;
// while(true)
}
$endStrpos = strpos($content, '"', $beginStrpos + 1);
if ($endStrpos === false)
{
break;
// while(true)
}
//$endStrpos--;
$parameters = substr($content, $beginStrpos + $beginLength, $endStrpos - $beginStrpos - $beginLength);
$parameters = html_entity_decode($parameters);
$offset = $beginStrpos + $beginLength;
$filePath = self::getCssFilePath($parameters);
if (bdCache_File::existsAndNotEmpty($filePath))
{
// start replacing...
$oldUrlOffset = $beginStrpos + 1;
$oldUrlLength = $endStrpos - $oldUrlOffset;
$oldUrl = substr($content, $oldUrlOffset, $oldUrlLength);
$newUrl = self::getCssUrl($parameters);
$newUrlLength = strlen($newUrl);
$content = substr_replace($content, $newUrl, $oldUrlOffset, $oldUrlLength);
}
else
{
$failed++;
}
}
return ($failed == 0);
}
public static function doHouseKeeping()
{
$cssPath = sprintf('%s/bdCache/css', XenForo_Helper_File::getExternalDataPath());
$dirs = glob(sprintf('%s/*', $cssPath));
$cssDirs = array();
foreach ($dirs as $dir)
{
$dirName = basename($dir);
if (is_numeric($dirName))
{
$cssDirs[intval($dirName)] = $dir;
}
}
ksort($cssDirs);
if (empty($cssDirs))
{
// nothing?
// maybe CSS caching is disabled
return false;
}
// leave out the latest directory, it contains current files
array_pop($cssDirs);
foreach ($cssDirs as $dir)
{
bdCache_File::removeDirectory($dir);
}
return true;
}
public static function getCssFilePath($parameters)
{
list($modifiedDate, $hash) = self::_getModifiedDateAndHash($parameters);
return sprintf('%s/bdCache/css/%d/%s.css', XenForo_Helper_File::getExternalDataPath(), $modifiedDate, $hash);
}
public static function getCssUrl($parameters)
{
list($modifiedDate, $hash) = self::_getModifiedDateAndHash($parameters);
$url = sprintf('%s/bdCache/css/%d/%s.css', XenForo_Application::$externalDataUrl, $modifiedDate, $hash);
return $url;
}
protected static function _getModifiedDateAndHash($parameters)
{
parse_str($parameters, $parsed);
ksort($parsed);
$modifiedDate = (isset($parsed['d']) ? $parsed['d'] : 0);
$hash = md5(implode('', $parsed));
return array(
$modifiedDate,
$hash
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment