1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
 * Returns a themed representation of all stylesheets that should be attached to the page.
 * It loads the CSS in order, with 'core' CSS first, then 'module' CSS, then 'theme' CSS files.
 * This ensures proper cascading of styles for easy overriding in modules and themes.
 *
 * @param $css
 *   (optional) An array of CSS files. If no array is provided, the default stylesheets array is used instead.
 * @return
 *   A string of XHTML CSS tags.
 */
function drupal_get_css($css = NULL) {
  $output = '';
  if (!isset($css)) {
    $css = drupal_add_css();
  }
  $no_module_preprocess = '';
  $no_theme_preprocess = '';

  $preprocess_css = variable_get('preprocess_css', FALSE);
  $directory = file_directory_path();
  $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);

  global $theme_info;
  // Read from theme's .info file.
  if (isset($theme_info->info['styleoverrides'])) {
    $style_overrides = $theme_info->info['styleoverrides'];
  }

  foreach ($css as $media => $types) {
    // 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) {
      foreach ($types[$type] as $file => $preprocess) {
        // Allow themes to provide module overrides.
        if ($type == 'module' && isset($style_overrides)) {
          // Module styles will be rebuilt to maintain original order.
          unset($types[$type][$file]);
          // Get the sub-path and style sheet for the module after "modules/" since it can be installed in multiple locations.
          $sub_path_style = substr(strstr($file, 'modules/'), 8);
          // Get the style sheet name.
          $style = substr($sub_path_style, strpos($sub_path_style, '/') + 1);
          // Check both strings for the override.
          foreach (array($sub_path_style, $style) as $override) {
            if (isset($style_overrides[$override]) && file_exists($override_file = path_to_theme() .'/'. $style_overrides[$override])) {
              $file = $override_file;
              break;
            }
          }
          // This rebuilds the styles for modules.
          $types[$type][$file] = $preprocess;
        }

        if (!$preprocess || !($is_writable && $preprocess_css)) {
          // 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') {
            $no_module_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file .'" />'."\n";
          }
          // If a CSS file is not to be preprocessed and it's a theme CSS file, it needs to *always* appear at the *bottom*,
          // regardless of whether preprocessing is on or off.
          else if (!$preprocess && $type == 'theme') {
            $no_theme_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file .'" />'."\n";
          }
          else {
            $output .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . '" />'."\n";
          }
        }
      }
    }

    if ($is_writable && $preprocess_css) {
      $filename = md5(serialize($types)) .'.css';
      $preprocess_file = drupal_build_css_cache($types, $filename);
      $output .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $preprocess_file .'" />'."\n";
    }
  }

  return $no_module_preprocess . $output . $no_theme_preprocess;
}