You are here

function advagg_js_compress_do_it in Advanced CSS/JS Aggregation 7.2

Compress a JS string.

Parameters

string $contents: Javascript string.

array $info: Info about the js file.

int $compressor: Use a particular compressor.

bool $force_run: TRUE to skip cache and force the compression test.

array $aggregate_settings: The aggregate_settings array.

bool $log_errors: FALSE to disable logging to watchdog on failure.

Return value

bool FALSE if there was an error.

1 call to advagg_js_compress_do_it()
advagg_js_compress_prep in advagg_js_compress/advagg_js_compress.advagg.inc
Compress a JS string.

File

advagg_js_compress/advagg_js_compress.advagg.inc, line 291

Code

function advagg_js_compress_do_it(&$contents, array $info, $compressor, $force_run, array $aggregate_settings, $log_errors) {
  $no_errors = TRUE;

  // Try cache.
  $content_hash = !empty($info['content_hash']) ? ":{$info['content_hash']}" : '';
  $cache_id = "advagg:js_compress:{$compressor}:{$info['filename_hash']}:{$content_hash}";
  $cache = cache_get($cache_id, 'cache_advagg_aggregates');
  $force_run = variable_get('advagg_js_compress_force_run', $force_run);
  if (!$force_run && !empty($cache->data)) {
    $contents = $cache->data;
  }
  else {

    // Strip Byte Order Marks (BOM's), preg_* cannot parse these well.
    $contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents);

    // Jsmin may have errors (incorrectly determining EOLs) with mixed tabs
    // and spaces. An example: jQuery.Cycle 3.0.3 - http://jquery.malsup.com/
    if ($compressor == 3) {
      $contents = str_replace("\t", " ", $contents);
    }

    // Add end string to get true end of file.
    // Generate random variable contents and add to end of js string.
    $random = dechex(mt_rand());
    $end_string = "var advagg_end=\"{$random}\";";
    $contents .= "\n{$end_string}";

    // Use the compressor.
    list(, , , $functions) = advagg_js_compress_configuration();
    if (isset($functions[$compressor])) {
      $run = $functions[$compressor];
      if (function_exists($run)) {
        $no_errors = $run($contents, $log_errors, $aggregate_settings);
      }
    }
    else {
      return FALSE;
    }

    // Get location of random variable.
    $end_string = substr($end_string, 0, -1);
    $pos = strrpos($contents, $end_string);
    if ($pos === FALSE) {
      $end_string = str_replace('"', "'", $end_string);
      $pos = strrpos($contents, $end_string);
    }
    if ($pos !== FALSE) {

      // Cut everything after random variable out of string.
      $contents = substr($contents, 0, $pos);
    }

    // Under some unknown/rare circumstances, JSMin and JSqueeze can add 2-3
    // extraneous/wrong chars at the end of the string. This work-around will
    // remove these chars if necessary. See https://www.drupal.org/node/2627468.
    // Also see https://github.com/sqmk/pecl-jsmin/issues/46.
    if ($compressor == 3 || $compressor == 5) {
      $a = strrpos($contents, ';');
      $b = strrpos($contents, '}');
      $c = strrpos($contents, ')');

      // Simple scripts can just end, check to make sure there's a
      // match before cutting.
      if ($a !== FALSE || $b !== FALSE || $c !== FALSE) {
        $contents = substr($contents, 0, 1 + max($a, $b, $c));
      }
    }

    // Ensure that $contents ends with ; or }.
    if (strpbrk(substr(trim($contents), -1), ';}') === FALSE) {

      // ; or } not found, add in ; to the end of $contents.
      $contents = trim($contents) . ';';
    }
    if (empty($info['#no_cache'])) {

      // Cache minified data for 1 week.
      cache_set($cache_id, $contents, 'cache_advagg_aggregates', REQUEST_TIME + 86400 * 7);
    }
    else {

      // Cache minified inline data for 1 hour.
      cache_set($cache_id, $contents, 'cache_advagg_aggregates', REQUEST_TIME + 3600);
    }
  }
  return $no_errors;
}