View source
<?php
define('ADVAGG_ENABLED', TRUE);
define('ADVAGG_STALE_FILE_THRESHOLD', 518400);
define('ADVAGG_STALE_FILE_LAST_USED_THRESHOLD', 259200);
define('ADVAGG_FILE_LAST_USED_INTERVAL', 1296000);
define('ADVAGG_GZIP_COMPRESSION', FALSE);
define('ADVAGG_ASYNC_GENERATION', FALSE);
define('ADVAGG_SOCKET_TIMEOUT', 1);
define('ADVAGG_CHECKSUM_MODE', 'mtime');
define('ADVAGG_DEBUG', FALSE);
define('ADVAGG_CSS_COUNT_THRESHOLD', 25);
define('ADVAGG_CSS_LOGGED_IN_IE_DETECT', TRUE);
define('ADVAGG_DIR_HTACCESS', TRUE);
define('ADVAGG_CUSTOM_FILES_DIR', '');
define('ADVAGG_CSS_RENDER_FUNCTION', 'advagg_unlimited_css_builder');
define('ADVAGG_JS_RENDER_FUNCTION', 'advagg_js_builder');
define('ADVAGG_FILE_SAVE_FUNCTION', 'advagg_file_saver');
define('ADVAGG_REBUILD_ON_FLUSH', FALSE);
define('ADVAGG_CLOSURE', TRUE);
define('ADVAGG_STRICT_JS_BUNDLES', TRUE);
define('ADVAGG_SET_TIME_LIMIT', 240);
define('ADVAGG_AGGREGATE_MODE', 2);
define('ADVAGG_PAGE_CACHE_MODE', TRUE);
define('ADVAGG_BUNDLE_BUILT_MODE', FALSE);
define('ADVAGG_ASYNC_SOCKET_CONNECT', FALSE);
define('ADVAGG_PRUNE_ON_CRON', TRUE);
define('ADVAGG_USE_FULL_CACHE', TRUE);
define('ADVAGG_PREPROCESS_JS', TRUE);
define('ADVAGG_PREPROCESS_CSS', TRUE);
define('ADVAGG_ONLY_CSS_FROM_VARIABLES', FALSE);
if (variable_get('advagg_closure', ADVAGG_CLOSURE)) {
if (!function_exists('phptemplate_closure')) {
function phptemplate_closure($main = 0) {
global $_advagg;
$_advagg['closure'] = TRUE;
$footer = implode("\n", module_invoke_all('footer', $main));
if (!variable_get('advagg_enabled', ADVAGG_ENABLED)) {
$footer .= drupal_get_js('footer');
}
return $footer;
}
}
else {
global $_advagg;
$_advagg['closure'] = FALSE;
}
}
function advagg_perm() {
return array(
'bypass advanced aggregation',
);
}
function advagg_menu() {
list($css_path, $js_path) = advagg_get_root_files_dir();
$file_path = drupal_get_path('module', 'advagg');
$items = array();
$items[$css_path . '/%'] = array(
'page callback' => 'advagg_missing_css',
'type' => MENU_CALLBACK,
'access callback' => TRUE,
'file path' => $file_path,
'file' => 'advagg.missing.inc',
);
$items[$js_path . '/%'] = array(
'page callback' => 'advagg_missing_js',
'type' => MENU_CALLBACK,
'access callback' => TRUE,
'file path' => $file_path,
'file' => 'advagg.missing.inc',
);
$items['admin/settings/advagg'] = array(
'title' => 'Advanced CSS/JS Aggregation',
'description' => 'Configuration for Advanced CSS/JS Aggregation.',
'page callback' => 'advagg_admin_page',
'type' => MENU_NORMAL_ITEM,
'access arguments' => array(
'administer site configuration',
),
'file path' => $file_path,
'file' => 'advagg.admin.inc',
);
$items['admin/settings/advagg/config'] = array(
'title' => 'Configuration',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/settings/advagg/info'] = array(
'title' => 'Information',
'description' => 'More detailed information about advagg.',
'page callback' => 'advagg_admin_info_page',
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer site configuration',
),
'file path' => $file_path,
'file' => 'advagg.admin.inc',
);
$items['admin_menu/flush-cache/advagg'] = array(
'page callback' => 'advagg_admin_flush_cache',
'type' => MENU_CALLBACK,
'access arguments' => array(
'administer site configuration',
),
'file path' => $file_path,
'file' => 'advagg.admin.inc',
);
return $items;
}
function advagg_admin_menu(&$deleted) {
$links = array();
$links[] = array(
'title' => 'Adv CSS/JS Agg',
'path' => 'admin_menu/flush-cache/advagg',
'query' => 'destination',
'parent_path' => 'admin_menu/flush-cache',
);
return $links;
}
function advagg_admin_menu_output_alter(&$content) {
if (!empty($content['icon']['icon']['flush-cache']['#access']) && !empty($content['icon']['icon']['flush-cache']['requisites']) && empty($content['icon']['icon']['flush-cache']['advagg'])) {
$content['icon']['icon']['flush-cache']['advagg'] = $content['icon']['icon']['flush-cache']['requisites'];
$content['icon']['icon']['flush-cache']['advagg']['#title'] = t('Adv CSS/JS Agg');
$content['icon']['icon']['flush-cache']['advagg']['#href'] = 'admin_menu/flush-cache/advagg';
}
}
function advagg_cron() {
if (!variable_get('advagg_prune_on_cron', ADVAGG_PRUNE_ON_CRON)) {
return;
}
$max_time = module_exists('advagg_bundler') ? variable_get('advagg_bundler_outdated', ADVAGG_BUNDLER_OUTDATED) : 1209600;
$max_file_time = time() - $max_time;
$max_bundle_time = time() - $max_time * 3;
$bundles_removed = 0;
$files_removed = array();
$results = db_query("SELECT filename, filename_md5 FROM {advagg_files}");
while ($row = db_fetch_array($results)) {
if (file_exists($row['filename'])) {
continue;
}
$bundles = db_query("SELECT bundle_md5 FROM {advagg_bundles} WHERE filename_md5 = '%s' AND timestamp < %d", $row['filename_md5'], $max_file_time);
while ($bundle_md5 = db_result($bundles)) {
$bundles_removed++;
db_query("DELETE FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $bundle_md5);
}
$count = db_result(db_query("SELECT COUNT(*) FROM {advagg_bundles} WHERE filename_md5 = '%s'", $row['filename_md5']));
if (empty($count)) {
db_query("DELETE FROM {advagg_files} WHERE filename_md5 = '%s'", $row['filename_md5']);
$files_removed[] = $row['filename'];
}
}
$bundles_removed += db_result(db_query("\n SELECT COUNT(DISTINCT bundle_md5) AS advagg_count\n FROM {advagg_bundles}\n WHERE timestamp < %d\n ", $max_bundle_time));
$results = db_query("DELETE FROM {advagg_bundles} WHERE timestamp < %d", $max_bundle_time);
if (!empty($bundles_removed) || !empty($files_removed)) {
watchdog('advagg', 'Cron ran and the following files where removed from the database: %files <br /> %count old bundles where also removed from the database.', array(
'%files' => implode(', ', $files_removed),
'%count' => $bundles_removed,
));
}
}
function advagg_init() {
global $base_path, $conf, $_advagg;
if (isset($_GET['advagg']) && $_GET['advagg'] == -1 && user_access('bypass advanced aggregation')) {
$conf['advagg_enabled'] = FALSE;
$conf['advagg_use_full_cache'] = FALSE;
}
if (isset($_GET['advagg-debug']) && $_GET['advagg-debug'] == 1 && user_access('bypass advanced aggregation')) {
$conf['advagg_debug'] = TRUE;
$conf['advagg_use_full_cache'] = FALSE;
}
if (isset($_GET['advagg-core']) && $_GET['advagg-core'] == 1 && user_access('bypass advanced aggregation')) {
$conf['preprocess_css'] = TRUE;
$conf['preprocess_js'] = TRUE;
$conf['advagg_use_full_cache'] = FALSE;
}
if (function_exists('ctools_include')) {
ctools_include('ajax');
}
if (variable_get('advagg_enabled', ADVAGG_ENABLED) && function_exists('ctools_ajax_run_page_preprocess')) {
ctools_ajax_run_page_preprocess(FALSE);
$_advagg['ctools_patched'] = TRUE;
}
}
function advagg_theme_registry_alter(&$theme_registry) {
global $_advagg;
if (isset($theme_registry['page'])) {
if (module_exists('jquery_update') && ($key = array_search('jquery_update_preprocess_page', $theme_registry['page']['preprocess functions']))) {
unset($theme_registry['page']['preprocess functions'][$key]);
}
if (!empty($_advagg['ctools_patched']) && module_exists('ctools') && ($key = array_search('ctools_ajax_page_preprocess', $theme_registry['page']['preprocess functions']))) {
unset($theme_registry['page']['preprocess functions'][$key]);
}
$theme_registry['page']['preprocess functions'][] = 'advagg_processor';
if (module_exists('labjs') && ($key = array_search('labjs_preprocess_page', $theme_registry['page']['preprocess functions']))) {
$theme_registry['page']['preprocess functions'][] = $theme_registry['page']['preprocess functions'][$key];
unset($theme_registry['page']['preprocess functions'][$key]);
}
if (module_exists('designkit') && ($key = array_search('designkit_preprocess_page', $theme_registry['page']['preprocess functions']))) {
$theme_registry['page']['preprocess functions'][] = $theme_registry['page']['preprocess functions'][$key];
unset($theme_registry['page']['preprocess functions'][$key]);
}
if (module_exists('conditional_styles') && ($key = array_search('conditional_styles_preprocess_page', $theme_registry['page']['preprocess functions']))) {
$theme_registry['page']['preprocess functions'][] = $theme_registry['page']['preprocess functions'][$key];
unset($theme_registry['page']['preprocess functions'][$key]);
}
}
}
function advagg_get_root_files_dir($reset = FALSE) {
static $css_path = '';
static $js_path = '';
if ($reset) {
$css_path = '';
$js_path = '';
}
if (!empty($css_path) && !empty($js_path)) {
return array(
$css_path,
$js_path,
);
}
$public_downloads = variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC;
if (!$public_downloads) {
$custom_path = variable_get('advagg_custom_files_dir', ADVAGG_CUSTOM_FILES_DIR);
}
if (empty($custom_path)) {
$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);
if (!variable_get('advagg_no_conf_path', FALSE)) {
$conf_path = conf_path();
if (is_link($conf_path)) {
$path = readlink($conf_path);
}
$conf_path = str_replace("\\", '/', $conf_path);
$conf_path = explode('/', $conf_path);
$conf_path = array_pop($conf_path);
$custom_path = $custom_path . '/' . $conf_path;
}
file_check_directory($custom_path, FILE_CREATE_DIRECTORY);
$css_path = $custom_path . '/advagg_css';
$js_path = $custom_path . '/advagg_js';
file_check_directory($css_path, FILE_CREATE_DIRECTORY);
file_check_directory($js_path, FILE_CREATE_DIRECTORY);
return array(
$css_path,
$js_path,
);
}
function advagg_merge_css($array1, $array2) {
if (!empty($array2)) {
foreach ($array2 as $media => $types) {
foreach ($types as $type => $files) {
foreach ($files as $file => $preprocess) {
$array1[$media][$type][$file] = $preprocess;
}
}
}
}
return $array1;
}
function advagg_merge_inline_css($array1, $array2) {
foreach ($array2 as $media => $types) {
foreach ($types as $type => $blobs) {
foreach ($blobs as $prefix => $data) {
foreach ($data as $suffix => $blob) {
$array1[$media][$type][$prefix][$suffix] = $blob;
}
}
}
}
return $array1;
}
function advagg_css_array_fixer(&$css_func) {
if (!module_exists('less')) {
return;
}
foreach ($css_func as $k => $v) {
foreach ($v as $ke => $va) {
foreach ($va as $file => $preprocess) {
if (substr($file, -5) === '.less') {
unset($css_func[$k][$ke][$file]);
}
}
}
}
}
function advagg_color_css(&$css) {
if (!module_exists('color') || empty($css['all']['theme'])) {
return;
}
$file_path = file_directory_path();
$files = array();
foreach ($css['all']['theme'] as $file => $preprocess) {
if (strpos($file, $file_path) === FALSE) {
continue;
}
if (strpos($file, '/color/') === FALSE) {
continue;
}
$files[basename($file)] = $file;
}
if (empty($files)) {
return;
}
foreach ($css['all']['theme'] as $file => $preprocess) {
$basename = basename($file);
if (isset($files[$basename]) && !in_array($file, $files)) {
unset($css['all']['theme'][$file]);
}
}
}
function advagg_string_ends_with($haystack, $needle) {
if (!function_exists('substr_compare')) {
function substr_compare($main_str, $str, $offset, $length = NULL, $case_insensitivity = FALSE) {
$offset = (int) $offset;
if ($offset >= strlen($main_str)) {
trigger_error('The start position cannot exceed initial string length.', E_USER_WARNING);
return FALSE;
}
if ($offset == 0 && is_int($length) && $case_insensitivity === TRUE) {
return strncasecmp($main_str, $str, $length);
}
if (is_int($length)) {
$main_substr = substr($main_str, $offset, $length);
$str_substr = substr($str, 0, $length);
}
else {
$main_substr = substr($main_str, $offset);
$str_substr = $str;
}
if ($case_insensitivity === TRUE) {
return strcasecmp($main_substr, $str_substr);
}
return strcmp($main_substr, $str_substr);
}
}
$haystack_len = strlen($haystack);
$needle_len = strlen($needle);
if ($needle_len > $haystack_len) {
return FALSE;
}
return substr_compare($haystack, $needle, $haystack_len - $needle_len, $needle_len, TRUE) === 0;
}
function advagg_advagg_disable_processor() {
if (isset($_GET['q']) && ($_GET['q'] == 'admin/settings/advagg' || $_GET['q'] == 'admin/settings/advagg/config' || $_GET['q'] == 'batch')) {
return TRUE;
}
}
function advagg_get_server_schema() {
return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || isset($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] == 'on' ? 'https' : 'http';
}
function advagg_processor(&$variables) {
global $_advagg, $conf;
$disabled = module_invoke_all('advagg_disable_processor');
if (!variable_get('advagg_enabled', ADVAGG_ENABLED) || in_array(TRUE, $disabled, TRUE)) {
if (module_exists('jquery_update')) {
return jquery_update_preprocess_page($variables);
}
else {
return;
}
}
if (isset($_GET['advagg']) && user_access('bypass advanced aggregation')) {
$conf['advagg_use_full_cache'] = FALSE;
}
$cookie_name = 'AdvAggDisabled';
$key = md5(drupal_get_private_key());
if (!empty($_COOKIE[$cookie_name]) && $_COOKIE[$cookie_name] == $key) {
$conf['advagg_use_full_cache'] = FALSE;
}
$schema = advagg_get_server_schema();
$css_var = $variables['css'];
$css_orig = $css_var;
if (!variable_get('advagg_only_css_from_variables', ADVAGG_ONLY_CSS_FROM_VARIABLES)) {
$css_func = drupal_add_css();
advagg_css_array_fixer($css_func);
}
else {
$css_func = array();
}
$css = advagg_merge_css($css_var, $css_func);
$css_func_inline = advagg_add_css_inline();
if (!empty($css_func_inline)) {
$css = advagg_merge_inline_css($css, $css_func_inline);
}
$css_conditional_styles = !empty($variables['conditional_styles']) ? $variables['conditional_styles'] : '';
$css_styles = $variables['styles'];
advagg_color_css($css);
if (variable_get('advagg_use_full_cache', ADVAGG_USE_FULL_CACHE)) {
$cid = 'advagg_processor:css:' . md5(serialize(array(
$css,
$css_conditional_styles,
))) . ':' . $schema . ':' . $_SERVER['HTTP_HOST'] . ':' . variable_get('advagg_css_render_function', ADVAGG_CSS_RENDER_FUNCTION) . ':' . substr(variable_get('css_js_query_string', '0'), 0, 1);
$cache = cache_get($cid, 'cache_advagg_bundle_reuse');
}
elseif (isset($cid)) {
unset($cid);
}
if (!empty($cache->data)) {
$variables['styles'] = $cache->data;
}
else {
$processed_css = advagg_process_css($css);
if (!empty($processed_css)) {
$variables['styles'] = $processed_css;
}
$variables['styles'] .= $css_conditional_styles;
if (isset($cid) && variable_get('advagg_use_full_cache', ADVAGG_USE_FULL_CACHE) && lock_acquire($cid)) {
cache_set($cid, $variables['styles'], 'cache_advagg_bundle_reuse', CACHE_TEMPORARY);
lock_release($cid);
}
}
$js_code = array();
$js_code['header'] = drupal_add_js(NULL, NULL, 'header');
if (variable_get('advagg_closure', ADVAGG_CLOSURE) && !empty($_advagg['closure'])) {
$js_code['footer'] = drupal_add_js(NULL, NULL, 'footer');
}
$skip_keys = variable_get('advagg_region_skip_keys', array(
'styles',
'scripts',
'zebra',
'id',
'directory',
'layout',
'head_title',
'base_path',
'front_page',
'head',
'body_classes',
'header',
'footer',
'closure',
));
foreach ($variables as $key => $value) {
if (!in_array($key, $skip_keys) && is_string($value) && !empty($value) && !isset($js_code[$key])) {
$js_code[$key] = drupal_add_js(NULL, NULL, $key);
}
}
$js_code_orig = $js_code;
if (variable_get('advagg_use_full_cache', ADVAGG_USE_FULL_CACHE)) {
$cid = 'advagg_processor:js:' . md5(serialize($js_code)) . ':' . $schema . ':' . $_SERVER['HTTP_HOST'] . ':' . variable_get('advagg_js_render_function', ADVAGG_JS_RENDER_FUNCTION) . ':' . substr(variable_get('css_js_query_string', '0'), 0, 1);
$cache = cache_get($cid, 'cache_advagg_bundle_reuse');
}
elseif (isset($cid)) {
unset($cid);
}
if (!empty($cache->data)) {
$js_code = $cache->data;
}
else {
advagg_jquery_updater($js_code['header']);
$js_code = advagg_process_js($js_code);
if (isset($cid) && variable_get('advagg_use_full_cache', ADVAGG_USE_FULL_CACHE) && lock_acquire($cid)) {
cache_set($cid, $js_code, 'cache_advagg_bundle_reuse', CACHE_TEMPORARY);
lock_release($cid);
}
}
foreach ($js_code as $key => $value) {
if ($key == 'header') {
$variables['scripts'] = $value;
}
elseif ($key == 'footer' && variable_get('advagg_closure', ADVAGG_CLOSURE) && !empty($_advagg['closure'])) {
$variables['closure'] .= $value;
}
else {
$variables[$key] .= $value;
}
}
advagg_async_send_http_request();
if (variable_get('advagg_debug', ADVAGG_DEBUG)) {
$data = array(
'css_before_vars' => $css_orig,
'css_before_function' => $css_func,
'css_before_styles' => $css_styles,
'css_before_inline' => $css_func_inline,
'css_before_conditional_styles' => $css_conditional_styles,
'css_merged' => $css,
'css_after' => $processed_css,
'js_before' => $js_code_orig,
'js_after' => $js_code,
);
$data['runtime'] = isset($_advagg['debug']) ? $_advagg['debug'] : FALSE;
$data = str_replace(' ', ' ', nl2br(htmlentities(iconv('utf-8', 'utf-8//IGNORE', print_r($data, TRUE)), ENT_QUOTES, 'UTF-8')));
watchdog('advagg', 'Debug info: !data', array(
'!data' => $data,
), WATCHDOG_DEBUG);
}
}
function advagg_jquery_updater(&$js) {
if (!module_exists('jquery_update') || !variable_get('jquery_update_replace', TRUE) || empty($js)) {
return;
}
$new_jquery = array(
jquery_update_jquery_path() => $js['core']['misc/jquery.js'],
);
$js['core'] = array_merge($new_jquery, $js['core']);
unset($js['core']['misc/jquery.js']);
$replacement_path = drupal_get_path('module', 'jquery_update') . '/replace/';
foreach (jquery_update_get_replacements() as $type => $replacements) {
foreach ($replacements as $find => $replace) {
if (isset($js[$type][$find])) {
$replace = $replacement_path . $replace;
$js[$type][$replace] = $js[$type][$find];
unset($js[$type][$find]);
}
}
}
}
function advagg_get_filename($files, $filetype, $counter = FALSE, $bundle_md5 = '') {
if (empty($files) || empty($filetype)) {
return FALSE;
}
global $_advagg;
$filenames = array();
$run_alter = FALSE;
if (empty($bundle_md5)) {
$schema = advagg_get_server_schema();
$bundle_md5 = md5($schema . implode('', $files));
$run_alter = TRUE;
if (empty($counter)) {
$counter = db_result(db_query("SELECT counter FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $bundle_md5));
}
if ($counter === FALSE) {
$counter = 0;
advagg_insert_bundle_db($files, $filetype, $bundle_md5, TRUE);
}
$row = db_fetch_array(db_query("SELECT root, timestamp FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $bundle_md5));
if ($row['root'] === 0 || time() - $row['timestamp'] > variable_get('advagg_file_last_used_interval', ADVAGG_FILE_LAST_USED_INTERVAL)) {
db_query("UPDATE {advagg_bundles} SET root = '1', timestamp = %d WHERE bundle_md5 = '%s'", time(), $bundle_md5);
}
}
$filenames[] = array(
'filetype' => $filetype,
'files' => $files,
'counter' => $counter,
'bundle_md5' => $bundle_md5,
);
if ($run_alter) {
$filenames[0]['counter'] = FALSE;
drupal_alter('advagg_filenames', $filenames);
}
$output = array();
$used_md5 = array();
if (variable_get('advagg_debug', ADVAGG_DEBUG)) {
$_advagg['debug']['get_filename_post_alter'][] = array(
'key' => $bundle_md5,
'filenames' => $filenames,
);
}
$counters = array();
foreach ($filenames as $key => $values) {
if (empty($values['counter'])) {
$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, counter');
while ($row = db_fetch_array($result)) {
$key = array_search($row['bundle_md5'], $counters);
if (empty($filenames[$key]['counter']) && $filenames[$key]['counter'] !== 0) {
$filenames[$key]['counter'] = intval($row['counter']);
}
}
foreach ($filenames as $values) {
$filetype = $values['filetype'];
$files = $values['files'];
$counter = $values['counter'];
$bundle_md5 = $values['bundle_md5'];
if (isset($used_md5[$bundle_md5])) {
continue;
}
$used_md5[$bundle_md5] = TRUE;
if (empty($counter) && $counter !== 0) {
$counter = 0;
advagg_insert_bundle_db($files, $filetype, $bundle_md5, FALSE);
}
$output[] = array(
'filename' => advagg_build_filename($filetype, $bundle_md5, $counter),
'files' => $files,
'bundle_md5' => $bundle_md5,
);
$row = db_fetch_array(db_query("SELECT timestamp FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $bundle_md5));
if (time() - $row['timestamp'] > variable_get('advagg_file_last_used_interval', ADVAGG_FILE_LAST_USED_INTERVAL)) {
db_query("UPDATE {advagg_bundles} SET timestamp = %d WHERE bundle_md5 = '%s'", time(), $bundle_md5);
}
}
return $output;
}
function advagg_cached_bundle_get($cached_data_key, $debug_name) {
global $_advagg;
$data = cache_get($cached_data_key, 'cache_advagg_bundle_reuse');
if (!empty($data->data)) {
$data = $data->data;
$bundle_contents = array();
$good = TRUE;
if (variable_get('advagg_debug', ADVAGG_DEBUG)) {
foreach ($data as $filename => $extra) {
if (is_numeric($filename)) {
continue;
}
$b_md5 = explode('/', $filename);
$b_md5 = explode('_', array_pop($b_md5));
$b_md5 = $b_md5[1];
if (!empty($b_md5)) {
list($b_filetype, $b_files) = advagg_get_files_in_bundle($b_md5);
$bundle_contents[$filename] = $b_files;
if (empty($b_files)) {
$good = FALSE;
}
}
}
$_advagg['debug'][$debug_name][] = array(
'key' => $cached_data_key,
'cache' => $data,
'bundle_contents' => $bundle_contents,
);
}
if ($good) {
return $data;
}
}
return FALSE;
}
function advagg_find_existing_bundle(&$files, &$bundle_md5) {
$temp_files = $files;
sort($temp_files);
$schema = advagg_get_server_schema();
$cached_data_key = 'advagg_existing_' . md5($schema . implode('', $temp_files));
$cached_data = advagg_cached_bundle_get($cached_data_key, 'advagg_find_existing_bundle');
if (!empty($cached_data)) {
$files = $cached_data[0]['files'];
$bundle_md5 = $cached_data[0]['bundle_md5'];
return;
}
$query = 'SELECT root.bundle_md5 FROM {advagg_bundles} AS root';
$joins = array();
$wheres = array();
$args = array();
$counter = 0;
foreach ($files as $filename) {
$key = strtr($counter, '01234567890', 'abcdefghij');
$joins[$key] = "\nINNER JOIN {advagg_bundles} AS {$key} USING(bundle_md5)\n";
if ($counter == 0) {
$wheres[$key] = "WHERE {$key}.filename_md5 = '%s'";
}
else {
$wheres[$key] = "AND {$key}.filename_md5 = '%s'";
}
$args[$key] = md5($filename);
$counter++;
}
$query .= implode("\n", $joins);
$query .= implode("\n", $wheres);
$query .= ' GROUP BY bundle_md5';
$files_count = count($files);
$results = db_query($query, $args);
while ($new_md5 = db_result($results)) {
$count = db_result(db_query("SELECT count(*) FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $new_md5));
if (!empty($count) && $count == $files_count) {
$bundle_md5 = $new_md5;
$data = array(
array(
'files' => $files,
'bundle_md5' => $bundle_md5,
),
);
cache_set($cached_data_key, $data, 'cache_advagg_bundle_reuse', CACHE_TEMPORARY);
return;
}
}
}
function advagg_build_filename($filetype, $bundle_md5, $counter) {
return $filetype . '_' . $bundle_md5 . '_' . $counter . '.' . $filetype;
}
function advagg_insert_bundle_db($files, $filetype, $bundle_md5, $root) {
$lock_name = 'advagg_insert_bundle_db' . $bundle_md5;
if (!lock_acquire($lock_name)) {
if (variable_get('advagg_aggregate_mode', ADVAGG_AGGREGATE_MODE) < 2) {
lock_wait($lock_name);
}
return;
}
$bundle_exists = db_result(db_query("SELECT 1 FROM {advagg_bundles} WHERE bundle_md5 = '%s'", $bundle_md5));
if ($bundle_exists) {
lock_release($lock_name);
return;
}
foreach ($files as $order => $filename) {
$filename_md5 = md5($filename);
$checksum = db_result(db_query("SELECT checksum FROM {advagg_files} WHERE filename_md5 = '%s'", $filename_md5));
if (empty($checksum)) {
$checksum = advagg_checksum($filename);
db_query("INSERT INTO {advagg_files} (filename, filename_md5, checksum, filetype, filesize) VALUES ('%s', '%s', '%s', '%s', %d)", $filename, $filename_md5, $checksum, $filetype, @filesize($filename));
}
db_query("INSERT INTO {advagg_bundles} (bundle_md5, filename_md5, counter, porder, root, timestamp) VALUES ('%s', '%s', '%d', '%d', '%d', '%d')", $bundle_md5, $filename_md5, 0, $order, $root, time());
}
lock_release($lock_name);
}
function advagg_file_saver($data, $dest, $force, $type) {
$tmp = file_directory_temp();
file_check_directory($tmp, FILE_CREATE_DIRECTORY);
$file_save_data = 'file_save_data';
$custom_path = variable_get('advagg_custom_files_dir', ADVAGG_CUSTOM_FILES_DIR);
if (!empty($custom_path)) {
$file_save_data = 'advagg_file_save_data';
}
if (!$file_save_data($data, $dest, FILE_EXISTS_REPLACE)) {
return FALSE;
}
advagg_clearstatcache(TRUE, $dest);
if (@filesize($dest) == 0 && !empty($data)) {
if (!$file_save_data($data, $dest, FILE_EXISTS_REPLACE)) {
return FALSE;
}
advagg_clearstatcache(TRUE, $dest);
if (@filesize($dest) == 0 && !empty($data)) {
file_delete($dest);
return FALSE;
}
}
if (variable_get('advagg_gzip_compression', ADVAGG_GZIP_COMPRESSION) && extension_loaded('zlib')) {
$gzip_dest = $dest . '.gz';
advagg_clearstatcache(TRUE, $gzip_dest);
if (!file_exists($gzip_dest) || $force) {
$gzip_data = gzencode($data, 9, FORCE_GZIP);
if (!$file_save_data($gzip_data, $gzip_dest, FILE_EXISTS_REPLACE)) {
return FALSE;
}
advagg_clearstatcache(TRUE, $gzip_dest);
if (@filesize($gzip_dest) == 0 && !empty($gzip_data)) {
if (!$file_save_data($gzip_data, $gzip_dest, FILE_EXISTS_REPLACE)) {
return FALSE;
}
advagg_clearstatcache(TRUE, $gzip_dest);
if (@filesize($gzip_dest) == 0 && !empty($gzip_data)) {
file_delete($gzip_dest);
return FALSE;
}
}
}
}
advagg_htaccess_check_generate($dest);
cache_set($dest, time(), 'cache_advagg', CACHE_PERMANENT);
return TRUE;
}
function advagg_file_save_data($data, $dest, $replace = FILE_EXISTS_RENAME) {
$temp = file_directory_temp();
$file = tempnam(realpath($temp), 'file');
if (!($fp = fopen($file, 'wb'))) {
drupal_set_message(t('The file could not be created.'), 'error');
return 0;
}
fwrite($fp, $data);
fclose($fp);
if (!advagg_file_move($file, $dest, $replace)) {
return 0;
}
return $file;
}
function advagg_file_move(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) {
$path_original = is_object($source) ? $source->filepath : $source;
if (advagg_file_copy($source, $dest, $replace)) {
$path_current = is_object($source) ? $source->filepath : $source;
if ($path_original == $path_current || file_delete($path_original)) {
return 1;
}
drupal_set_message(t('The removal of the original file %file has failed.', array(
'%file' => $path_original,
)), 'error');
}
return 0;
}
function advagg_file_copy(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) {
$directory = dirname($dest);
if (is_object($source)) {
$file = $source;
$source = $file->filepath;
if (!$basename) {
$basename = $file->filename;
}
}
$source = realpath($source);
advagg_clearstatcache(TRUE, $source);
if (!file_exists($source)) {
drupal_set_message(t('The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array(
'%file' => $source,
)), 'error');
return 0;
}
$basename = basename($dest);
$basename = $basename ? $basename : basename($source);
$dest = $directory . '/' . $basename;
if ($source != realpath($dest)) {
if (!($dest = file_destination($dest, $replace))) {
drupal_set_message(t('The selected file %file could not be copied, because a file by that name already exists in the destination.', array(
'%file' => $source,
)), 'error');
return FALSE;
}
$result = FALSE;
if ($replace == FILE_EXISTS_REPLACE) {
$temporary_file = tempnam(dirname($dest), 'file');
if ($temporary_file && @copy($source, $temporary_file)) {
if (!($result = @rename($temporary_file, $dest))) {
@unlink($dest);
$result = @rename($temporary_file, $dest);
}
if (!$result) {
@unlink($temporary_file);
}
}
}
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;
}
@chmod($dest, 0664);
}
if (isset($file) && is_object($file)) {
$file->filename = $basename;
$file->filepath = $dest;
$source = $file;
}
else {
$source = $dest;
}
return 1;
}
function advagg_checksum($filename) {
advagg_clearstatcache(TRUE, $filename);
if (file_exists($filename)) {
$mode = variable_get('advagg_checksum_mode', ADVAGG_CHECKSUM_MODE);
if ($mode == 'mtime') {
$checksum = @filemtime($filename);
if ($checksum === FALSE) {
touch($filename);
advagg_clearstatcache(TRUE, $filename);
$checksum = @filemtime($filename);
if ($checksum === FALSE) {
$checksum = md5(file_get_contents($filename));
}
}
}
elseif ($mode == 'md5') {
$checksum = md5(file_get_contents($filename));
}
}
else {
$checksum = '-1';
}
return $checksum;
}
function advagg_bundle_built($filepath) {
if (!variable_get('advagg_bundle_built_mode', ADVAGG_BUNDLE_BUILT_MODE)) {
advagg_clearstatcache(TRUE, $filepath);
return file_exists($filepath);
}
$data = advagg_get_bundle_from_filename(basename($filepath));
if (is_array($data)) {
list($type, $md5, $counter) = $data;
}
else {
return FALSE;
}
$data = cache_get($filepath, 'cache_advagg');
if (isset($data->data)) {
if (time() - $data->data > variable_get('advagg_file_last_used_interval', ADVAGG_FILE_LAST_USED_INTERVAL)) {
cache_set($filepath, time(), 'cache_advagg', CACHE_PERMANENT);
db_query("UPDATE {advagg_bundles} SET timestamp = %d WHERE bundle_md5 = '%s'", time(), $md5);
}
return TRUE;
}
advagg_clearstatcache(TRUE, $filepath);
if (file_exists($filepath)) {
if (@filesize($filepath) == 0) {
return FALSE;
}
}
else {
return FALSE;
}
cache_set($filepath, time(), 'cache_advagg', CACHE_PERMANENT);
db_query("UPDATE {advagg_bundles} SET timestamp = %d WHERE bundle_md5 = '%s'", time(), $md5);
return TRUE;
}
function advagg_get_bundle_from_filename($filename) {
if (!preg_match('/^(j|cs)s_[0-9a-f]{32}_\\d+\\.(j|cs)s$/', $filename)) {
return t('Wrong Pattern.');
}
$type = substr($filename, 0, strpos($filename, '_'));
$ext = substr($filename, strpos($filename, '.', 37) + 1);
if ($ext != $type) {
return t('Type does not match extension.');
}
if ($type == 'css') {
$md5 = substr($filename, 4, 32);
$counter = substr($filename, 37, strpos($filename, '.', 38) - 37);
}
elseif ($type == 'js') {
$md5 = substr($filename, 3, 32);
$counter = substr($filename, 36, strpos($filename, '.', 37) - 36);
}
else {
return t('Wrong file type.');
}
return array(
$type,
$md5,
$counter,
);
}
function advagg_flush_caches() {
if (function_exists('set_time_limit')) {
@set_time_limit(variable_get('advagg_set_time_limit', ADVAGG_SET_TIME_LIMIT));
}
global $_advagg;
if (!lock_acquire('advagg_flush_caches')) {
return;
}
if (!db_table_exists('advagg_files')) {
return array(
'cache_advagg_bundle_reuse',
);
}
$needs_refreshing = array();
$results = db_query("SELECT * FROM {advagg_files}");
while ($row = db_fetch_array($results)) {
$checksum = advagg_checksum($row['filename']);
$hook_results = module_invoke_all('advagg_files_table', $row, $checksum);
$update = FALSE;
if (!empty($hook_results)) {
foreach ($hook_results as $update) {
if ($update === TRUE) {
break;
}
}
}
if ($checksum != $row['checksum'] || $update == TRUE) {
$needs_refreshing[$row['filename_md5']] = $row['filename'];
db_query("UPDATE {advagg_files} SET checksum = '%s', counter = counter + 1 WHERE filename_md5 = '%s'", $checksum, $row['filename_md5']);
}
}
$bundles = array();
foreach ($needs_refreshing as $filename_md5 => $filename) {
$results = db_query("SELECT bundle_md5 FROM {advagg_bundles} WHERE filename_md5 = '%s'", $filename_md5);
while ($row = db_fetch_array($results)) {
$bundles[$row['bundle_md5']] = $row['bundle_md5'];
}
}
foreach ($bundles as $bundle_md5) {
db_query("UPDATE {advagg_bundles} SET counter = counter + 1, timestamp = %d WHERE bundle_md5 = '%s'", time(), $bundle_md5);
if (variable_get('advagg_rebuild_on_flush', ADVAGG_REBUILD_ON_FLUSH)) {
register_shutdown_function('advagg_rebuild_bundle', $bundle_md5, '', TRUE);
}
}
$_advagg['bundles'] = $bundles;
$_advagg['files'] = $needs_refreshing;
list($css_path, $js_path) = advagg_get_root_files_dir();
file_scan_directory($css_path, '.*', array(
'.',
'..',
'CVS',
), 'advagg_delete_file_if_stale', TRUE);
file_scan_directory($js_path, '.*', array(
'.',
'..',
'CVS',
), 'advagg_delete_file_if_stale', TRUE);
lock_release('advagg_flush_caches');
return array(
'cache_advagg_bundle_reuse',
);
}
function advagg_rebuild_bundle($bundle_md5, $counter = '', $force = FALSE) {
global $conf, $_advagg;
list($filetype, $files) = advagg_get_files_in_bundle($bundle_md5);
$conf['advagg_async_generation'] = FALSE;
$good = advagg_css_js_file_builder($filetype, $files, '', $counter, $force, $bundle_md5);
if (!$good) {
watchdog('advagg', 'This bundle could not be generated correctly. Bundle MD5: %md5', array(
'%md5' => $bundle_md5,
));
}
else {
$_advagg['rebuilt'][] = $bundle_md5;
}
return $good;
}
function advagg_get_files_in_bundle($bundle_md5) {
$files = array();
$filetype = NULL;
$results = db_query("SELECT filename, filetype FROM {advagg_files} AS af INNER JOIN {advagg_bundles} AS ab USING ( filename_md5 ) WHERE bundle_md5 = '%s' ORDER BY porder ASC", $bundle_md5);
while ($row = db_fetch_array($results)) {
$files[] = $row['filename'];
$filetype = $row['filetype'];
}
return array(
$filetype,
$files,
);
}
function advagg_delete_file_if_stale($filename) {
if (strpos($filename, '.gz') !== FALSE) {
return;
}
$now = time();
$file_last_mod = variable_get('advagg_stale_file_threshold', ADVAGG_STALE_FILE_THRESHOLD);
$file_last_used = variable_get('advagg_stale_file_last_used_threshold', ADVAGG_STALE_FILE_LAST_USED_THRESHOLD);
advagg_clearstatcache(TRUE, $filename);
if ($now - filemtime($filename) <= $file_last_mod) {
return;
}
$data = cache_get($filename, 'cache_advagg');
if (!empty($data->data)) {
advagg_clearstatcache(TRUE, $filename);
$file_last_a = @fileatime($filename);
$file_last_agz = @fileatime($filename . '.gz');
$file_last_a = max($file_last_a, $file_last_agz);
if ($now - $data->data > $file_last_used && $now - $file_last_a > $file_last_used) {
file_delete($filename);
file_delete($filename . '.gz');
}
else {
touch($filename);
}
}
else {
file_delete($filename);
file_delete($filename . '.gz');
}
}
function advagg_get_file_data($filename_md5) {
$data = cache_get($filename_md5, 'cache_advagg_files_data');
if (empty($data->data)) {
return FALSE;
}
return $data->data;
}
function advagg_set_file_data($filename_md5, $data) {
cache_set($filename_md5, $data, 'cache_advagg_files_data', CACHE_PERMANENT);
}
function advagg_build_uri($path) {
static $hook_file_url_alter = array();
$fragments = parse_url($path);
if (isset($fragments['host'])) {
return $path;
}
$original_path = $path;
if (module_exists('cdn')) {
$status = variable_get(CDN_STATUS_VARIABLE, CDN_DISABLED);
if ($status == CDN_ENABLED || $status == CDN_TESTING && user_access(CDN_PERM_ACCESS_TESTING)) {
if (variable_get(CDN_THEME_LAYER_FALLBACK_VARIABLE, FALSE)) {
cdn_file_url_alter($path);
}
else {
$path = advagg_file_create_url($path);
}
if (strcmp($original_path, $path) != 0) {
return $path;
}
}
}
if (empty($hook_file_url_alter)) {
$hook_file_url_alter = module_implements('file_url_alter');
}
if (!empty($hook_file_url_alter)) {
$path = advagg_file_create_url($path);
if (strcmp($original_path, $path) != 0) {
return $path;
}
}
return base_path() . $path;
}
function advagg_file_create_url($path) {
$old_path = $path = str_replace('\\', '/', $path);
drupal_alter('file_url', $path);
if ($path != $old_path) {
return $path;
}
if (strpos($path, file_directory_path() . '/') !== 0) {
return base_path() . $path;
}
else {
switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) {
case FILE_DOWNLOADS_PUBLIC:
return $GLOBALS['base_url'] . '/' . $path;
case FILE_DOWNLOADS_PRIVATE:
$path = file_directory_strip($path);
return url('system/files/' . $path, array(
'absolute' => TRUE,
));
}
}
}
function advagg_process_css_js_prep($noagg = FALSE, $type = NULL) {
global $conf;
$preprocess = !defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update';
if ($noagg || isset($_GET['advagg']) && $_GET['advagg'] == 0 && user_access('bypass advanced aggregation')) {
$preprocess = FALSE;
$conf['advagg_use_full_cache'] = FALSE;
}
$cookie_name = 'AdvAggDisabled';
$key = md5(drupal_get_private_key());
if (!empty($_COOKIE[$cookie_name]) && $_COOKIE[$cookie_name] == $key) {
$preprocess = FALSE;
$conf['advagg_use_full_cache'] = FALSE;
}
$public_downloads = variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC;
if (!$public_downloads) {
$custom_path = variable_get('advagg_custom_files_dir', ADVAGG_CUSTOM_FILES_DIR);
if (!empty($custom_path)) {
$public_downloads = TRUE;
}
}
if ($preprocess) {
if ($type == 'js' && !variable_get('advagg_preprocess_js', ADVAGG_PREPROCESS_JS)) {
$preprocess = FALSE;
}
if ($type == 'css' && !variable_get('advagg_preprocess_css', ADVAGG_PREPROCESS_CSS)) {
$preprocess = FALSE;
}
}
$query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1);
return array(
$preprocess,
$public_downloads,
$query_string,
);
}
function advagg_process_css($css = NULL, $noagg = FALSE) {
global $conf;
$original_css = $css;
if (!isset($css)) {
$css = drupal_add_css();
}
if (empty($css)) {
return FALSE;
}
list($preprocess_css, $public_downloads, $query_string) = advagg_process_css_js_prep($noagg, 'css');
drupal_alter('advagg_css_pre', $css, $preprocess_css, $public_downloads);
$external_no_preprocess = array();
$module_no_preprocess = array();
$output_no_preprocess = array();
$output_preprocess = array();
$theme_no_preprocess = array();
$inline_no_preprocess = array();
$files_included = array();
$files_aggregates_included = array();
$inline_included = array();
foreach ($css as $media => $types) {
$files_included[$media] = array();
$files_aggregates_included[$media] = array();
$inline_included[$media] = array();
foreach ($types as $type => $files) {
if ($type == 'module') {
$theme_styles = array();
foreach (array_keys($css[$media]['theme']) as $theme_style) {
$theme_styles[] = basename($theme_style);
}
}
foreach ($types[$type] as $file => $preprocess) {
if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) {
unset($types[$type][$file]);
continue;
}
if ($type == 'inline') {
if (is_array($preprocess)) {
foreach ($preprocess as $suffix => $blob) {
$blob = advagg_drupal_load_stylesheet_content($blob, $preprocess);
drupal_alter('advagg_css_inline', $blob);
$inline_no_preprocess[] = array(
'media' => $media,
'data' => $blob,
'prefix' => $file,
'suffix' => $suffix,
);
$inline_included[$media][] = $blob;
}
}
unset($types[$type][$file]);
continue;
}
$prefix = '';
$suffix = '';
$values = array(
$file,
NULL,
$prefix,
$suffix,
);
drupal_alter('advagg_css_extra', $values);
list($file, $null, $prefix, $suffix) = $values;
if ($type == 'inline') {
$file = advagg_drupal_load_stylesheet_content($file, $preprocess);
drupal_alter('advagg_css_inline', $file);
$inline_no_preprocess[] = array(
'media' => $media,
'data' => $file,
'prefix' => $prefix,
'suffix' => $suffix,
);
$inline_included[$media][] = $file;
unset($types[$type][$file]);
continue;
}
if ($type == 'external') {
$external_no_preprocess[] = array(
'media' => $media,
'href' => $file,
'prefix' => $prefix,
'suffix' => $suffix,
);
$files_included[$media][$file] = TRUE;
unset($types[$type][$file]);
continue;
}
if (advagg_file_exists($file)) {
if (!$preprocess || !($public_downloads && $preprocess_css)) {
$file_uri = advagg_build_uri($file) . $query_string;
$files_included[$media][$file] = $preprocess;
if (!$preprocess && $type == 'module') {
$module_no_preprocess[] = array(
'media' => $media,
'href' => $file_uri,
'prefix' => $prefix,
'suffix' => $suffix,
);
}
elseif (!$preprocess && $type == 'theme') {
$theme_no_preprocess[] = array(
'media' => $media,
'href' => $file_uri,
'prefix' => $prefix,
'suffix' => $suffix,
);
}
else {
$output_no_preprocess[] = array(
'media' => $media,
'href' => $file_uri,
'prefix' => $prefix,
'suffix' => $suffix,
);
}
}
}
}
}
if ($public_downloads && $preprocess_css) {
$files_aggregates_included[$media] = $files_included[$media];
$files = array();
foreach ($types as $type) {
foreach ($type as $file => $cache) {
if ($cache && advagg_file_exists($file)) {
$files[] = $file;
$files_included[$media][$file] = TRUE;
unset($files_aggregates_included[$file]);
}
}
}
if (!empty($files)) {
$preprocess_files = advagg_css_js_file_builder('css', $files, $query_string);
if (!empty($preprocess_files)) {
$good = TRUE;
foreach ($preprocess_files as $preprocess_file => $extra) {
if (empty($preprocess_file)) {
continue;
}
if ($extra !== FALSE && is_array($extra)) {
$prefix = $extra['prefix'];
$suffix = $extra['suffix'];
$output_preprocess[] = array(
'media' => $media,
'href' => advagg_build_uri($preprocess_file),
'prefix' => $prefix,
'suffix' => $suffix,
);
$files_aggregates_included[$media][$preprocess_file] = $extra;
}
else {
$good = FALSE;
break;
}
}
}
if (empty($good)) {
watchdog('advagg', 'CSS aggregation failed. %filename could not be saved correctly.', array(
'%filename' => $preprocess_file,
), WATCHDOG_ERROR);
$data = advagg_process_css($original_css, TRUE);
return $data;
}
}
}
}
$function = variable_get('advagg_css_render_function', ADVAGG_CSS_RENDER_FUNCTION);
return $function($external_no_preprocess, $module_no_preprocess, $output_no_preprocess, $output_preprocess, $theme_no_preprocess, $inline_no_preprocess, $inline_included, $files_included, $files_aggregates_included);
}
function advagg_unlimited_css_builder($external_no_preprocess, $module_no_preprocess, $output_no_preprocess, $output_preprocess, $theme_no_preprocess, $inline_no_preprocess, $files_included, $files_aggregates_included, $inline_included) {
global $user;
$styles = '';
$files = array_merge($external_no_preprocess, $module_no_preprocess, $output_no_preprocess, $output_preprocess, $theme_no_preprocess, $inline_no_preprocess);
if (count($files) < variable_get('advagg_css_count_threshold', ADVAGG_CSS_COUNT_THRESHOLD)) {
advagg_unlimited_css_traditional($files, $styles);
}
elseif (variable_get('advagg_css_logged_in_ie_detect', ADVAGG_CSS_LOGGED_IN_IE_DETECT) && $user->uid != 0) {
$is_ie = FALSE;
if (isset($_SERVER['HTTP_USER_AGENT'])) {
if (stristr($_SERVER['HTTP_USER_AGENT'], 'microsoft internet explorer') || stristr($_SERVER['HTTP_USER_AGENT'], 'msie') || stristr($_SERVER['HTTP_USER_AGENT'], 'mspie')) {
$is_ie = TRUE;
}
}
else {
$is_ie = TRUE;
}
if ($is_ie) {
advagg_unlimited_css_import(array_merge($external_no_preprocess, $module_no_preprocess, $output_no_preprocess), $styles);
advagg_unlimited_css_import($output_preprocess, $styles);
advagg_unlimited_css_import($theme_no_preprocess, $styles);
advagg_unlimited_css_traditional($inline_no_preprocess, $styles);
}
else {
advagg_unlimited_css_traditional($files, $styles);
}
}
else {
advagg_unlimited_css_import(array_merge($external_no_preprocess, $module_no_preprocess, $output_no_preprocess), $styles);
advagg_unlimited_css_import($output_preprocess, $styles);
advagg_unlimited_css_import($theme_no_preprocess, $styles);
advagg_unlimited_css_traditional($inline_no_preprocess, $styles);
}
return $styles;
}
function advagg_unlimited_css_traditional($files, &$styles) {
$last_prefix = '';
$last_suffix = '';
foreach ($files as $css_file) {
$media = $css_file['media'];
$prefix = empty($css_file['prefix']) ? '' : $css_file['prefix'] . "\n";
$suffix = empty($css_file['suffix']) ? '' : $css_file['suffix'];
if (isset($css_file['href'])) {
$href = $css_file['href'];
if ($prefix != $last_prefix) {
$styles .= $last_suffix . "\n" . $prefix . '<link type="text/css" rel="stylesheet" media="' . $media . '" href="' . $href . '" />' . "\n";
}
else {
$styles .= '<link type="text/css" rel="stylesheet" media="' . $media . '" href="' . $href . '" />' . "\n";
}
}
else {
$data = $css_file['data'];
if ($prefix != $last_prefix) {
$styles .= $last_suffix . "\n" . $prefix . '<style type="text/css" media="' . $media . '">' . "\n" . $data . "\n" . '</style>' . "\n";
}
else {
$styles .= '<style type="text/css" media="' . $media . '">' . "\n" . $data . "\n" . '</style>' . "\n";
}
}
$last_prefix = $prefix;
$last_suffix = $suffix;
}
$styles .= empty($last_suffix) ? '' : $last_suffix . "\n";
}
function advagg_unlimited_css_import($files, &$styles) {
$counter = 0;
$media = NULL;
$import = '';
foreach ($files as $css_file) {
$media_new = $css_file['media'];
$href = $css_file['href'];
if ($media_new != $media || $counter > variable_get('advagg_css_count_threshold', ADVAGG_CSS_COUNT_THRESHOLD)) {
if ($media && !empty($import)) {
$styles .= "\n" . '<style type="text/css" media="' . $media . '">' . "\n" . $import . '</style>';
$import = '';
}
$counter = 0;
$media = $media_new;
}
$import .= '@import "' . $href . '";' . "\n";
$counter++;
}
if ($media && !empty($import)) {
$styles .= "\n" . '<style type="text/css" media="' . $media . '">' . "\n" . $import . '</style>';
}
}
function advagg_process_js($master_set, $noagg = FALSE) {
global $conf;
if ((!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') && function_exists('locale_update_js_files')) {
locale_update_js_files();
}
list($preprocess_js, $public_downloads, $query_string) = advagg_process_css_js_prep($noagg, 'js');
$advagg_json_encode_function = variable_get('advagg_json_encode_function', 'advagg_drupal_to_js');
$output = array();
foreach ($master_set as $scope => $javascript) {
if ($scope != 'header' && $scope != 'footer' && empty($javascript)) {
continue;
}
drupal_alter('advagg_js_pre', $javascript, $preprocess_js, $public_downloads, $scope);
$master_set[$scope] = $javascript;
}
drupal_alter('advagg_js_header_footer', $master_set, $preprocess_js, $public_downloads);
foreach ($master_set as $scope => $javascript) {
if (empty($javascript)) {
continue;
}
$setting_no_preprocess = array();
$inline_no_preprocess = array();
$external_no_preprocess = array();
$output_no_preprocess = array(
'core' => array(),
'module' => array(),
'theme' => array(),
);
$output_preprocess = array();
$preprocess_list = array();
$js_settings_array = array();
$inline_included = array();
$files_included = array();
$files_aggregates_included = array();
foreach ($javascript as $type => $data) {
if (empty($data)) {
continue;
}
if ($type != 'setting') {
foreach ($data as &$info) {
$info['prefix'] = isset($info['prefix']) ? $info['prefix'] : '';
$info['suffix'] = isset($info['suffix']) ? $info['suffix'] : '';
}
unset($info);
}
switch ($type) {
case 'setting':
$data = call_user_func_array('array_merge_recursive', $data);
$js_settings_array[] = $data;
$js_settings = $advagg_json_encode_function($data);
$js_settings = preg_replace(array(
'/"DRUPAL_JS_RAW\\:/',
'/\\:DRUPAL_JS_RAW"/',
), array(
'',
'',
), $js_settings);
$setting_no_preprocess[] = 'jQuery.extend(Drupal.settings, ' . $js_settings . ");";
break;
case 'inline':
foreach ($data as $info) {
drupal_alter('advagg_js_inline', $info['code']);
$inline_no_preprocess[] = array(
$info['code'],
$info['defer'],
$info['prefix'],
$info['suffix'],
);
$inline_included[] = $info['code'];
}
break;
case 'external':
foreach ($data as $path => $info) {
$external_no_preprocess[] = array(
$path,
$info['defer'],
$info['prefix'],
$info['suffix'],
);
$files_included[$path] = TRUE;
}
break;
default:
foreach ($data as $path => $info) {
if (!$info['preprocess'] || !$public_downloads || !$preprocess_js) {
$output_no_preprocess[$type][] = array(
advagg_build_uri($path) . ($info['cache'] ? $query_string : '?' . time()),
$info['defer'],
$info['prefix'],
$info['suffix'],
);
$files_included[$path] = $info['preprocess'];
}
else {
$preprocess_list[$path] = $info;
}
}
break;
}
}
if ($public_downloads && $preprocess_js && count($preprocess_list) > 0) {
$files_aggregates_included = $files_included;
$files = array();
foreach ($preprocess_list as $path => $info) {
if ($info['preprocess']) {
$files[] = $path;
$files_included[$path] = TRUE;
}
}
if (!empty($files)) {
$preprocess_files = advagg_css_js_file_builder('js', $files, $query_string);
if (!empty($preprocess_files)) {
$good = TRUE;
foreach ($preprocess_files as $preprocess_file => $extra) {
if (empty($preprocess_file)) {
continue;
}
if ($extra !== FALSE && is_array($extra)) {
$prefix = $extra['prefix'];
$suffix = $extra['suffix'];
$output_preprocess[] = array(
advagg_build_uri($preprocess_file),
$prefix,
$suffix,
);
$files_aggregates_included[$preprocess_file] = $extra;
}
else {
$good = FALSE;
break;
}
}
}
if (empty($good)) {
watchdog('advagg', 'JS aggregation failed. %filename could not be saved correctly.', array(
'%filename' => $preprocess_file,
), WATCHDOG_ERROR);
$data = advagg_process_js($master_set, TRUE);
return $data;
}
}
}
$function = variable_get('advagg_js_render_function', ADVAGG_JS_RENDER_FUNCTION);
$output[$scope] = $function($external_no_preprocess, $output_preprocess, $output_no_preprocess, $setting_no_preprocess, $inline_no_preprocess, $scope, $js_settings_array, $inline_included, $files_included, $files_aggregates_included);
}
return $output;
}
function advagg_js_builder($external_no_preprocess, $output_preprocess, $output_no_preprocess, $setting_no_preprocess, $inline_no_preprocess, $js_settings_array, $inline_included, $files_included, $files_aggregates_included) {
$output = '';
$embed_prefix = "\n<!--//--><![CDATA[//><!--\n";
$embed_suffix = "\n//--><!]]>\n";
if (!empty($external_no_preprocess)) {
foreach ($external_no_preprocess as $values) {
list($src, $defer, $prefix, $suffix) = $values;
$output .= $prefix . '<script type="text/javascript"' . ($defer ? ' defer="defer"' : '') . ' src="' . $src . '"></script>' . $suffix . "\n";
}
}
if (!empty($output_preprocess)) {
foreach ($output_preprocess as $values) {
list($src, $prefix, $suffix) = $values;
$output .= $prefix . '<script type="text/javascript" src="' . $src . '"></script>' . $suffix . "\n";
}
}
foreach ($output_no_preprocess as $type => $list) {
if (!empty($list)) {
foreach ($list as $values) {
list($src, $defer, $prefix, $suffix) = $values;
$output .= $prefix . '<script type="text/javascript"' . ($defer ? ' defer="defer"' : '') . ' src="' . $src . '"></script>' . $suffix . "\n";
}
}
}
if (!empty($setting_no_preprocess)) {
foreach ($setting_no_preprocess as $code) {
$output .= '<script type="text/javascript">' . $embed_prefix . $code . $embed_suffix . "</script>\n";
}
}
if (!empty($inline_no_preprocess)) {
foreach ($inline_no_preprocess as $values) {
list($code, $defer, $prefix, $suffix) = $values;
$output .= $prefix . '<script type="text/javascript"' . ($defer ? ' defer="defer"' : '') . '>' . $embed_prefix . $code . $embed_suffix . '</script>' . $suffix . "\n";
}
}
return $output;
}
function advagg_return_true() {
return TRUE;
}
function advagg_disable_page_cache() {
global $conf;
$conf['advagg_use_full_cache'] = FALSE;
if (variable_get('advagg_page_cache_mode', ADVAGG_PAGE_CACHE_MODE)) {
$conf['cache'] = CACHE_DISABLED;
module_invoke_all('advagg_disable_page_cache');
}
}
function advagg_css_js_file_builder($type, $files, $query_string = '', $counter = FALSE, $force = FALSE, $md5 = '') {
global $_advagg, $base_path;
$data = '';
$schema = advagg_get_server_schema();
$cached_data_key = 'advagg_file_builder_' . md5($schema . implode('', array_filter(array_unique($files))));
if (!$force) {
$cached_data = advagg_cached_bundle_get($cached_data_key, 'file_builder_cache_object');
if (!empty($cached_data)) {
foreach ($cached_data as $filepath => $values) {
advagg_bundle_built($filepath);
}
return $cached_data;
}
}
list($css_path, $js_path) = advagg_get_root_files_dir();
if ($type == 'js') {
$file_type_path = $js_path;
}
if ($type == 'css') {
$file_type_path = $css_path;
}
$filenames = advagg_get_filename($files, $type, $counter, $md5);
if (empty($filenames)) {
return FALSE;
}
if (variable_get('advagg_debug', ADVAGG_DEBUG)) {
$_advagg['debug']['file_builder_get_filenames'][] = array(
'key' => $cached_data_key,
'filenames' => $filenames,
);
}
$output = array();
$locks = array();
$cacheable = TRUE;
$files_used = array();
foreach ($filenames as $info) {
$filename = $info['filename'];
$files = $info['files'];
$bundle_md5 = $info['bundle_md5'];
$prefix = '';
$suffix = '';
$filepath = $file_type_path . '/' . $filename;
$values = array(
$filename,
$bundle_md5,
$prefix,
$suffix,
);
drupal_alter('advagg_' . $type . '_extra', $values);
list($filename, $bundle_md5, $prefix, $suffix) = $values;
$built = advagg_bundle_built($filepath);
if (!$built || $force) {
if (variable_get('advagg_async_generation', ADVAGG_ASYNC_GENERATION) && !$force && empty($_GET['generator'])) {
$redirect_counter = isset($_GET['redirect_counter']) ? intval($_GET['redirect_counter']) : 0;
$url = _advagg_build_url($filepath . '?generator=1&redirect_counter=' . $redirect_counter);
$headers = array(
'Host' => $_SERVER['HTTP_HOST'],
'Connection' => 'close',
);
if (function_exists('stream_socket_client') && function_exists('stream_select')) {
advagg_async_connect_http_request($url, array(
'headers' => $headers,
));
}
else {
$socket_timeout = ini_set('default_socket_timeout', variable_get('advagg_socket_timeout', ADVAGG_SOCKET_TIMEOUT));
drupal_http_request($url, $headers, 'GET');
ini_set('default_socket_timeout', $socket_timeout);
}
if (variable_get('advagg_aggregate_mode', ADVAGG_AGGREGATE_MODE) < 2 || advagg_bundle_built($filepath)) {
$output[$filepath] = array(
'prefix' => $prefix,
'suffix' => $suffix,
'files' => array_map('advagg_return_true', array_flip($files)),
);
}
else {
foreach ($files as $file) {
$output[$file . $query_string] = array(
'prefix' => '',
'suffix' => '',
'files' => array(
$file . $query_string => TRUE,
),
);
}
$cacheable = FALSE;
advagg_disable_page_cache();
}
continue;
}
$lock_name = 'advagg_' . $filename;
if (!lock_acquire($lock_name) && !$force) {
if (variable_get('advagg_aggregate_mode', ADVAGG_AGGREGATE_MODE) == 0) {
$locks[$lock_name] = $filepath;
$output[$filepath] = array(
'prefix' => $prefix,
'suffix' => $suffix,
'files' => array_map('advagg_return_true', array_flip($files)),
);
}
else {
foreach ($files as $file) {
$output[$file . $query_string] = array(
'prefix' => '',
'suffix' => '',
'files' => array(
$file . $query_string => TRUE,
),
);
}
$cacheable = FALSE;
advagg_disable_page_cache();
}
continue;
}
if ($type == 'css') {
$data = advagg_build_css_bundle($files);
}
elseif ($type == 'js') {
$data = advagg_build_js_bundle($files);
}
drupal_alter('advagg_' . $type, $data, $files, $bundle_md5);
$files_used = array_merge($files_used, $files);
if (empty($data) && !$force) {
lock_release($lock_name);
continue;
}
file_check_directory($file_type_path, FILE_CREATE_DIRECTORY);
$function = variable_get('advagg_file_save_function', ADVAGG_FILE_SAVE_FUNCTION);
$good = $function($data, $filepath, $force, $type);
lock_release($lock_name);
if (!$good) {
$output[$filepath] = FALSE;
$cacheable = FALSE;
continue;
}
}
else {
$files_used = array_merge($files_used, $files);
}
$output[$filepath] = array(
'prefix' => $prefix,
'suffix' => $suffix,
'files' => array_map('advagg_return_true', array_flip($files)),
);
}
if (!empty($locks)) {
foreach ($locks as $lock_name => $filepath) {
lock_wait($lock_name);
if (!advagg_bundle_built($filepath)) {
$output[$filepath] = FALSE;
}
}
}
if (empty($output)) {
$output[] = FALSE;
return $output;
}
if (!$force && $cacheable) {
$new_cached_data_key = 'advagg_file_builder_' . md5($schema . implode('', array_filter(array_unique($files_used))));
if ($new_cached_data_key == $cached_data_key) {
cache_set($cached_data_key, $output, 'cache_advagg_bundle_reuse', CACHE_TEMPORARY);
}
}
return $output;
}
function advagg_build_css_bundle($files) {
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;
}
$data = '';
foreach ($files as $file) {
$contents = advagg_drupal_load_stylesheet($file, $optimize);
$css_base_url = advagg_file_create_url($file);
$css_base_url = substr($css_base_url, 0, strrpos($css_base_url, '/'));
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 . '/');
$data .= preg_replace_callback('/url\\(\\s*[\'"]?(?![a-z]+:|\\/+)([^\'")]+)[\'"]?\\s*\\)/i', '_drupal_build_css_path', $contents);
}
$regexp = '/@import[^;]+;/i';
preg_match_all($regexp, $data, $matches);
$data = preg_replace($regexp, '', $data);
$data = implode('', $matches[0]) . $data;
return $data;
}
function advagg_build_js_bundle($files) {
if (empty($files)) {
return '';
}
$data = '';
foreach ($files as $file) {
if (advagg_file_exists($file)) {
$data .= @file_get_contents($file) . ";/**/\n";
}
}
return $data;
}
function advagg_file_exists($filename) {
static $files = array();
if (empty($files)) {
$data = cache_get('advagg_file_checksum', 'cache');
if (empty($data->data)) {
$result = db_query("SELECT filename, checksum FROM {advagg_files}");
while ($row = db_fetch_array($result)) {
$files[$row['filename']] = $row['checksum'];
}
cache_set('advagg_file_checksum', $files, 'cache', CACHE_TEMPORARY);
}
else {
$files = $data->data;
}
}
if (!empty($files[$filename]) && $files[$filename] != -1) {
return TRUE;
}
else {
advagg_clearstatcache(TRUE, $filename);
return file_exists($filename);
}
}
function advagg_missing_fast404($msg = '') {
global $base_path;
if (!headers_sent()) {
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
header('X-AdvAgg: Failed Validation. ' . $msg);
}
print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n";
print '<html>';
print '<head><title>404 Not Found</title></head>';
print '<body><h1>Not Found</h1>';
print '<p>The requested URL was not found on this server.</p>';
print '<p><a href="' . $base_path . '">Home</a></p>';
print '<!-- advagg_missing_fast404 -->';
print '</body></html>';
exit;
}
function advagg_htaccess_check_generate($dest, $force = FALSE) {
global $base_path;
if (!$force && !variable_get('advagg_dir_htaccess', ADVAGG_DIR_HTACCESS)) {
return TRUE;
}
$dir = dirname($dest);
$htaccess_file = $dir . '/.htaccess';
advagg_clearstatcache(TRUE, $htaccess_file);
if (!$force && file_exists($htaccess_file)) {
return TRUE;
}
list($css_path, $js_path) = advagg_get_root_files_dir();
$type = '';
if ($dir == $js_path) {
$ext = 'js';
$path = $js_path;
$type = 'text/javascript';
}
elseif ($dir == $css_path) {
$ext = 'css';
$path = $css_path;
$type = 'text/css';
}
else {
return FALSE;
}
$data = "\n";
if (variable_get('advagg_gzip_compression', ADVAGG_GZIP_COMPRESSION)) {
$data .= "<IfModule mod_rewrite.c>\n";
$data .= " RewriteEngine on\n";
$data .= " RewriteBase {$base_path}{$path}\n";
$data .= "\n";
$data .= " # Send 404's back to index.php\n";
$data .= " RewriteCond %{REQUEST_FILENAME} !-s\n";
$data .= " RewriteRule ^(.*)\$ {$base_path}index.php?q={$path}/\$1 [L]\n";
$data .= "\n";
$data .= " # Rules to correctly serve gzip compressed {$ext} files.\n";
$data .= " # Requires both mod_rewrite and mod_headers to be enabled.\n";
$data .= " <IfModule mod_headers.c>\n";
$data .= " # Serve gzip compressed {$ext} files if they exist and client accepts gzip.\n";
$data .= " RewriteCond %{HTTP:Accept-encoding} gzip\n";
$data .= " RewriteCond %{REQUEST_FILENAME}\\.gz -s\n";
$data .= " RewriteRule ^(.*)\\.{$ext}\$ \$1\\.{$ext}\\.gz [QSA]\n";
$data .= "\n";
$data .= " # Serve correct content types, and prevent mod_deflate double gzip.\n";
$data .= " RewriteRule \\.{$ext}\\.gz\$ - [T={$type},E=no-gzip:1]\n";
$data .= "\n";
$data .= " <FilesMatch \"\\.{$ext}\\.gz\$\">\n";
$data .= " # Serve correct encoding type.\n";
$data .= " Header set Content-Encoding gzip\n";
$data .= " # Force proxies to cache gzipped & non-gzipped {$ext} files separately.\n";
$data .= " Header append Vary Accept-Encoding\n";
$data .= " </FilesMatch>\n";
$data .= " </IfModule>\n";
$data .= "</IfModule>\n";
$data .= "\n";
}
$data .= "<FilesMatch \"^{$ext}_[0-9a-f]{32}_.+\\.{$ext}(\\.gz)?\">\n";
$data .= " # No mod_headers\n";
$data .= " <IfModule !mod_headers.c>\n";
$data .= " # No mod_expires\n";
$data .= " <IfModule !mod_expires.c>\n";
$data .= " # Use ETags.\n";
$data .= " FileETag MTime Size\n";
$data .= " </IfModule>\n";
$data .= "\n";
$data .= " # Use Expires Directive.\n";
$data .= " <IfModule mod_expires.c>\n";
$data .= " # Do not use ETags.\n";
$data .= " FileETag None\n";
$data .= " # Enable expirations.\n";
$data .= " ExpiresActive On\n";
$data .= " # Cache all aggregated {$ext} files for 480 weeks after access (A).\n";
$data .= " ExpiresDefault A290304000\n";
$data .= " </IfModule>\n";
$data .= " </IfModule>\n";
$data .= "\n";
$data .= " <IfModule mod_headers.c>\n";
$data .= " # Set a far future Cache-Control header to 480 weeks.\n";
$data .= " Header set Cache-Control \"max-age=290304000, no-transform, public\"\n";
$data .= " # Set a far future Expires header.\n";
$data .= " Header set Expires \"Tue, 20 Jan 2037 04:20:42 GMT\"\n";
$data .= " # Pretend the file was last modified a long time ago in the past.\n";
$data .= " Header set Last-Modified \"Wed, 20 Jan 1988 04:20:42 GMT\"\n";
$data .= " # Do not use etags for cache validation.\n";
$data .= " Header unset ETag\n";
$data .= " </IfModule>\n";
$data .= "</FilesMatch>\n";
if (!advagg_file_save_data($data, $htaccess_file, FILE_EXISTS_REPLACE)) {
return FALSE;
}
return TRUE;
}
function advagg_add_css_inline($data = NULL, $media = 'all', $prefix = NULL, $suffix = NULL) {
static $css = array();
if (isset($data)) {
if (!isset($css[$media]['inline'][$prefix][$suffix])) {
$css[$media]['inline'][$prefix][$suffix] = $data;
}
else {
$css[$media]['inline'][$prefix][$suffix] .= "\n" . $data;
}
return;
}
else {
return $css;
}
}
function advagg_drupal_to_js($var) {
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', '>=');
}
if ($php530) {
$options = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
if ($php550) {
$options |= JSON_PARTIAL_OUTPUT_ON_ERROR;
}
return @json_encode($var, $options);
}
if (function_exists('json_encode')) {
return str_replace(array(
"<",
">",
"&",
), array(
'\\u003c',
'\\u003e',
'\\u0026',
), json_encode($var));
}
switch (gettype($var)) {
case 'boolean':
return $var ? 'true' : 'false';
case 'integer':
case 'double':
return $var;
case 'resource':
case 'string':
$replace_pairs = array(
'\\' => '\\u005C',
'"' => '\\u0022',
"\0" => '\\u0000',
"\1" => '\\u0001',
"\2" => '\\u0002',
"\3" => '\\u0003',
"\4" => '\\u0004',
"\5" => '\\u0005',
"\6" => '\\u0006',
"\7" => '\\u0007',
"\10" => '\\u0008',
"\t" => '\\u0009',
"\n" => '\\u000A',
"\v" => '\\u000B',
"\f" => '\\u000C',
"\r" => '\\u000D',
"\16" => '\\u000E',
"\17" => '\\u000F',
"\20" => '\\u0010',
"\21" => '\\u0011',
"\22" => '\\u0012',
"\23" => '\\u0013',
"\24" => '\\u0014',
"\25" => '\\u0015',
"\26" => '\\u0016',
"\27" => '\\u0017',
"\30" => '\\u0018',
"\31" => '\\u0019',
"\32" => '\\u001A',
"\33" => '\\u001B',
"\34" => '\\u001C',
"\35" => '\\u001D',
"\36" => '\\u001E',
"\37" => '\\u001F',
"'" => '\\u0027',
'<' => '\\u003C',
'>' => '\\u003E',
'&' => '\\u0026',
'/' => '\\u002F',
"
" => '\\u2028',
"
" => '\\u2029',
);
return '"' . strtr($var, $replace_pairs) . '"';
case 'array':
if (empty($var) || array_keys($var) === range(0, sizeof($var) - 1)) {
$output = array();
foreach ($var as $v) {
$output[] = advagg_drupal_to_js($v);
}
return '[ ' . implode(', ', $output) . ' ]';
}
case 'object':
$output = array();
foreach ($var as $k => $v) {
$output[] = advagg_drupal_to_js(strval($k)) . ': ' . advagg_drupal_to_js($v);
}
return '{ ' . implode(', ', $output) . ' }';
default:
return 'null';
}
}
function advagg_drupal_load_stylesheet_content($contents, $optimize = FALSE) {
$contents = preg_replace('/^@charset\\s+[\'"](\\S*)\\b[\'"];/i', '', $contents);
if ($optimize) {
$comment = '/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/';
$double_quot = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
$single_quot = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'";
$contents = preg_replace("<({$double_quot}|{$single_quot})|{$comment}>Ss", "\$1", $contents);
$contents = preg_replace('<
# Strip leading and trailing whitespace.
\\s*([@{};,])\\s*
# Strip only leading whitespace from:
# - Closing parenthesis: Retain "@media (bar) and foo".
| \\s+([\\)])
# Strip only trailing whitespace from:
# - Opening parenthesis: Retain "@media (bar) and foo".
# - Colon: Retain :pseudo-selectors.
| ([\\(:])\\s+
>xS', '$1$2$3', $contents);
$contents = trim($contents);
$contents .= "\n";
}
$contents = preg_replace_callback('/@import\\s*(?:url\\(\\s*)?[\'"]?(?![a-z]+:)([^\'"\\()]+)[\'"]?\\s*\\)?\\s*;/', '_advagg_drupal_load_stylesheet', $contents);
return $contents;
}
function _advagg_drupal_load_stylesheet($matches) {
$filename = $matches[1];
$file = advagg_build_css_bundle(array(
$filename,
));
$directory = dirname($filename);
$directory = $directory == '.' ? '' : $directory . '/';
return preg_replace('/url\\(\\s*([\'"]?)(?![a-z]+:|\\/+)/i', 'url(\\1' . $directory, $file);
}
function advagg_drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE) {
static $_optimize, $basepath;
if ($reset_basepath) {
$basepath = '';
}
if (isset($optimize)) {
$_optimize = $optimize;
}
if ($basepath && !file_uri_scheme($file)) {
$file = $basepath . '/' . $file;
}
$basepath = dirname($file);
if ($contents = @file_get_contents($file)) {
return advagg_drupal_load_stylesheet_content($contents, $_optimize);
}
return '';
}
function advagg_async_connect_http_request($url, array $options = array()) {
$result = new stdClass();
$uri = @parse_url($url);
if (empty($uri)) {
$result->error = 'unable to parse URL';
$result->code = -1001;
return $result;
}
if (!isset($uri['scheme'])) {
$result->error = 'missing schema';
$result->code = -1002;
return $result;
}
$options += array(
'headers' => array(),
'method' => 'GET',
'data' => NULL,
'max_redirects' => 3,
'timeout' => 30.0,
'context' => NULL,
);
$options['timeout'] = (double) $options['timeout'];
switch ($uri['scheme']) {
case 'http':
case 'feed':
$port = isset($uri['port']) ? $uri['port'] : 80;
$socket = 'tcp://' . $uri['host'] . ':' . $port;
if (empty($options['headers']['Host'])) {
$options['headers']['Host'] = $uri['host'];
}
if ($port != 80) {
$options['headers']['Host'] .= ':' . $port;
}
break;
case 'https':
$port = isset($uri['port']) ? $uri['port'] : 443;
$socket = 'ssl://' . $uri['host'] . ':' . $port;
if (empty($options['headers']['Host'])) {
$options['headers']['Host'] = $uri['host'];
}
if ($port != 443) {
$options['headers']['Host'] .= ':' . $port;
}
break;
default:
$result->error = 'invalid schema ' . $uri['scheme'];
$result->code = -1003;
return $result;
}
$flags = STREAM_CLIENT_CONNECT;
if (variable_get('advagg_async_socket_connect', ADVAGG_ASYNC_SOCKET_CONNECT)) {
$flags = STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT;
}
if (empty($options['context'])) {
$fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags);
}
else {
$fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags, $options['context']);
}
if (!$fp) {
$result->code = -$errno;
$result->error = trim($errstr) ? trim($errstr) : t('Error opening socket @socket', array(
'@socket' => $socket,
));
return $result;
}
stream_set_blocking($fp, 0);
$path = isset($uri['path']) ? $uri['path'] : '/';
if (isset($uri['query'])) {
$path .= '?' . $uri['query'];
}
$options['headers'] += array(
'User-Agent' => 'Drupal (+http://drupal.org/)',
);
$content_length = strlen($options['data']);
if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
$options['headers']['Content-Length'] = $content_length;
}
if (isset($uri['user'])) {
$options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
}
$test_info =& $GLOBALS['drupal_test_info'];
if (!empty($test_info['test_run_id'])) {
$options['headers']['User-Agent'] = drupal_generate_test_ua($test_info['test_run_id']);
}
$request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";
foreach ($options['headers'] as $name => $value) {
$request .= $name . ': ' . trim($value) . "\r\n";
}
$request .= "\r\n" . $options['data'];
$result->request = $request;
return advagg_async_send_http_request($fp, $request, $options['timeout']);
}
function advagg_async_send_http_request($fp = NULL, $request = '', $timeout = 30) {
static $requests = array();
static $registered = FALSE;
$args = array(
$fp,
$request,
$timeout,
);
if (!empty($fp)) {
$requests[] = $args;
if (!$registered) {
register_shutdown_function(__FUNCTION__);
$registered = TRUE;
}
return TRUE;
}
if (empty($requests)) {
return FALSE;
}
$streams = array();
foreach ($requests as $id => $values) {
list($fp, $request, $timeout) = $values;
$streams[$id] = $fp;
}
$retry_count = 2;
while (!empty($streams)) {
$read = $write = $streams;
$except = array();
$n = @stream_select($read, $write, $except, $timeout);
if (!empty($n)) {
foreach ($write as $id => $w) {
fwrite($w, $requests[$id][1]);
fclose($w);
unset($streams[$id]);
}
}
elseif (!empty($retry_count)) {
$retry_count--;
}
else {
break;
}
}
$requests = array();
if ($n !== FALSE && empty($streams)) {
return TRUE;
}
else {
return FALSE;
}
}
function advagg_advagg_js_header_footer_alter(&$master_set, $preprocess_js, $public_downloads) {
if (!defined('CTOOLS_AJAX_INCLUDED')) {
return;
}
$js_files = array();
foreach ($master_set as $scope => $scripts) {
if (empty($scripts)) {
continue;
}
advagg_ctools_process_js_files($js_files, $scope, $scripts);
}
$loaded = array(
'CToolsAJAX' => array(
'scripts' => $js_files,
),
);
drupal_add_js($loaded, 'setting', 'footer');
if (!isset($master_set['footer']['setting']) || !is_array($master_set['footer']['setting'])) {
$master_set['footer']['setting'] = array();
}
$master_set['footer']['setting'][] = $loaded;
}
function advagg_advagg_css_pre_alter(&$css, $preprocess_css, $public_downloads) {
if (!defined('CTOOLS_AJAX_INCLUDED')) {
return;
}
$css_files = array();
ctools_process_css_files($css_files, $css);
drupal_add_js(array(
'CToolsAJAX' => array(
'css' => $css_files,
),
), 'setting', 'footer');
}
function advagg_ctools_process_js_files(&$js_files, $scope, $scripts = NULL) {
$scripts = drupal_add_js(NULL, NULL, $scope);
if (empty($scripts)) {
$scripts = drupal_add_js(NULL, NULL, $scope);
}
static $replacements = NULL;
if (!isset($replacements)) {
$replacements = module_invoke_all('js_replacements');
}
$settings = array();
foreach ($scripts as $type => $data) {
switch ($type) {
case 'setting':
$settings = $data;
break;
case 'inline':
case 'theme':
break;
default:
foreach ($data as $path => $info) {
$final_path = isset($replacements[$type][$path]) ? $replacements[$type][$path] : $path;
$js_files[base_path() . $final_path] = TRUE;
}
}
}
return $settings;
}
function advagg_clearstatcache($clear_realpath_cache = FALSE, $filename = NULL) {
static $php530;
if (!isset($php530)) {
$php530 = version_compare(PHP_VERSION, '5.3.0', '>=');
}
if ($php530) {
return clearstatcache($clear_realpath_cache, $filename);
}
else {
return clearstatcache();
}
}
function advagg_db_multi_select_in($table, $field, $placeholder, $data, $returns = array(), $groupby = '') {
if (empty($returns)) {
$returns[] = '*';
}
$rows = count($data);
$in = $placeholder;
for ($i = 1; $i < $rows; $i++) {
$in .= ', ' . $placeholder;
}
$query = "SELECT " . implode(', ', $returns) . " FROM {" . $table . "} WHERE {$field} IN ({$in}) {$groupby}";
return db_query($query, $data);
}
function advagg_get_js_css_get_array($js_files_excluded = array(), $css_files_excluded = array()) {
global $conf, $_advagg;
$variables = array(
'css' => array(),
'js' => array(),
);
$css_function = variable_get('advagg_css_render_function', ADVAGG_CSS_RENDER_FUNCTION);
$js_function = variable_get('advagg_js_render_function', ADVAGG_JS_RENDER_FUNCTION);
$conf['advagg_css_render_function'] = 'advagg_css_array';
$conf['advagg_js_render_function'] = 'advagg_js_array';
$css_array = array();
$variables['css'] = drupal_add_css();
if (module_exists('less')) {
less_preprocess_page($variables, NULL);
}
$css_func_inline = advagg_add_css_inline();
if (!empty($css_func_inline)) {
$variables['css'] = advagg_merge_inline_css($variables['css'], $css_func_inline);
}
foreach ($variables['css'] as $media => $types) {
foreach ($types as $type => $values) {
foreach ($values as $filename => $preprocess) {
if (in_array($filename, $css_files_excluded)) {
unset($variables['css'][$media][$type][$filename]);
}
}
}
}
$css_array = advagg_process_css($variables['css']);
$js_array = array();
$variables['js']['header'] = drupal_add_js(NULL, NULL, 'header');
if (variable_get('advagg_closure', ADVAGG_CLOSURE) && !empty($_advagg['closure'])) {
$variables['js']['footer'] = drupal_add_js(NULL, NULL, 'footer');
}
advagg_jquery_updater($variables['js']['header']);
foreach ($variables['js'] as $scope => $values) {
foreach ($values as $type => $data) {
foreach ($data as $filename => $info) {
if (in_array($filename, $js_files_excluded)) {
unset($variables['js'][$scope][$type][$filename]);
}
}
}
}
$js_array = advagg_process_js($variables['js']);
$conf['advagg_css_render_function'] = $css_function;
$conf['advagg_js_render_function'] = $js_function;
return array(
'js' => $js_array,
'css' => $css_array,
);
}
function advagg_css_array($external_no_preprocess, $module_no_preprocess, $output_no_preprocess, $output_preprocess, $theme_no_preprocess, $inline_no_preprocess, $inline_included, $files_included, $files_aggregates_included) {
return array(
'inline' => $inline_included,
'files' => $files_included,
'files_aggregates' => $files_aggregates_included,
);
}
function advagg_js_array($external_no_preprocess, $output_preprocess, $output_no_preprocess, $setting_no_preprocess, $inline_no_preprocess, $scope, $js_settings_array, $inline_included, $files_included, $files_aggregates_included) {
return array(
'settings' => $js_settings_array,
'inline' => $inline_included,
'files' => $files_included,
'files_aggregates' => $files_aggregates_included,
);
}
function advagg_file_download($file, $type = '') {
if (strpos($file, '/advagg_') === FALSE || empty($type)) {
return;
}
$return = array();
$return[] = 'Content-Length: ' . filesize($file);
$return[] = "Cache-Control: max-age=290304000, no-transform, public";
$return[] = 'Expires: Tue, 20 Jan 2037 04:20:42 GMT';
$return[] = 'Last-Modified: Wed, 20 Jan 1988 04:20:42 GMT';
if ($type == 'css') {
$return[] = 'Content-Type: text/css';
}
if ($type == 'js') {
$return[] = 'Content-Type: text/javascript';
}
return $return;
}
function _advagg_build_url($filepath = '') {
global $base_path;
$auth = '';
if (isset($_SERVER['AUTH_TYPE']) && $_SERVER['AUTH_TYPE'] == 'Basic') {
$auth = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@';
}
$ip = variable_get('advagg_server_addr', FALSE);
if ($ip == -1) {
$ip = $_SERVER['HTTP_HOST'];
}
elseif (empty($ip)) {
$ip = empty($_SERVER['SERVER_ADDR']) ? '127.0.0.1' : $_SERVER['SERVER_ADDR'];
}
$port = '';
return 'http://' . $auth . $ip . $port . $base_path . $filepath;
}