function JsCollectionOptimizerLazy::optimize

Same name and namespace in other branches
  1. 11.x core/lib/Drupal/Core/Asset/JsCollectionOptimizerLazy.php \Drupal\Core\Asset\JsCollectionOptimizerLazy::optimize()

Optimizes a collection of assets.

Parameters

array $assets: An asset collection.

array $libraries: An array of library names.

Return value

array An optimized asset collection.

Overrides AssetCollectionOptimizerInterface::optimize

File

core/lib/Drupal/Core/Asset/JsCollectionOptimizerLazy.php, line 61

Class

JsCollectionOptimizerLazy
Optimizes JavaScript assets.

Namespace

Drupal\Core\Asset

Code

public function optimize(array $js_assets, array $libraries) {
  // File names are generated based on library/asset definitions. This
  // includes a hash of the assets and the group index. Additionally, the full
  // set of libraries, already loaded libraries and theme are sent as query
  // parameters to allow a PHP controller to generate a valid file with
  // sufficient information. Files are not generated by this method since
  // they're assumed to be successfully returned from the URL created whether
  // on disk or not.
  // Group the assets.
  $js_groups = $this->grouper
    ->group($js_assets);
  $js_assets = [];
  foreach ($js_groups as $order => $js_group) {
    // We have to return a single asset, not a group of assets. It is now up
    // to one of the pieces of code in the switch statement below to set the
    // 'data' property to the appropriate value.
    $js_assets[$order] = $js_group;
    switch ($js_group['type']) {
      case 'file':
        // No preprocessing, single JS asset: just use the existing URI.
        if (!$js_group['preprocess']) {
          $uri = $js_group['items'][0]['data'];
          $js_assets[$order]['data'] = $uri;
        }
        else {
          // To reproduce the full context of assets outside of the request,
          // we must know the entire set of libraries used to generate all CSS
          // groups, whether or not files in a group are from a particular
          // library or not.
          $js_assets[$order]['preprocessed'] = TRUE;
        }
        break;

      case 'external':
        // We don't do any aggregation and hence also no caching for external
        // JS assets.
        $uri = $js_group['items'][0]['data'];
        $js_assets[$order]['data'] = $uri;
        break;

      case 'setting':
        $js_assets[$order]['data'] = $js_group['data'];
        break;

    }
  }
  if ($libraries) {
    // All group URLs have the same query arguments apart from the delta and
    // scope, so prepare them in advance.
    $language = $this->languageManager
      ->getCurrentLanguage()
      ->getId();
    $query_args = [
      'language' => $language,
      'theme' => $this->themeManager
        ->getActiveTheme()
        ->getName(),
      'include' => UrlHelper::compressQueryParameter(implode(',', $this->dependencyResolver
        ->getMinimalRepresentativeSubset($libraries))),
    ];
    $ajax_page_state = $this->requestStack
      ->getCurrentRequest()
      ->get('ajax_page_state');
    $already_loaded = isset($ajax_page_state) ? explode(',', $ajax_page_state['libraries']) : [];
    if ($already_loaded) {
      $query_args['exclude'] = UrlHelper::compressQueryParameter(implode(',', $this->dependencyResolver
        ->getMinimalRepresentativeSubset($already_loaded)));
    }
    // Generate a URL for the group, but do not process it inline, this is
    // done by \Drupal\system\controller\JsAssetController.
    foreach ($js_assets as $order => $js_asset) {
      if (!empty($js_asset['preprocessed'])) {
        $query = [
          'scope' => $js_asset['scope'] === 'header' ? 'header' : 'footer',
          'delta' => "{$order}",
        ] + $query_args;
        // Add a filename prefix to mitigate ad blockers which can block
        // any script beginning with 'ad'.
        $filename = 'js_' . $this->generateHash($js_asset) . '.js';
        $uri = 'assets://js/' . $filename;
        $js_assets[$order]['data'] = $this->fileUrlGenerator
          ->generateString($uri) . '?' . UrlHelper::buildQuery($query);
      }
      unset($js_assets[$order]['items']);
    }
  }
  return $js_assets;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.