예제 #1
0
 /**
  * {@inheritdoc}
  *
  * The cache file name is retrieved on a page load via a lookup variable that
  * contains an associative array. The array key is the hash of the file names
  * in $css while the value is the cache file name. The cache file is generated
  * in two cases. First, if there is no file name value for the key, which will
  * happen if a new file name has been added to $css or after the lookup
  * variable is emptied to force a rebuild of the cache. Second, the cache file
  * is generated if it is missing on disk. Old cache files are not deleted
  * immediately when the lookup variable is emptied, but are deleted after a
  * configurable period (@code system.performance.stale_file_threshold @endcode)
  * to ensure that files referenced by a cached page will still be available.
  */
 public function optimize(array $css_assets)
 {
     // Group the assets.
     $css_groups = $this->grouper->group($css_assets);
     // Now optimize (concatenate + minify) and dump each asset group, unless
     // that was already done, in which case it should appear in
     // drupal_css_cache_files.
     // Drupal contrib can override this default CSS aggregator to keep the same
     // grouping, optimizing and dumping, but change the strategy that is used to
     // determine when the aggregate should be rebuilt (e.g. mtime, HTTPS …).
     $map = $this->state->get('drupal_css_cache_files') ?: array();
     $css_assets = array();
     foreach ($css_groups as $order => $css_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.
         $css_assets[$order] = $css_group;
         unset($css_assets[$order]['items']);
         switch ($css_group['type']) {
             case 'file':
                 // No preprocessing, single CSS asset: just use the existing URI.
                 if (!$css_group['preprocess']) {
                     $uri = $css_group['items'][0]['data'];
                     $css_assets[$order]['data'] = $uri;
                 } else {
                     $key = $this->generateHash($css_group);
                     $uri = '';
                     if (isset($map[$key])) {
                         $uri = $map[$key];
                     }
                     if (empty($uri) || !file_exists($uri)) {
                         // Optimize each asset within the group.
                         $data = '';
                         foreach ($css_group['items'] as $css_asset) {
                             $data .= $this->optimizer->optimize($css_asset);
                         }
                         // Per the W3C specification at
                         // http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, @import
                         // rules must proceed any other style, so we move those to the
                         // top.
                         $regexp = '/@import[^;]+;/i';
                         preg_match_all($regexp, $data, $matches);
                         $data = preg_replace($regexp, '', $data);
                         $data = implode('', $matches[0]) . $data;
                         // Dump the optimized CSS for this group into an aggregate file.
                         $uri = $this->dumper->dump($data, 'css');
                         // Set the URI for this group's aggregate file.
                         $css_assets[$order]['data'] = $uri;
                         // Persist the URI for this aggregate file.
                         $map[$key] = $uri;
                         $this->state->set('drupal_css_cache_files', $map);
                     } else {
                         // Use the persisted URI for the optimized CSS file.
                         $css_assets[$order]['data'] = $uri;
                     }
                     $css_assets[$order]['preprocessed'] = TRUE;
                 }
                 break;
             case 'inline':
                 // We don't do any caching for inline CSS assets.
                 $data = '';
                 foreach ($css_group['items'] as $css_asset) {
                     $data .= $this->optimizer->optimize($css_asset);
                 }
                 unset($css_assets[$order]['data']['items']);
                 $css_assets[$order]['data'] = $data;
                 break;
             case 'external':
                 // We don't do any aggregation and hence also no caching for external
                 // CSS assets.
                 $uri = $css_group['items'][0]['data'];
                 $css_assets[$order]['data'] = $uri;
                 break;
         }
     }
     return $css_assets;
 }
예제 #2
0
 /**
  * {@inheritdoc}
  *
  * The cache file name is retrieved on a page load via a lookup variable that
  * contains an associative array. The array key is the hash of the names in
  * $files while the value is the cache file name. The cache file is generated
  * in two cases. First, if there is no file name value for the key, which will
  * happen if a new file name has been added to $files or after the lookup
  * variable is emptied to force a rebuild of the cache. Second, the cache file
  * is generated if it is missing on disk. Old cache files are not deleted
  * immediately when the lookup variable is emptied, but are deleted after a
  * configurable period (@code system.performance.stale_file_threshold @endcode)
  * to ensure that files referenced by a cached page will still be available.
  */
 public function optimize(array $js_assets)
 {
     // Group the assets.
     $js_groups = $this->grouper->group($js_assets);
     // Now optimize (concatenate, not minify) and dump each asset group, unless
     // that was already done, in which case it should appear in
     // system.js_cache_files.
     // Drupal contrib can override this default JS aggregator to keep the same
     // grouping, optimizing and dumping, but change the strategy that is used to
     // determine when the aggregate should be rebuilt (e.g. mtime, HTTPS …).
     $map = $this->state->get('system.js_cache_files') ?: array();
     $js_assets = array();
     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;
         unset($js_assets[$order]['items']);
         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 {
                     $key = $this->generateHash($js_group);
                     $uri = '';
                     if (isset($map[$key])) {
                         $uri = $map[$key];
                     }
                     if (empty($uri) || !file_exists($uri)) {
                         // Concatenate each asset within the group.
                         $data = '';
                         foreach ($js_group['items'] as $js_asset) {
                             // Optimize this JS file, but only if it's not yet minified.
                             if (isset($js_asset['minified']) && $js_asset['minified']) {
                                 $data .= file_get_contents($js_asset['data']);
                             } else {
                                 $data .= $this->optimizer->optimize($js_asset);
                             }
                             // Append a ';' and a newline after each JS file to prevent them
                             // from running together.
                             $data .= ";\n";
                         }
                         // Remove unwanted JS code that cause issues.
                         $data = $this->optimizer->clean($data);
                         // Dump the optimized JS for this group into an aggregate file.
                         $uri = $this->dumper->dump($data, 'js');
                         // Set the URI for this group's aggregate file.
                         $js_assets[$order]['data'] = $uri;
                         // Persist the URI for this aggregate file.
                         $map[$key] = $uri;
                         $this->state->set('system.js_cache_files', $map);
                     } else {
                         // Use the persisted URI for the optimized JS file.
                         $js_assets[$order]['data'] = $uri;
                     }
                     $js_assets[$order]['preprocessed'] = TRUE;
                 }
                 break;
             case 'external':
             case 'setting':
             case 'inline':
                 // We don't do any aggregation and hence also no caching for external,
                 // setting or inline JS assets.
                 $uri = $js_group['items'][0]['data'];
                 $js_assets[$order]['data'] = $uri;
                 break;
         }
     }
     return $js_assets;
 }