You are here

css_gzip.module in CSS Gzip 6

Gzips aggregated CSS files if CSS Optimization is turned on.

File

css_gzip.module
View source
<?php

/**
 * @file
 * Gzips aggregated CSS files if CSS Optimization is turned on.
 */

/**
 * Implementation of hook_help().
 *
 * @param $path
 *   A Drupal menu router path the help is being requested fo
 * @param $arg
 *   An array that corresponds to the return of the arg() function
 */
function css_gzip_help($path, $arg) {
  switch ($path) {
    case 'admin/help#css_gzip':
      $output = '<p>' . t('Option to gzip the aggregated CSS file when <em>CSS optimization</em> has been enabled in the <a href="@performance">Performance settings</a>. Requires .htaccess mod_rewrite (apache web server & clean urls).', array(
        '@performance' => url('admin/settings/performance'),
      )) . '</p>';
      return $output;
  }
}

/**
 * Implementation of hook_form_alter().
 *
 * @param &$form
 *   Nested array of form elements that comprise the form.
 * @param $form_state
 *   A keyed array containing the current state of the form.
 * @param $form_id
 *   String representing the name of the form itself. Typically this is the name of the function that generated the form.
 */
function css_gzip_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'system_performance_settings') {
    $form['bandwidth_optimizations']['preprocess_css']['#weight'] = -10;
    $form['bandwidth_optimizations']['css_gzip'] = array(
      '#type' => 'checkbox',
      '#title' => t('GZip CSS'),
      '#description' => t('Optionally <a href="@gzip">GZip</a> the aggregated CSS file to dramatically decrease its size.', array(
        '@gzip' => 'http://en.wikipedia.org/wiki/Gzip',
      )),
      '#default_value' => variable_get('css_gzip', FALSE),
      '#weight' => -9,
    );
    $form['bandwidth_optimizations']['css_gzip_no_htaccess'] = array(
      '#type' => 'checkbox',
      '#title' => t('GZip CSS: Do not generate .htaccess file'),
      '#description' => t('Sometimes your host does not like multiple .htaccess files. Enable this to bypass htaccess file generation. Follow directions in the README.txt if this is effecting you.'),
      '#default_value' => variable_get('css_gzip_no_htaccess', FALSE),
      '#weight' => -8,
    );
    $form['bandwidth_optimizations']['css_gzip_exit'] = array(
      '#type' => 'checkbox',
      '#title' => t('GZip CSS: Use hook exit as well.'),
      '#description' => t("If you're using a recolorable theme, you should probably use this."),
      '#default_value' => variable_get('css_gzip_exit', FALSE),
      '#weight' => -7,
    );
  }
}

/**
 * Implementation of template_preprocess_page().
 *
 * Does not modify the pages contents, only gets info. Could probably use
 * drupal_get_css() and a different hook, if needed.
 *
 * @param &$variables
 *   Array containing various page elements.
 */
function css_gzip_preprocess_page(&$variables) {
  $htaccess = file_directory_path() . '/css/' . '.htaccess';
  if (!variable_get('css_gzip', FALSE) || variable_get('css_gzip_no_htaccess', FALSE)) {
    css_gzip_remove_htaccess($htaccess);
  }
  if (!empty($variables['styles']) && variable_get('preprocess_css', FALSE) && variable_get('css_gzip', FALSE)) {
    if (!variable_get('css_gzip_no_htaccess', FALSE) && (file_exists($htaccess) == FALSE || variable_get('css_gzip_htaccess_size', NULL) != filesize($htaccess))) {
      css_gzip_create_htaccess($htaccess);
    }
    $css_files = css_gzip_file_list($variables['styles']);

    // Create the GZip file if it doesn't already exist.
    css_gzip_copy_compress($css_files);
  }
}

/**
 * Implementation of hook_init().
 *
 * Start the output buffer.
 */
function css_gzip_init() {
  if (variable_get('css_gzip', FALSE) && variable_get('css_gzip_exit', FALSE)) {
    ob_start();
  }
}

/**
 * Implementation of hook_exit().
 *
 * Alt way of getting the css filenames
 */
function css_gzip_exit() {

  // Ensure we are not serving a cached page; drupal_set_content is the first
  // function in common.inc which is included in the full drupal bootstrap.
  if (variable_get('css_gzip', FALSE) && variable_get('css_gzip_exit', FALSE) && function_exists('drupal_set_content')) {
    $buffer = ob_get_contents();

    // Extract external css files from html document
    $css = explode('<link type="text/css" rel="stylesheet" ', $buffer);
    array_shift($css);
    foreach ($css as $key => $value) {

      // Only grab the first one, containing the css filename.
      $css[$key] = array_shift(explode(' />', $value));
    }
    $css = implode('', $css);
    $css_files = css_gzip_file_list($css);

    // Create the GZip file if it doesn't already exist.
    css_gzip_copy_compress($css_files);
  }
}

/**
 * Get list of css files for this page
 *
 * @param &$variables
 *   Array containing various page elements.
 */
function css_gzip_file_list($css) {
  $path = base_path() . file_directory_path() . '/css/';
  $css_files = explode($path, $css);
  array_shift($css_files);
  for ($i = 0; $i < count($css_files); $i++) {
    $css_files[$i] = array_shift(explode('.css', $css_files[$i])) . '.css';
  }
  return $css_files;
}

/**
 * Generate & write the .htaccess file inside the files/css dir.
 *
 * @param $htaccess
 *   Path and filename of the subdir .htaccess file.
 */
function css_gzip_create_htaccess($htaccess) {
  $htaccess_contents = <<<EOT
# Requires mod_mime to be enabled.
<IfModule mod_mime.c>
  # Send any files ending in .gz with x-gzip encoding in the header.
  AddEncoding gzip .gz
</IfModule>
# Gzip compressed css files are of the type 'text/css'.
<FilesMatch "\\.css\\.gz\$">
  ForceType text/css
</FilesMatch>
<IfModule mod_rewrite.c>
  RewriteEngine on
  # Serve gzip compressed css files
  RewriteCond %{HTTP:Accept-encoding} gzip
  RewriteCond %{REQUEST_FILENAME}\\.gz -s
  RewriteRule ^(.*)\\.css \$1\\.css\\.gz [L,QSA,T=text/css]
</IfModule>
EOT;
  file_save_data($htaccess_contents, $htaccess, FILE_EXISTS_REPLACE);
  variable_set('css_gzip_htaccess_size', filesize($htaccess));
}

/**
 * Delete the .htaccess file inside the files/css dir.
 *
 * @param $htaccess
 *   Path and filename of the subdir .htaccess file.
 */
function css_gzip_remove_htaccess($htaccess) {
  if (file_exists($htaccess)) {
    file_delete($htaccess);
  }
}

/**
 * Read and compress the css files.
 *
 * @param $css_files
 *   Array of css filenames.
 */
function css_gzip_copy_compress($css_files) {
  foreach ($css_files as $css_file) {
    if (file_exists(file_directory_path() . '/css/' . $css_file) && !file_exists(file_directory_path() . '/css/' . $css_file . '.gz')) {
      file_save_data(gzencode(file_get_contents(file_directory_path() . '/css/' . $css_file), 9), file_directory_path() . '/css/' . $css_file . '.gz', FILE_EXISTS_REPLACE);
    }
  }
}

Functions

Namesort descending Description
css_gzip_copy_compress Read and compress the css files.
css_gzip_create_htaccess Generate & write the .htaccess file inside the files/css dir.
css_gzip_exit Implementation of hook_exit().
css_gzip_file_list Get list of css files for this page
css_gzip_form_alter Implementation of hook_form_alter().
css_gzip_help Implementation of hook_help().
css_gzip_init Implementation of hook_init().
css_gzip_preprocess_page Implementation of template_preprocess_page().
css_gzip_remove_htaccess Delete the .htaccess file inside the files/css dir.