You are here

function advagg_generate_groups in Advanced CSS/JS Aggregation 7.2

Group the CSS/JS into the biggest buckets possible.

Parameters

array $files_to_aggregate: An array of CSS/JS groups.

string $type: String; css or js.

Return value

array New version of groups.

1 call to advagg_generate_groups()
advagg_build_aggregate_plans in ./advagg.inc
Replacement for drupal_build_css_cache() and drupal_build_js_cache().

File

./advagg.inc, line 814
Advanced CSS/JS aggregation module.

Code

function advagg_generate_groups(array $files_to_aggregate, $type) {
  $groups = array();
  $count = 0;
  $location = 0;
  $media = '';
  $defer = '';
  $async = '';
  $cache = '';
  $scope = '';
  $use_strict = 0;
  $browsers = array();
  $selector_count = 0;

  // Get CSS limit value.
  $limit_value = variable_get('advagg_ie_css_selector_limiter_value', ADVAGG_IE_CSS_SELECTOR_LIMITER_VALUE);
  if (variable_get('advagg_ie_css_selector_limiter', ADVAGG_IE_CSS_SELECTOR_LIMITER) || variable_get('advagg_resource_hints_dns_prefetch', ADVAGG_RESOURCE_HINTS_DNS_PREFETCH) || variable_get('advagg_resource_hints_preconnect', ADVAGG_RESOURCE_HINTS_PRECONNECT) || variable_get('advagg_resource_hints_preload', ADVAGG_RESOURCE_HINTS_PRELOAD)) {
    $filenames = array();
    foreach ($files_to_aggregate as $data) {
      foreach ($data as $values) {
        foreach ($values['items'] as $file_info) {
          if (!empty($file_info['data']) && is_string($file_info['data'])) {
            $filenames[] = $file_info['data'];
          }
          else {
            watchdog('advagg', 'Bad data key. File info: <code>@finfo</code> Group info: <code>@ginfo</code>', array(
              '@finfo' => var_export($file_info, TRUE),
              '@ginfo' => var_export($values, TRUE),
            ));
          }
        }
      }
    }

    // Get filesystem data.
    $files_info = advagg_get_info_on_files($filenames, TRUE);
  }
  $strict_files = array();
  if ($type == 'js') {

    // Make drupal_get_installed_schema_version() available.
    include_once DRUPAL_ROOT . '/includes/install.inc';
    if (drupal_get_installed_schema_version('advagg') >= 7213) {
      $query = db_select('advagg_files', 'af')
        ->fields('af', array(
        'filename',
        'use_strict',
      ))
        ->condition('use_strict', 1)
        ->execute();
      foreach ($query as $row) {
        $strict_files[$row->filename] = $row->use_strict;
      }
    }
  }
  foreach ($files_to_aggregate as $data) {
    foreach ($data as $values) {

      // Group into the biggest buckets possible.
      $last_ext = '';
      foreach ($values['items'] as $file_info) {
        $parts = array();

        // Check to see if media, browsers, defer, async, cache, or scope has
        // changed from the previous run of this loop.
        $changed = FALSE;
        $ext = isset($file_info['fileext']) ? $file_info['fileext'] : pathinfo($file_info['data'], PATHINFO_EXTENSION);
        $ext = strtolower($ext);
        if ($ext !== 'css' && $ext !== 'js') {
          if (empty($last_ext)) {

            // Get the $ext from the database.
            $row = db_select('advagg_files', 'af')
              ->fields('af')
              ->condition('filename', $file_info['data'])
              ->execute()
              ->fetchAssoc();
            $ext = $row['filetype'];
          }
          else {
            $ext = $last_ext;
          }
        }
        $last_ext = $ext;
        if ($ext === 'css') {
          if (isset($file_info['media'])) {
            if (variable_get('advagg_combine_css_media', ADVAGG_COMBINE_CSS_MEDIA)) {
              $file_info['media_query'] = $file_info['media'];
            }
            elseif ($media != $file_info['media']) {

              // Media changed.
              $changed = TRUE;
              $media = $file_info['media'];
            }
          }
          if (empty($file_info['media']) && !empty($media)) {

            // Media changed to empty.
            $changed = TRUE;
            $media = '';
          }
        }
        if (isset($file_info['browsers'])) {

          // Browsers changed.
          $diff = array_merge(array_diff_assoc($file_info['browsers'], $browsers), array_diff_assoc($browsers, $file_info['browsers']));
          if (!empty($diff)) {
            $changed = TRUE;
            $browsers = $file_info['browsers'];
          }
        }
        if (empty($file_info['browsers']) && !empty($browsers)) {

          // Browsers changed to empty.
          $changed = TRUE;
          $browsers = array();
        }
        if (!empty($strict_files[$file_info['data']]) && $use_strict != $strict_files[$file_info['data']]) {

          // use_strict value changed to 1.
          $changed = TRUE;
          $use_strict = 1;
        }
        if (!empty($use_strict) && empty($strict_files[$file_info['data']])) {

          // use_strict value changed to 0.
          $changed = TRUE;
          $use_strict = 0;
        }
        if (isset($file_info['defer']) && $defer != $file_info['defer']) {

          // Defer value changed.
          $changed = TRUE;
          $defer = $file_info['defer'];
        }
        if (!empty($defer) && empty($file_info['defer'])) {

          // Defer value changed to empty.
          $changed = TRUE;
          $defer = '';
        }
        if (isset($file_info['async']) && $async != $file_info['async']) {

          // Async value changed.
          $changed = TRUE;
          $async = $file_info['async'];
        }
        if (!empty($async) && empty($file_info['async'])) {

          // Async value changed to empty.
          $changed = TRUE;
          $async = '';
        }
        if (isset($file_info['cache']) && $cache != $file_info['cache']) {

          // Cache value changed.
          $changed = TRUE;
          $cache = $file_info['cache'];
        }
        if (!empty($cache) && empty($file_info['cache'])) {

          // Cache value changed to empty.
          $changed = TRUE;
          $cache = '';
        }
        if (isset($file_info['scope']) && $scope != $file_info['scope']) {

          // Scope value changed.
          $changed = TRUE;
          $scope = $file_info['scope'];
        }
        if (!empty($scope) && empty($file_info['scope'])) {

          // Scope value changed to empty.
          $changed = TRUE;
          $scope = '';
        }
        if (variable_get('advagg_ie_css_selector_limiter', ADVAGG_IE_CSS_SELECTOR_LIMITER) && array_key_exists('data', $file_info) && is_string($file_info['data']) && array_key_exists($file_info['data'], $files_info)) {
          $file_info += $files_info[$file_info['data']];

          // Prevent CSS rules exceeding 4095 due to limits with IE9 and below.
          if ($ext === 'css') {
            $selector_count += $file_info['linecount'];
            if ($selector_count > $limit_value) {
              $changed = TRUE;
              $selector_count = $file_info['linecount'];

              // Break large file into multiple smaller files.
              if ($file_info['linecount'] > $limit_value) {
                $parts = advagg_split_css_file($file_info);
              }
            }
          }
        }

        // Merge in dns_prefetch.
        if ((variable_get('advagg_resource_hints_dns_prefetch', ADVAGG_RESOURCE_HINTS_DNS_PREFETCH) || variable_get('advagg_resource_hints_preconnect', ADVAGG_RESOURCE_HINTS_PRECONNECT)) && isset($files_info[$file_info['data']]['dns_prefetch'])) {
          if (!isset($file_info['dns_prefetch'])) {
            $file_info['dns_prefetch'] = array();
          }
          if (!empty($file_info['dns_prefetch']) && is_string($file_info['dns_prefetch'])) {
            $temp = $file_info['dns_prefetch'];
            unset($file_info['dns_prefetch']);
            $file_info['dns_prefetch'] = array(
              $temp,
            );
          }
          $file_info['dns_prefetch'] = array_filter(array_unique(array_merge($file_info['dns_prefetch'], $files_info[$file_info['data']]['dns_prefetch'])));
        }

        // Merge in preload.
        if (variable_get('advagg_resource_hints_preload', ADVAGG_RESOURCE_HINTS_PRELOAD) && isset($files_info[$file_info['data']]['preload'])) {
          if (!isset($file_info['preload'])) {
            $file_info['preload'] = array();
          }
          if (!empty($file_info['preload']) && is_string($file_info['preload'])) {
            $temp = $file_info['preload'];
            unset($file_info['preload']);
            $file_info['preload'] = array(
              $temp,
            );
          }
          $file_info['preload'] = array_filter(array_unique(array_merge($file_info['preload'], $files_info[$file_info['data']]['preload'])));
        }

        // If one of the above options changed, it needs to be in a different
        // aggregate.
        if (!empty($parts)) {
          foreach ($parts as $part) {
            ++$count;
            $groups[$location][$count][] = $part;
          }
        }
        else {
          if ($changed) {
            ++$count;
          }
          $groups[$location][$count][] = $file_info;
        }
      }
    }

    // Grouping if inline is mixed between files.
    ++$location;
  }
  return $groups;
}