New version 6.x-1.11 for Advanced CSS/JS Aggregation module
This commit is contained in:
parent
e72db62736
commit
329321644a
17 changed files with 734 additions and 414 deletions
|
@ -101,6 +101,11 @@ define('ADVAGG_CLOSURE', TRUE);
|
|||
*/
|
||||
define('ADVAGG_STRICT_JS_BUNDLES', TRUE);
|
||||
|
||||
/**
|
||||
* Default value for how long the request can go before php times out.
|
||||
*/
|
||||
define('ADVAGG_SET_TIME_LIMIT', 240);
|
||||
|
||||
/**
|
||||
* Default mode for aggregate creation.
|
||||
*
|
||||
|
@ -359,6 +364,10 @@ function advagg_init() {
|
|||
$conf['advagg_use_full_cache'] = FALSE;
|
||||
}
|
||||
|
||||
// Include the ctools_ajax_run_page_preprocess() function.
|
||||
if (function_exists('ctools_include')) {
|
||||
ctools_include('ajax');
|
||||
}
|
||||
// Disable ctools_ajax_page_preprocess() if this functionality is available.
|
||||
if (variable_get('advagg_enabled', ADVAGG_ENABLED) && function_exists('ctools_ajax_run_page_preprocess')) {
|
||||
ctools_ajax_run_page_preprocess(FALSE);
|
||||
|
@ -438,8 +447,9 @@ function advagg_get_root_files_dir($reset = FALSE) {
|
|||
$custom_path = variable_get('advagg_custom_files_dir', ADVAGG_CUSTOM_FILES_DIR);
|
||||
}
|
||||
if (empty($custom_path)) {
|
||||
$css_path = file_create_path('advagg_css');
|
||||
$js_path = file_create_path('advagg_js');
|
||||
$file_path = file_directory_path();
|
||||
$css_path = file_create_path($file_path . '/advagg_css');
|
||||
$js_path = file_create_path($file_path . '/advagg_js');
|
||||
return array($css_path, $js_path);
|
||||
}
|
||||
file_check_directory($custom_path, FILE_CREATE_DIRECTORY);
|
||||
|
@ -967,7 +977,7 @@ function advagg_get_filename($files, $filetype, $counter = FALSE, $bundle_md5 =
|
|||
$counters[$key] = $values['bundle_md5'];
|
||||
}
|
||||
}
|
||||
$result = advagg_db_multi_select_in('advagg_bundles', 'bundle_md5', "'%s'", $counters, array('counter', 'bundle_md5'), 'GROUP BY bundle_md5');
|
||||
$result = advagg_db_multi_select_in('advagg_bundles', 'bundle_md5', "'%s'", $counters, array('counter', 'bundle_md5'), 'GROUP BY bundle_md5, counter');
|
||||
while ($row = db_fetch_array($result)) {
|
||||
$key = array_search($row['bundle_md5'], $counters);
|
||||
if (empty($filenames[$key]['counter']) && $filenames[$key]['counter'] !== 0) {
|
||||
|
@ -1414,7 +1424,34 @@ function advagg_file_copy(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!@copy($source, $dest)) {
|
||||
// Perform the replace operation. Since there could be multiple processes
|
||||
// writing to the same file, the best option is to create a temporary file in
|
||||
// the same directory and then rename it to the destination. A temporary file
|
||||
// is needed if the directory is mounted on a separate machine; thus ensuring
|
||||
// the rename command stays local.
|
||||
$result = FALSE;
|
||||
if ($replace == FILE_EXISTS_REPLACE) {
|
||||
// Get a temporary filename in the destination directory.
|
||||
$temporary_file = tempnam(dirname($dest), 'file');
|
||||
// Place contents in the temporary file.
|
||||
if ($temporary_file && @copy($source, $temporary_file)) {
|
||||
if (!$result = @rename($temporary_file, $dest)) {
|
||||
// Unlink and try again for windows. Rename on windows does not replace
|
||||
// the file if it already exists.
|
||||
@unlink($dest);
|
||||
$result = @rename($temporary_file, $dest);
|
||||
}
|
||||
// Remove temporary_file if rename failed.
|
||||
if (!$result) {
|
||||
@unlink($temporary_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Perform the copy operation.
|
||||
else {
|
||||
$result = @copy($source, $dest);
|
||||
}
|
||||
if ($result === FALSE) {
|
||||
drupal_set_message(t('The selected file %file could not be copied. ' . $dest, array('%file' => $source)), 'error');
|
||||
return 0;
|
||||
}
|
||||
|
@ -1462,7 +1499,7 @@ function advagg_checksum($filename) {
|
|||
}
|
||||
}
|
||||
}
|
||||
elseif ($mode = 'md5') {
|
||||
elseif ($mode == 'md5') {
|
||||
$checksum = md5(file_get_contents($filename));
|
||||
}
|
||||
}
|
||||
|
@ -1560,7 +1597,7 @@ function advagg_get_bundle_from_filename($filename) {
|
|||
function advagg_flush_caches() {
|
||||
// Try to allocate enough time to flush the cache
|
||||
if (function_exists('set_time_limit')) {
|
||||
@set_time_limit(240);
|
||||
@set_time_limit(variable_get('advagg_set_time_limit', ADVAGG_SET_TIME_LIMIT));
|
||||
}
|
||||
|
||||
global $_advagg;
|
||||
|
@ -1779,7 +1816,7 @@ function advagg_build_uri($path) {
|
|||
}
|
||||
// Use the patched version of file_create_url().
|
||||
else {
|
||||
$path = file_create_url($path);
|
||||
$path = advagg_file_create_url($path);
|
||||
}
|
||||
// Return here if the path was changed above.
|
||||
if (strcmp($original_path, $path) != 0) {
|
||||
|
@ -1793,7 +1830,7 @@ function advagg_build_uri($path) {
|
|||
$hook_file_url_alter = module_implements('file_url_alter');
|
||||
}
|
||||
if (!empty($hook_file_url_alter)) {
|
||||
$path = file_create_url($path);
|
||||
$path = advagg_file_create_url($path);
|
||||
// Return here if the path was changed above.
|
||||
if (strcmp($original_path, $path) != 0) {
|
||||
return $path;
|
||||
|
@ -1804,6 +1841,63 @@ function advagg_build_uri($path) {
|
|||
return base_path() . $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the download path to a file.
|
||||
*
|
||||
* There are two kinds of local files:
|
||||
* - "created files", i.e. those in the files directory (which is stored in
|
||||
* the file_directory_path variable and can be retrieved using
|
||||
* file_directory_path()). These are files that have either been uploaded by
|
||||
* users or were generated automatically (for example through CSS
|
||||
* aggregation).
|
||||
* - "shipped files", i.e. those outside of the files directory, which ship as
|
||||
* part of Drupal core or contributed modules or themes.
|
||||
*
|
||||
* @param $path
|
||||
* A string containing the Drupal path (i.e. path relative to the Drupal
|
||||
* root directory) of the file to generate the URL for.
|
||||
* @return
|
||||
* A string containing a URL that can be used to download the file.
|
||||
*/
|
||||
function advagg_file_create_url($path) {
|
||||
// Clean up Windows paths.
|
||||
$old_path = $path = str_replace('\\', '/', $path);
|
||||
|
||||
drupal_alter('file_url', $path);
|
||||
|
||||
// If any module has altered the path, then return the alteration.
|
||||
if ($path != $old_path) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
// Otherwise serve the file from Drupal's web server. This point will only
|
||||
// be reached when either no custom_file_url_rewrite() function has been
|
||||
// defined, or when that function returned FALSE, thereby indicating that it
|
||||
// cannot (or doesn't wish to) rewrite the URL. This is typically because
|
||||
// the file doesn't match some conditions to be served from a CDN or static
|
||||
// file server, or because the file has not yet been synced to the CDN or
|
||||
// static file server.
|
||||
|
||||
// Shipped files.
|
||||
if (strpos($path, file_directory_path() . '/') !== 0) {
|
||||
return base_path() . $path;
|
||||
}
|
||||
// Created files.
|
||||
else {
|
||||
switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) {
|
||||
case FILE_DOWNLOADS_PUBLIC:
|
||||
return $GLOBALS['base_url'] . '/' . $path;
|
||||
case FILE_DOWNLOADS_PRIVATE:
|
||||
// Strip file_directory_path from $path. Private downloads' URLs are
|
||||
// rewritten to be served relatively to system/files (which is a menu
|
||||
// callback that streams the file) instead of relatively to the file
|
||||
// directory path.
|
||||
$path = file_directory_strip($path);
|
||||
return url('system/files/' . $path, array('absolute' => TRUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ***MODIFIED CORE FUNCTIONS BELOW***
|
||||
*
|
||||
|
@ -2066,7 +2160,7 @@ function advagg_process_css($css = NULL, $noagg = FALSE) {
|
|||
$files = array();
|
||||
foreach ($types as $type) {
|
||||
foreach ($type as $file => $cache) {
|
||||
if ($cache) {
|
||||
if ($cache && advagg_file_exists($file)) {
|
||||
$files[] = $file;
|
||||
$files_included[$media][$file] = TRUE;
|
||||
unset($files_aggregates_included[$file]);
|
||||
|
@ -2664,9 +2758,9 @@ function advagg_css_js_file_builder($type, $files, $query_string = '', $counter
|
|||
|
||||
// Only generate once.
|
||||
$lock_name = 'advagg_' . $filename;
|
||||
if (!lock_acquire($lock_name)) {
|
||||
if (!lock_acquire($lock_name) && !$force) {
|
||||
if (variable_get('advagg_aggregate_mode', ADVAGG_AGGREGATE_MODE) == 0 ) {
|
||||
$locks[] = array($lock_name => $filepath);
|
||||
$locks[$lock_name] = $filepath;
|
||||
$output[$filepath] = array(
|
||||
'prefix' => $prefix,
|
||||
'suffix' => $suffix,
|
||||
|
@ -2771,15 +2865,32 @@ function advagg_css_js_file_builder($type, $files, $query_string = '', $counter
|
|||
* string containing all the files.
|
||||
*/
|
||||
function advagg_build_css_bundle($files) {
|
||||
$data = '';
|
||||
// Check if CSS compression is enabled.
|
||||
if (module_exists('advagg_css') && (variable_get('advagg_css_compress_agg_files', ADVAGG_CSS_COMPRESS_AGG_FILES) || variable_get('advagg_css_compress_inline', ADVAGG_CSS_COMPRESS_INLINE))) {
|
||||
$optimize = FALSE;
|
||||
}
|
||||
else {
|
||||
$optimize = TRUE;
|
||||
}
|
||||
|
||||
// Build aggregate CSS file.
|
||||
$data = '';
|
||||
foreach ($files as $file) {
|
||||
$contents = drupal_load_stylesheet($file, TRUE);
|
||||
// Return the path to where this CSS file originated from.
|
||||
$base = base_path() . dirname($file) . '/';
|
||||
_drupal_build_css_path(NULL, $base);
|
||||
// Prefix all paths within this CSS file, ignoring external and absolute paths.
|
||||
$data .= preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $contents);
|
||||
$contents = advagg_drupal_load_stylesheet($file, $optimize);
|
||||
|
||||
// Build the base URL of this CSS file: start with the full URL.
|
||||
$css_base_url = advagg_file_create_url($file);
|
||||
// Move to the parent.
|
||||
$css_base_url = substr($css_base_url, 0, strrpos($css_base_url, '/'));
|
||||
// Simplify to a relative URL if the stylesheet URL starts with the
|
||||
// base URL of the website.
|
||||
if (substr($css_base_url, 0, strlen($GLOBALS['base_root'])) == $GLOBALS['base_root']) {
|
||||
$css_base_url = substr($css_base_url, strlen($GLOBALS['base_root']));
|
||||
}
|
||||
|
||||
_drupal_build_css_path(NULL, $css_base_url . '/');
|
||||
// Anchor all paths in the CSS with its base URL, ignoring external and absolute paths.
|
||||
$data .= preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $contents);
|
||||
}
|
||||
|
||||
// Per the W3C specification at http://www.w3.org/TR/REC-CSS2/cascade.html#at-import,
|
||||
|
@ -2806,9 +2917,10 @@ function advagg_build_js_bundle($files) {
|
|||
$data = '';
|
||||
// Build aggregate JS file.
|
||||
foreach ($files as $file) {
|
||||
// Append a ';' and a newline after each JS file to prevent them from running together.
|
||||
// Append a ';', '/**/', and a newline after each JS file to prevent them
|
||||
// from running together.
|
||||
if (advagg_file_exists($file)) {
|
||||
$data .= file_get_contents($file) . ";\n";
|
||||
$data .= @file_get_contents($file) . ";/**/\n";
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
|
@ -3013,14 +3125,26 @@ function advagg_add_css_inline($data = NULL, $media = 'all', $prefix = NULL, $su
|
|||
* We use HTML-safe strings, i.e. with <, > and & escaped.
|
||||
*/
|
||||
function advagg_drupal_to_js($var) {
|
||||
// Different versions of PHP handle json_encode() differently.
|
||||
static $php550;
|
||||
static $php530;
|
||||
if (!isset($php550)) {
|
||||
$php550 = version_compare(PHP_VERSION, '5.5.0', '>=');
|
||||
}
|
||||
if (!isset($php530)) {
|
||||
$php530 = version_compare(PHP_VERSION, '5.3.0', '>=');
|
||||
}
|
||||
|
||||
// json_encode on PHP prior to PHP 5.3.0 doesn't support options.
|
||||
if ($php530) {
|
||||
return json_encode($var, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
|
||||
// Default json encode options.
|
||||
$options = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
|
||||
if ($php550) {
|
||||
// Output partial json if PHP >= 5.5.0.
|
||||
$options |= JSON_PARTIAL_OUTPUT_ON_ERROR;
|
||||
}
|
||||
// Encode to JSON.
|
||||
return @json_encode($var, $options);
|
||||
}
|
||||
|
||||
// if json_encode exists, use it.
|
||||
|
@ -3197,6 +3321,54 @@ function _advagg_drupal_load_stylesheet($matches) {
|
|||
return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+)/i', 'url(\1' . $directory, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the stylesheet and resolves all @import commands.
|
||||
*
|
||||
* Loads a stylesheet and replaces @import commands with the contents of the
|
||||
* imported file. Use this instead of file_get_contents when processing
|
||||
* stylesheets.
|
||||
*
|
||||
* The returned contents are compressed removing white space and comments only
|
||||
* when CSS aggregation is enabled. This optimization will not apply for
|
||||
* color.module enabled themes with CSS aggregation turned off.
|
||||
*
|
||||
* @param $file
|
||||
* Name of the stylesheet to be processed.
|
||||
* @param $optimize
|
||||
* Defines if CSS contents should be compressed or not.
|
||||
* @param $reset_basepath
|
||||
* Used internally to facilitate recursive resolution of @import commands.
|
||||
*
|
||||
* @return
|
||||
* Contents of the stylesheet, including any resolved @import commands.
|
||||
*/
|
||||
function advagg_drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE) {
|
||||
// These statics are not cache variables, so we don't use drupal_static().
|
||||
static $_optimize, $basepath;
|
||||
if ($reset_basepath) {
|
||||
$basepath = '';
|
||||
}
|
||||
// Store the value of $optimize for preg_replace_callback with nested
|
||||
// @import loops.
|
||||
if (isset($optimize)) {
|
||||
$_optimize = $optimize;
|
||||
}
|
||||
// Stylesheets are relative one to each other. Start by adding a base path
|
||||
// prefix provided by the parent stylesheet (if necessary).
|
||||
if ($basepath && !file_uri_scheme($file)) {
|
||||
$file = $basepath . '/' . $file;
|
||||
}
|
||||
$basepath = dirname($file);
|
||||
// Load the CSS stylesheet. We suppress errors because themes may specify
|
||||
// stylesheets in their .info file that don't exist in the theme's path,
|
||||
// but are merely there to disable certain module CSS files.
|
||||
if ($contents = @file_get_contents($file)) {
|
||||
// Return the processed stylesheet.
|
||||
return advagg_drupal_load_stylesheet_content($contents, $_optimize);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an HTTP request; does not wait for reply & you will never get it
|
||||
* back.
|
||||
|
|
Reference in a new issue