diff --git a/advagg.cache.inc b/advagg.cache.inc index 0e3e86e..541d67c 100644 --- a/advagg.cache.inc +++ b/advagg.cache.inc @@ -95,6 +95,9 @@ function advagg_push_new_changes() { advagg_insert_update_files(array($filename => $meta_data), $ext); } + // Let other modules know about the changed files. + module_invoke_all('advagg_changed_files', $files, $types); + // Clear out the full aggregates cache. foreach ($types as $ext => $bool) { cache_clear_all('advagg:' . $ext . ':', 'cache_advagg_aggregates', TRUE); diff --git a/advagg.module b/advagg.module index cc92ffb..63fb14e 100644 --- a/advagg.module +++ b/advagg.module @@ -59,6 +59,7 @@ function advagg_hook_info() { 'advagg_get_js_aggregate_contents_alter', 'advagg_save_aggregate_alter', 'advagg_build_aggregate_plans_alter', + 'advagg_changed_files', ); $hooks = array(); foreach ($advagg_hooks as $hook) { @@ -784,6 +785,7 @@ function advagg_hooks_implemented($all = TRUE) { if ($all) { $hooks += array( 'advagg_build_aggregate_plans_alter' => array(), + 'advagg_changed_files' => array(), 'js_alter' => array(), 'css_alter' => array(), ); diff --git a/advagg_js_compress/advagg_js_compress.advagg.inc b/advagg_js_compress/advagg_js_compress.advagg.inc index 5eb90f5..ac7fcf7 100644 --- a/advagg_js_compress/advagg_js_compress.advagg.inc +++ b/advagg_js_compress/advagg_js_compress.advagg.inc @@ -63,7 +63,8 @@ function advagg_js_compress_advagg_save_aggregate_alter(&$files_to_save, $aggreg } // Use packer on non gzip JS data. - advagg_js_compress_jspacker($data); + $aggregate_settings['variables']['advagg_js_compressor'] = 2; + advagg_js_compress_prep($data, $uri, $aggregate_settings, FALSE); $files_to_save[$uri] = $data; } @@ -74,35 +75,49 @@ function advagg_js_compress_advagg_save_aggregate_alter(&$files_to_save, $aggreg * Javascript string. * @param $filename * filename. + * @param $add_licensing + * FALSE to remove Source and licensing information comment. + * @param $log_errors + * FALSE to disable logging to watchdog on failure. + * @param $test_ratios + * FALSE to disable compression ratio testing. */ -function advagg_js_compress_prep(&$contents, $filename, $aggregate_settings) { +function advagg_js_compress_prep(&$contents, $filename, $aggregate_settings, $add_licensing = TRUE, $log_errors = TRUE, $test_ratios = TRUE) { // Get the JS string length before the compression operation. $contents_before = $contents; $before = strlen($contents); + // Strip Byte Order Marks (BOM's) from the file, packer cannot parse these. + $contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents); + // Use the compressor. $compressor = $aggregate_settings['variables']['advagg_js_compressor']; if ($compressor == 0) { - advagg_js_compress_jsminplus($contents); + advagg_js_compress_jsminplus($contents, $log_errors); } elseif ($compressor == 1) { $contents = jsmin($contents); } - - // Make sure compression ratios are good. - $after = strlen($contents); - $ratio = 0; - if ($before != 0) { - $ratio = ($before - $after) / $before; - } - // Make sure the returned string is not empty or has a VERY high - // compression ratio. - if (empty($contents) || empty($ratio) || $ratio > $aggregate_settings['variables']['advagg_js_max_compress_ratio']) { - $contents = $contents_before; + elseif ($compressor == 2) { + advagg_js_compress_jspacker($contents); } - else { - $url = url($filename, array('absolute' => TRUE)); - $contents = "/* Source and licensing information for the line(s) below can be found at $url. */\n" . $contents . ";\n/* Source and licensing information for the above line(s) can be found at $url. */\n"; + + if ($test_ratios) { + // Make sure compression ratios are good. + $after = strlen($contents); + $ratio = 0; + if ($before != 0) { + $ratio = ($before - $after) / $before; + } + // Make sure the returned string is not empty or has a VERY high + // compression ratio. + if (empty($contents) || empty($ratio) || $ratio > $aggregate_settings['variables']['advagg_js_max_compress_ratio']) { + $contents = $contents_before; + } + elseif ($add_licensing) { + $url = url($filename, array('absolute' => TRUE)); + $contents = "/* Source and licensing information for the line(s) below can be found at $url. */\n" . $contents . ";\n/* Source and licensing information for the above line(s) can be found at $url. */\n"; + } } } @@ -111,10 +126,10 @@ function advagg_js_compress_prep(&$contents, $filename, $aggregate_settings) { * * @param $contents * Javascript string. - * @return - * array with the size before and after. + * @param $log_errors + * FALSE to disable logging to watchdog on failure. */ -function advagg_js_compress_jsminplus(&$contents) { +function advagg_js_compress_jsminplus(&$contents, $log_errors = TRUE) { $contents_before = $contents; // Only include jsminplus.inc if the JSMinPlus class doesn't exist. @@ -123,8 +138,6 @@ function advagg_js_compress_jsminplus(&$contents) { } ob_start(); try { - // Strip Byte Order Marks (BOM's) from the file, JSMin+ cannot parse these. - $contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents); // JSMin+ the contents of the aggregated file. $contents = JSMinPlus::minify($contents); @@ -136,7 +149,9 @@ function advagg_js_compress_jsminplus(&$contents) { } catch (Exception $e) { // Log the exception thrown by JSMin+ and roll back to uncompressed content. - watchdog('advagg_js_compress', $e->getMessage() . '
' . $contents_before . '
', NULL, WATCHDOG_WARNING); + if ($log_errors) { + watchdog('advagg_js_compress', $e->getMessage() . '
' . $contents_before . '
', NULL, WATCHDOG_WARNING); + } $contents = $contents_before; } ob_end_clean(); @@ -154,18 +169,10 @@ function advagg_js_compress_jspacker(&$contents) { include(drupal_get_path('module', 'advagg_js_compress') . '/jspacker.inc'); } - // Strip Byte Order Marks (BOM's) from the file, packer cannot parse these. - $contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents); - // Add semicolons to the end of lines if missing. $contents = str_replace("}\n", "};\n", $contents); $contents = str_replace("\nfunction", ";\nfunction", $contents); - // Remove char returns, - $contents = str_replace("\n\r", "", $contents); - $contents = str_replace("\r", "", $contents); - $contents = str_replace("\n", "", $contents); - $packer = new JavaScriptPacker($contents, 62, TRUE, FALSE); $contents = $packer->pack(); } diff --git a/advagg_js_compress/advagg_js_compress.module b/advagg_js_compress/advagg_js_compress.module index d74d7ed..24cf497 100644 --- a/advagg_js_compress/advagg_js_compress.module +++ b/advagg_js_compress/advagg_js_compress.module @@ -24,7 +24,7 @@ define('ADVAGG_JS_COMPRESS_RATIO', 0.1); /** * Default value for the compression ratio test. */ -define('ADVAGG_JS_MAX_COMPRESS_RATIO', 0.98); +define('ADVAGG_JS_MAX_COMPRESS_RATIO', 0.90); /** * Default value to see if this will compress aggregated files. @@ -62,3 +62,98 @@ function advagg_js_compress_advagg_current_hooks_hash_array_alter(&$aggregate_se $aggregate_settings['variables']['advagg_js_compress_packer'] = variable_get('advagg_js_compress_packer', ADVAGG_JS_COMPRESS_PACKER); $aggregate_settings['variables']['advagg_js_max_compress_ratio'] = variable_get('advagg_js_max_compress_ratio', ADVAGG_JS_MAX_COMPRESS_RATIO); } + +function advagg_js_compress_setup_test($filename) { + // Get the info on this file. + module_load_include('inc', 'advagg', 'advagg'); + $info = advagg_get_info_on_file($filename); + + // Set to 0 if file doesn't exist. + if (empty($info['content_hash'])) { + $results = array( + 0 => array('code' => 0, 'ratio' => 0, 'name' => 'jsminplus'), + 1 => array('code' => 0, 'ratio' => 0, 'name' => 'jsmin'), + 2 => array('code' => 0, 'ratio' => 0, 'name' => 'packer'), + ); + } + else { + // Set to "-1" so if php bombs out, the file will be marked as bad. + $results = array( + 0 => array('code' => -1, 'ratio' => 0, 'name' => 'jsminplus'), + 1 => array('code' => -1, 'ratio' => 0, 'name' => 'jsmin'), + 2 => array('code' => -1, 'ratio' => 0, 'name' => 'packer'), + ); + // Run this via httprl if possible. + if (!module_exists('httprl') || !httprl_is_background_callback_capable()) { + $results = advagg_js_compress_test_file($filename); + } + else { + // Setup callback options array. + $callback_options = array( + array( + 'function' => 'advagg_js_compress_test_file', + 'return' => &$results, + ), + $filename, + ); + // Queue up the request. + httprl_queue_background_callback($callback_options); + // Execute request. + httprl_send_request(); + } + } + // Place results into array. + $info['advagg_js_compress'] = $results; + + // Save results. + $cache_id = 'advagg:file:' . $info['filename_hash']; + if (variable_get('advagg_use_file_cache', ADVAGG_USE_FILE_CACHE)) { + cache_set($cache_id, $info, 'cache_advagg_info', CACHE_PERMANENT); + } + return $info; +} + +function advagg_js_compress_test_file($filename) { + $contents = file_get_contents($filename); + // Get the JS string length before the compression operation. + $contents_before = $contents; + $before = strlen($contents); + + module_load_include('inc', 'advagg_js_compress', 'advagg_js_compress.advagg'); + + $compressors = array(0 => 'jsminplus', 2 => 'packer'); + if (function_exists('jsmin')) { + $compressors[1] = 'jsmin'; + } + ksort($compressors); + $results = array(); + foreach ($compressors as $key => $name) { + $contents = $contents_before; + $aggregate_settings['variables']['advagg_js_compressor'] = $key; + $aggregate_settings['variables']['advagg_js_max_compress_ratio'] = variable_get('advagg_js_max_compress_ratio', ADVAGG_JS_MAX_COMPRESS_RATIO); + + // Compress it. + advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE, FALSE, FALSE); + $after = strlen($contents); + + $ratio = 0; + if ($before != 0) { + $ratio = ($before - $after) / $before; + } + // Set to "-2" if compression ratio sucks. + if ($ratio < variable_get('advagg_js_compress_ratio', ADVAGG_JS_COMPRESS_RATIO)) { + $results[$key] = array('code' => -2, 'ratio' => $ratio, 'name' => $name); + } + // Set to "-3" if the compression ratio is way too good. + elseif ($ratio > variable_get('advagg_js_max_compress_ratio', ADVAGG_JS_MAX_COMPRESS_RATIO)) { + $results[$key] = array('code' => -3, 'ratio' => $ratio, 'name' => $name); + } + // Set to "1". Everything worked, mark this file as compressible. + else { + $results[$key] = array('code' => 1, 'ratio' => $ratio, 'name' => $name); + } + } + return $results; +} + +