Advanced CSS/JS aggregation external compression module.

File

advagg_ext_compress/advagg_ext_compress.module

View source
<?php


/**
 * @file
 * Advanced CSS/JS aggregation external compression module.
 */

/**
 * @addtogroup hooks
 * @{
 */

/**
 * Implements hook_menu().
 */
function advagg_ext_compress_menu() {
    $file_path = drupal_get_path('module', 'advagg_ext_compress');
    $config_path = advagg_admin_config_root_path();
    $items[$config_path . '/advagg/ext-compress'] = array(
        'title' => 'External Compression',
        'description' => 'Adjust External Compression settings.',
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
            'advagg_ext_compress_admin_settings_form',
        ),
        'type' => MENU_LOCAL_TASK,
        'access arguments' => array(
            'administer site configuration',
        ),
        'file path' => $file_path,
        'file' => 'advagg_ext_compress.admin.inc',
        'weight' => 10,
    );
    return $items;
}

/**
 * @} End of "addtogroup hooks".
 */

/**
 * @addtogroup advagg_hooks
 * @{
 */

/**
 * Implements hook_advagg_js_compress_configuration_alter().
 */
function advagg_ext_compress_advagg_js_compress_configuration_alter(&$options_desc, &$compressors, &$functions) {
    list($options, $description) = $options_desc;
    $key = 10;
    while (isset($options[$key])) {
        $key++;
    }
    $options[$key] = t('AdvAgg Command Line Compressor');
    $compressors[$key] = 'advagg_cmdline';
    $functions[$key] = 'advagg_ext_compress_js_compress';
    $options_desc = array(
        $options,
        $description,
    );
}

/**
 * Implements hook_advagg_css_compress_configuration_alter().
 */
function advagg_ext_compress_advagg_css_compress_configuration_alter(&$options_desc, &$compressors, &$functions) {
    list($options, $description) = $options_desc;
    $key = 10;
    while (isset($options[$key])) {
        $key++;
    }
    $options[$key] = t('AdvAgg Command Line Compressor');
    $functions[$key] = 'advagg_ext_compress_css_compress';
    $options_desc = array(
        $options,
        $description,
    );
}

/**
 * @} End of "addtogroup advagg_hooks".
 */

/**
 * Compress Javascript using via command line.
 *
 * @param string $input_file
 *   The file containing the uncompressed css/js data.
 * @param string $ext
 *   The string css or js.
 * @param array $debug
 *   Optional debug array.
 *
 * @return string
 *   The filename containing the compressed css/js data.
 */
function advagg_ext_compress_execute_cmd($input_file, $ext = '', array &$debug = array()) {
    $run = variable_get("advagg_ext_compress_{$ext}_cmd", '');
    if (empty($run)) {
        return FALSE;
    }
    // Get file extension.
    if (empty($ext)) {
        $ext = strtolower(pathinfo($input_file, PATHINFO_EXTENSION));
        if ($ext !== 'css' && $ext !== 'js') {
            // Get the $ext from the database.
            $row = db_select('advagg_files', 'af')->fields('af')
                ->condition('filename', $input_file)
                ->execute()
                ->fetchAssoc();
            if (!empty($row['filetype'])) {
                $ext = $row['filetype'];
            }
            if ($ext === 'less') {
                $ext = 'css';
            }
        }
    }
    // Generate temp file.
    $temp_file = drupal_tempnam('temporary://', 'advagg_file_');
    $new_temp_file = $temp_file . '.' . basename($input_file);
    @rename($temp_file, $new_temp_file);
    // Set the permissions on the temp file.
    drupal_chmod($new_temp_file);
    $output = advagg_get_relative_path($new_temp_file);
    // Create command to run.
    $cmd = str_replace(array(
        '{%CWD%}',
        '{%IN%}',
        '{%IN_URL_ENC%}',
        '{%OUT%}',
    ), array(
        DRUPAL_ROOT,
        $input_file,
        urlencode(file_create_url($input_file)),
        escapeshellarg(realpath($output)),
    ), $run);
    // Run command and return the output file.
    $shell_output = array();
    $return_var = 0;
    $shell = exec($cmd, $shell_output, $return_var);
    $debug = array(
        $cmd,
        $shell_output,
        $return_var,
        $shell,
    );
    // Cleanup leftover files.
    if (file_exists($temp_file)) {
        @unlink($temp_file);
    }
    return $output;
}

/**
 * Compress Javascript using via command line.
 *
 * @param string $contents
 *   The JavaScript to compress.
 * @param bool $log_errors
 *   TRUE to log errors.
 *
 * @return bool
 *   FALSE if this failed.
 */
function advagg_ext_compress_js_compress(&$contents, $log_errors) {
    return advagg_ext_compress_string($contents, 'js', $log_errors);
}

/**
 * Compress CSS using via command line.
 *
 * @param string $contents
 *   The CSS to compress.
 * @param bool $log_errors
 *   TRUE to log errors.
 *
 * @return bool
 *   FALSE if this failed.
 */
function advagg_ext_compress_css_compress(&$contents, $log_errors) {
    return advagg_ext_compress_string($contents, 'css', $log_errors);
}

/**
 * Compress CSS using via command line.
 *
 * @param string $contents
 *   The data to compress.
 * @param string $type
 *   Should be css or js.
 * @param bool $log_errors
 *   TRUE to log errors.
 *
 * @return bool
 *   TRUE on success.
 */
function advagg_ext_compress_string(&$contents, $type, $log_errors) {
    list($css_path, $js_path) = advagg_get_root_files_dir();
    if ($type === 'css') {
        $dir = $css_path[0];
    }
    else {
        $dir = $js_path[0];
    }
    $new_temp_file = $dir . '/advagg_file_' . drupal_hash_base64(microtime(TRUE) . mt_rand()) . '.' . $type;
    $temp_file_full = advagg_get_relative_path($new_temp_file);
    file_put_contents($new_temp_file, $contents);
    // Set the permissions on the temp file.
    drupal_chmod($new_temp_file);
    $debug = array();
    $output = advagg_ext_compress_execute_cmd($temp_file_full, $type, $debug);
    if (empty($output)) {
        return FALSE;
    }
    $new_contents = advagg_file_get_contents($output);
    if (strpos($new_contents, 'Error') === 0) {
        if ($log_errors) {
            watchdog('advagg_ext_compress', "@a \n<br>\n<br> @b", array(
                // Only log 4k of data.
'@a' => substr($new_contents, 0, 4096),
                '@b' => print_r($debug, TRUE),
            ));
        }
        $return = FALSE;
    }
    else {
        $contents = $new_contents;
        $return = TRUE;
    }
    // Cleanup.
    if (file_exists($new_temp_file)) {
        unlink($new_temp_file);
    }
    if (file_exists($temp_file_full)) {
        unlink($temp_file_full);
    }
    if (file_exists($output)) {
        unlink($output);
    }
    return $return;
}

Functions

Title Deprecated Summary
advagg_ext_compress_advagg_css_compress_configuration_alter Implements hook_advagg_css_compress_configuration_alter().
advagg_ext_compress_advagg_js_compress_configuration_alter Implements hook_advagg_js_compress_configuration_alter().
advagg_ext_compress_css_compress Compress CSS using via command line.
advagg_ext_compress_execute_cmd Compress Javascript using via command line.
advagg_ext_compress_js_compress Compress Javascript using via command line.
advagg_ext_compress_menu Implements hook_menu().
advagg_ext_compress_string Compress CSS using via command line.