You are here

function advagg_process_css in Advanced CSS/JS Aggregation 7

Same name and namespace in other branches
  1. 6 advagg.module \advagg_process_css()

Returns a themed representation of all stylesheets that should be attached to the page.

It loads the CSS in order, with 'module' first, then 'theme' afterwards. This ensures proper cascading of styles so themes can easily override module styles through CSS selectors.

Themes may replace module-defined CSS files by adding a stylesheet with the same filename. For example, themes/garland/system-menus.css would replace modules/system/system-menus.css. This allows themes to override complete CSS files, rather than specific selectors, when necessary.

If the original CSS file is being overridden by a theme, the theme is responsible for supplying an accompanying RTL CSS file to replace the module's.

Parameters

$css: (optional) An array of CSS files. If no array is provided, the default stylesheets array is used instead.

$noagg: (optional) Bool indicating that aggregation should be disabled if TRUE.

Return value

A string of XHTML CSS tags.

See also

drupal_get_css()

2 calls to advagg_process_css()
advagg_get_js_css_get_array in ./advagg.module
Return a large array of the CSS & JS files loaded on this page.
advagg_process_html_css in includes/css.inc

File

includes/css.inc, line 89

Code

function advagg_process_css($css = NULL, $noagg = FALSE) {
  global $conf;
  $original_css = $css;
  if (!isset($css)) {
    $css = drupal_add_css(CSS_DEFAULT);
  }
  if (empty($css)) {
    return FALSE;
  }

  // Get useful info.
  list($preprocess_css, $scheme, $query_string) = advagg_process_css_js_prep($noagg, 'css');

  // Invoke hook_advagg_css_pre_alter() to give installed modules a chance to
  // modify the data in the $javascript array if necessary.
  drupal_alter('advagg_css_pre', $css, $preprocess_css, $scheme);

  // Set variables.
  $external_no_preprocess = array();
  $module_no_preprocess = array();
  $output_no_preprocess = array();
  $output_preprocess = array();
  $theme_no_preprocess = array();
  $inline_no_preprocess = array();
  $files_included = array();
  $files_aggregates_included = array();
  $inline_included = array();

  // Process input.
  foreach ($css as $media => $types) {

    // Setup some variables
    $files_included[$media] = array();
    $files_aggregates_included[$media] = array();
    $inline_included[$media] = array();

    // If CSS preprocessing is off, we still need to output the styles.
    // Additionally, go through any remaining styles if CSS preprocessing is on
    // and output the non-cached ones.
    foreach ($types as $type => $files) {
      if ($type == 'module') {

        // Setup theme overrides for module styles.
        $theme_styles = array();
        foreach (array_keys($css[$media]['theme']) as $theme_style) {
          $theme_styles[] = basename($theme_style);
        }
      }
      foreach ($types[$type] as $file => $preprocess) {

        // If the theme supplies its own style using the name of the module
        // style, skip its inclusion. This includes any RTL styles associated
        // with its main LTR counterpart.
        if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) {

          // Unset the file to prevent its inclusion when CSS aggregation is enabled.
          unset($types[$type][$file]);
          continue;
        }

        // If a CSS file is not to be preprocessed and it's an inline CSS blob
        // it needs to *always* appear at the *very bottom*.
        if ($type == 'inline') {
          if (is_array($preprocess)) {
            foreach ($preprocess as $suffix => $blob) {
              $blob = advagg_drupal_load_stylesheet_content($blob, $preprocess);

              // Invoke hook_advagg_css_inline_alter() to give installed modules
              // a chance to modify the contents of $blob if necessary.
              drupal_alter('advagg_css_inline', $blob);
              $inline_no_preprocess[] = array(
                'media' => $media,
                'data' => $blob,
                'prefix' => $file,
                'suffix' => $suffix,
              );
              $inline_included[$media][] = $blob;
            }
          }

          // Unset to prevent its inclusion.
          unset($types[$type][$file]);
          continue;
        }
        $prefix = '';
        $suffix = '';

        // Invoke hook_advagg_css_extra_alter() to
        // give installed modules a chance to modify the prefix or suffix for a
        // given filename.
        $values = array(
          $file,
          NULL,
          $prefix,
          $suffix,
        );
        drupal_alter('advagg_css_extra', $values);
        list($file, $null, $prefix, $suffix) = $values;
        if ($type == 'inline') {
          $file = advagg_drupal_load_stylesheet_content($file, $preprocess);

          // Invoke hook_advagg_css_inline_alter() to give installed modules a
          // chance to modify the contents of $file if necessary.
          drupal_alter('advagg_css_inline', $file);
          $inline_no_preprocess[] = array(
            'media' => $media,
            'data' => $file,
            'prefix' => $prefix,
            'suffix' => $suffix,
          );
          $inline_included[$media][] = $file;

          // Unset to prevent its inclusion.
          unset($types[$type][$file]);
          continue;
        }

        // If a CSS file is not to be preprocessed and it's an external
        // CSS file, it needs to *always* appear at the *very top*,
        // regardless of whether preprocessing is on or off.
        if ($type == 'external') {
          $external_no_preprocess[] = array(
            'media' => $media,
            'href' => $file,
            'prefix' => $prefix,
            'suffix' => $suffix,
          );
          $files_included[$media][$file] = TRUE;

          // Unset the file to prevent its inclusion.
          unset($types[$type][$file]);
          continue;
        }

        // Only include the stylesheet if it exists.
        if (advagg_file_exists($file)) {
          if (!$preprocess || !($scheme === 'public' && $preprocess_css)) {

            // Create URI for file.
            $file_uri = advagg_build_uri($file) . $query_string;
            $files_included[$media][$file] = $preprocess;

            // If a CSS file is not to be preprocessed and it's a module CSS
            // file, it needs to *always* appear at the *top*, regardless of
            // whether preprocessing is on or off.
            if (!$preprocess && $type == 'module') {
              $module_no_preprocess[] = array(
                'media' => $media,
                'href' => $file_uri,
                'prefix' => $prefix,
                'suffix' => $suffix,
              );
            }
            elseif (!$preprocess && $type == 'theme') {
              $theme_no_preprocess[] = array(
                'media' => $media,
                'href' => $file_uri,
                'prefix' => $prefix,
                'suffix' => $suffix,
              );
            }
            else {
              $output_no_preprocess[] = array(
                'media' => $media,
                'href' => $file_uri,
                'prefix' => $prefix,
                'suffix' => $suffix,
              );
            }
          }
        }
      }
    }
    if ($scheme == 'public' && $preprocess_css) {
      $files_aggregates_included[$media] = $files_included[$media];
      $files = array();
      foreach ($types as $type) {
        foreach ($type as $file => $cache) {
          if ($cache) {
            $files[] = $file;
            $files_included[$media][$file] = TRUE;
            unset($files_aggregates_included[$file]);
          }
        }
      }
      if (!empty($files)) {
        $preprocess_files = advagg_css_js_file_builder('css', $files, $query_string);
        if (!empty($preprocess_files)) {
          $good = TRUE;
          foreach ($preprocess_files as $preprocess_file => $extra) {

            // Empty aggregate, skip
            if (empty($preprocess_file)) {
              continue;
            }
            if ($extra !== FALSE && is_array($extra)) {
              $prefix = $extra['prefix'];
              $suffix = $extra['suffix'];
              $output_preprocess[] = array(
                'media' => $media,
                'href' => advagg_build_uri($preprocess_file),
                'prefix' => $prefix,
                'suffix' => $suffix,
              );
              $files_aggregates_included[$media][$preprocess_file] = $extra;
            }
            else {
              $good = FALSE;
              break;
            }
          }
        }
        if (empty($good)) {

          // Redo with aggregation turned off and return the new value.
          watchdog('advagg', 'CSS aggregation failed. %filename could not be saved correctly.', array(
            '%filename' => $preprocess_file,
          ), WATCHDOG_ERROR);
          $data = advagg_process_css($original_css, TRUE);
          return $data;
        }
      }
    }
  }

  // Default function called: advagg_unlimited_css_builder
  $function = variable_get('advagg_css_render_function', ADVAGG_CSS_RENDER_FUNCTION);
  return $function($external_no_preprocess, $module_no_preprocess, $output_no_preprocess, $output_preprocess, $theme_no_preprocess, $inline_no_preprocess, $inline_included, $files_included, $files_aggregates_included);
}