public static function hostfile($hostfile) { $config = CssCrush::$config; $regex = CssCrush::$regex; // Keep track of all import file info for later logging $mtimes = array(); $filenames = array(); // Get the hostfile contents and obfuscate commented imports $str = self::obfuscateComments(file_get_contents($hostfile->path)); // This may be set non-zero if an absoulte URL is encountered $searchOffset = 0; // Recurses until the nesting heirarchy is flattened and all files are combined while (preg_match($regex->import, $str, $match, PREG_OFFSET_CAPTURE, $searchOffset)) { $fullMatch = $match[0][0]; // Full match $matchStart = $match[0][1]; // Full match offset $matchEnd = $matchStart + strlen($fullMatch); $url = trim($match[1][0]); // The url $mediaContext = trim($match[2][0]); // The media context if specified $preStatement = substr($str, 0, $matchStart); $postStatement = substr($str, $matchEnd); // Pass over absolute urls // Move the search pointer forward if (preg_match('!^https?://!', $url)) { $searchOffset = $matchEnd; continue; } $import = new stdClass(); $import->name = $url; $import->mediaContext = $mediaContext; $import->path = "{$hostfile->dir}/{$import->name}"; $import->content = @file_get_contents($import->path); // Failed to open import, just continue with the import line removed if (!$import->content) { CssCrush::log("Import file '{$import->name}' not found"); $str = $preStatement . $postStatement; continue; } else { $import->content = self::obfuscateComments($import->content); if ($import->mediaContext) { $import->content = "@media {$import->mediaContext} {" . $import->content . '}'; } $import->dir = dirname($import->name); // Store import file info $mtimes[] = filemtime($import->path); $filenames[] = $import->name; // Store the replacements we might find $replacements = array(); // Match all @import statements in the import content // Alter all the url strings to be paths relative to the hostfile $matchCount = preg_match_all($regex->import, $import->content, $matchAll, PREG_OFFSET_CAPTURE); for ($index = 0; $index < $matchCount; $index++) { $fullMatch = $matchAll[0][$index][0]; $urlMatch = $matchAll[1][$index][0]; $search = $urlMatch; $replace = "{$import->dir}/{$urlMatch}"; // Try to resolve absolute paths // On failure strip the @import statement if (strpos($urlMatch, '/') === 0) { $replace = self::resolveAbsolutePath($urlMatch); if (!$replace) { $search = $fullMatch; $replace = ''; } } $replacements[$fullMatch] = str_replace($search, $replace, $fullMatch); } // If we've stored any altered @import strings then we need to apply them if (count($replacements)) { $import->content = str_replace(array_keys($replacements), array_values($replacements), $import->content); } // CssCrush::log( $replacements ); $str = $preStatement . $import->content . $postStatement; } } // End while self::save(array('imports' => $filenames, 'datem_sum' => array_sum($mtimes) + $hostfile->mtime, 'options' => CssCrush::$options)); return $str; }