function minify($files, $mime = NULL, $header = TRUE, $path = NULL)
{
$fw = Base::instance();
if (is_string($files)) {
$files = $fw->split($files);
}
if (!$mime) {
$mime = $this->mime($files[0]);
}
preg_match('/\\w+$/', $files[0], $ext);
$cache = Cache::instance();
$dst = '';
if (!isset($path)) {
$path = $fw->get('UI') . ';./';
}
foreach ($fw->split($path, FALSE) as $dir) {
foreach ($files as $file) {
if (is_file($save = $fw->fixslashes($dir . $file)) && is_bool(strpos($save, '../')) && preg_match('/\\.(css|js)$/i', $file)) {
if ($fw->get('CACHE') && ($cached = $cache->exists($hash = $fw->hash($save) . '.' . $ext[0], $data)) && $cached[0] > filemtime($save)) {
$dst .= $data;
} else {
$data = '';
$src = $fw->read($save);
for ($ptr = 0, $len = strlen($src); $ptr < $len;) {
if (preg_match('/^@import\\h+url' . '\\(\\h*([\'"])((?!(?:https?:)?\\/\\/).+?)\\1\\h*\\)[^;]*;/', substr($src, $ptr), $parts)) {
$path = dirname($file);
$data .= $this->minify(($path ? $path . '/' : '') . $parts[2], $mime, $header);
$ptr += strlen($parts[0]);
continue;
}
if ($src[$ptr] == '/') {
if ($src[$ptr + 1] == '*') {
// Multiline comment
$str = strstr(substr($src, $ptr + 2), '*/', TRUE);
$ptr += strlen($str) + 4;
} elseif ($src[$ptr + 1] == '/') {
// Single-line comment
$str = strstr(substr($src, $ptr + 2), "\n", TRUE);
$ptr += empty($str) ? strlen(substr($src, $ptr)) : strlen($str) + 2;
} else {
// Presume it's a regex pattern
$regex = TRUE;
// Backtrack and validate
for ($ofs = $ptr; $ofs; $ofs--) {
// Pattern should be preceded by
// open parenthesis, colon,
// object property or operator
if (preg_match('/(return|[(:=!+\\-*&|])$/', substr($src, 0, $ofs))) {
$data .= '/';
$ptr++;
while ($ptr < $len) {
$data .= $src[$ptr];
$ptr++;
if ($src[$ptr - 1] == '\\') {
$data .= $src[$ptr];
$ptr++;
} elseif ($src[$ptr - 1] == '/') {
break;
}
}
break;
} elseif (!ctype_space($src[$ofs - 1])) {
// Not a regex pattern
$regex = FALSE;
break;
}
}
if (!$regex) {
// Division operator
$data .= $src[$ptr];
$ptr++;
}
}
continue;
}
if (in_array($src[$ptr], ['\'', '"'])) {
$match = $src[$ptr];
$data .= $match;
$ptr++;
// String literal
while ($ptr < $len) {
$data .= $src[$ptr];
$ptr++;
if ($src[$ptr - 1] == '\\') {
$data .= $src[$ptr];
$ptr++;
} elseif ($src[$ptr - 1] == $match) {
break;
}
}
continue;
}
if (ctype_space($src[$ptr])) {
if ($ptr + 1 < strlen($src) && preg_match('/[\\w' . ($ext[0] == 'css' ? '#\\.%+\\-*()\\[\\]' : '\\$') . ']{2}|' . '[+\\-]{2}/', substr($data, -1) . $src[$ptr + 1])) {
$data .= ' ';
}
$ptr++;
continue;
}
$data .= $src[$ptr];
$ptr++;
}
if ($fw->get('CACHE')) {
$cache->set($hash, $data);
}
$dst .= $data;
}
}
}
}
if (PHP_SAPI != 'cli' && $header) {
header('Content-Type: ' . $mime . '; charset=' . $fw->get('ENCODING'));
}
return $dst;
}