You are here

function _css_emimage_text_processor in CSS Embedded Images 6.2

Same name and namespace in other branches
  1. 7 css_emimage.advagg.inc \_css_emimage_text_processor()

Process the css text and replace it with image data where necessary.

Parameters

$data: CSS text data to process over.

$key: Used for a static cache.

$type: The type of css wanted back, base or emimage.

2 calls to _css_emimage_text_processor()
css_emimage_advagg_css_alter in ./css_emimage.module
Implementation of hook_advagg_css_alter().
_css_emimage_process in ./css_emimage.module
Helper function to replace URLs with data URIs.

File

./css_emimage.module, line 469
CSS Embedded Images module.

Code

function _css_emimage_text_processor(&$data, $key, $type) {
  static $values = array();

  // This only processes base & emimage types.
  if ($type != 'base' && $type != 'emimage') {
    return;
  }
  if (empty($values[$key][$type])) {

    // Do magic; code could be improved.
    _css_emimage_collect_static(array(
      array(),
      array(),
    ));

    // Reset the processed declarations.
    $contents = $data;
    $datauri_css = '';
    $pattern = '/([^{}]+){([^{}]*?(background(?:-image)?|list-style(?:-image)?):[^{};)]*?(?:none|url\\([\'"]?.+?[\'"]?\\))[^{}]*)}/i';
    $contents = preg_replace_callback($pattern, '_css_emimage_replace', $contents);
    if (!is_null($contents)) {
      list($declarations, $file_stats) = _css_emimage_collect_static();

      // Check for duplicate images and exclude those exceeding our duplication limit.
      // Sum the amount of data being embedded.
      $datauri_total_length = 0;
      foreach ($file_stats as $fs) {
        if (count($fs['indices']) > 1 && $fs['total_length'] > variable_get('css_emimage_duplicate_embed_limit', CSS_EMIMAGE_DUPLICATE_EMBED_LIMIT)) {
          foreach ($fs['indices'] as $fsi) {
            $declarations[$fsi]['base64'] = '';
          }
        }
        else {
          $datauri_total_length += $fs['total_length'];
        }
      }
      list($ext_contents, $ext_data) = _css_emimage_build_external($contents, $declarations);

      // If the amount of data being embedded is within the inline limit, inline the data URIs;
      // otherwise, store the data URIs in a separate CSS file.
      if (variable_get('css_emimage_force_inline', 0) || $datauri_total_length && $datauri_total_length <= variable_get('css_emimage_inline_datauri_limit', CSS_EMIMAGE_INLINE_DATAURI_LIMIT)) {
        $inline = _css_emimage_build_inline($contents, $declarations);
        if (strlen($inline) < strlen($ext_contents) + strlen($ext_data)) {
          $datauri_css = $inline;
        }
        else {
          $datauri_css = "{$ext_contents}\n{$ext_data}";
        }
        $contents = '';
      }
      else {
        $contents = $ext_contents;
        $datauri_css = $ext_data;
      }
    }
    else {
      $error_code = preg_last_error();
      $error_messages = array(
        PREG_NO_ERROR => 'NO_ERROR',
        PREG_INTERNAL_ERROR => 'INTERNAL_ERROR',
        PREG_BACKTRACK_LIMIT_ERROR => 'BACKTRACK_LIMIT_ERROR',
        PREG_RECURSION_LIMIT_ERROR => 'RECURSION_LIMIT_ERROR',
        PREG_BAD_UTF8_ERROR => 'BAD_UTF8_ERROR',
        PREG_BAD_UTF8_OFFSET_ERROR => 'BAD_UTF8_OFFSET_ERROR',
      );
      watchdog('css_emimage', 'Error while trying to embed images in your CSS, falling back to unmodified CSS. PCRE error was: !error.', array(
        '!error' => array_key_exists($error_code, $error_messages) ? $error_messages[$error_code] : $error_code,
      ), WATCHDOG_ERROR);
      return;
    }
    $values[$key]['base'] = $contents;
    $values[$key]['emimage'] = $datauri_css;
  }

  // Send data back.
  $data = $values[$key][$type];

  // Free memory, values only gets used once.
  unset($values[$key][$type]);
}