Same filename in other branches
  1. 5.0.x advagg.install
  2. 6.0.x advagg.install
  3. 7.x-2.x advagg.install
  4. 8.x-2.x advagg.install
  5. 8.x-3.x advagg.install
  6. 8.x-4.x advagg.install

Handles Advanced Aggregation installation and upgrade tasks.

File

./advagg.install

View source
<?php


/**
 * @file
 * Handles Advanced Aggregation installation and upgrade tasks.
 */

/**
 * Implements hook_enable().
 */
function advagg_enable() {
    // Create the advagg_css/ path within the files folder.
    $css_path = 'public://advagg_css';
    file_prepare_directory($css_path, FILE_CREATE_DIRECTORY);
    $js_path = 'public://advagg_js';
    // Create the advagg_js/ path within the files folder.
    file_prepare_directory($js_path, FILE_CREATE_DIRECTORY);
    // Include the module file.
    register_shutdown_function('drupal_load', 'module', 'advagg');
    // Rescan files.
    register_shutdown_function('advagg_flush_caches');
    // Check for fast404.
    register_shutdown_function('advagg_check_missing_handler');
    if (module_exists('javascript_aggregator')) {
        variable_set('advagg_closure', FALSE);
    }
}

/**
 * Implements hook_disable().
 */
function advagg_disable() {
    // Make sure the advagg_flush_caches function is available.
    drupal_load('module', 'advagg');
    // Flush advagg caches.
    $cache_tables = advagg_flush_caches();
    foreach ($cache_tables as $table) {
        cache_clear_all('*', $table, TRUE);
    }
}

/**
 * Implements hook_install().
 */
function advagg_install() {
    // Make sure we run last.
    // @TODO: Please review the conversion of this statement to the D7 database API syntax.
    
    /* db_query("UPDATE {system} SET weight = 250 WHERE name = 'advagg'") */
    db_update('system')->fields(array(
        'weight' => 250,
    ))
        ->condition('name', 'advagg')
        ->execute();
}

/**
 * Implements hook_uninstall().
 */
function advagg_uninstall() {
    // Make sure the advagg_get_root_files_dir function is available.
    drupal_load('module', 'advagg');
    // Remove files.
    list($css_path, $js_path) = advagg_get_root_files_dir();
    file_scan_directory($css_path, '/.*/', array(
        'callback' => 'file_unmanaged_delete',
    ));
    @unlink($css_path);
    file_scan_directory($js_path, '/.*/', array(
        'callback' => 'file_unmanaged_delete',
    ));
    @unlink($js_path);
    // Remove database tables.
    cache_clear_all('*', 'cache_advagg', TRUE);
    cache_clear_all('*', 'cache_advagg_files_data', TRUE);
    cache_clear_all('*', 'cache_advagg_bundle_reuse', TRUE);
    // Remove variables.
    // TODO Please review the conversion of this statement to the D7 database API syntax.
    
    /* db_query("DELETE FROM {variable} WHERE name LIKE 'cache_flush_cache_advagg%'") */
    db_delete('variable')->condition('name', 'advagg_%', 'LIKE')
        ->condition('name', 'cache_flush_cache_advagg%', 'LIKE')
        ->execute();
}

/**
 * Implements hook_requirements().
 */
function advagg_requirements($phase) {
    global $_advagg;
    $requirements = array();
    // Ensure translations don't break at install time
    $t = get_t();
    // Report Drupal version
    if ($phase == 'runtime') {
        list($css_path, $js_path) = array(
            'public://advagg_css',
            'public://advagg_js',
        );
        if (!file_prepare_directory($css_path, FILE_CREATE_DIRECTORY)) {
            $requirements['advagg_css_path'] = array(
                'title' => $t('Adv CSS/JS Agg - CSS Path'),
                'severity' => REQUIREMENT_ERROR,
                'value' => $t('CSS directory is not created or writable'),
                'description' => $t('%path is not setup correctly.', array(
                    '%path' => $css_path,
                )),
            );
        }
        if (!file_prepare_directory($js_path, FILE_CREATE_DIRECTORY)) {
            $requirements['advagg_js_path'] = array(
                'title' => $t('Adv CSS/JS Agg - JS Path'),
                'severity' => REQUIREMENT_ERROR,
                'value' => $t('JS directory is not created or writable'),
                'description' => $t('%path is not setup correctly.', array(
                    '%path' => $js_path,
                )),
            );
        }
        if (variable_get('preprocess_css', FALSE) || variable_get('preprocess_js', FALSE)) {
            $requirements['advagg_core_off'] = array(
                'title' => $t('Adv CSS/JS Agg - Core Variables'),
                'severity' => REQUIREMENT_ERROR,
                'value' => $t('Cores CSS and/or JS aggregation is enabled'),
                'description' => $t('"Optimize CSS files" and "Optimize JavaScript files" on the <a href="@performance">performance page</a> should be disabled.', array(
                    '@performance' => url('admin/config/development/performance'),
                )),
            );
        }
        if (variable_get('advagg_enabled', ADVAGG_ENABLED) == FALSE) {
            $requirements['advagg_not_on'] = array(
                'title' => $t('Adv CSS/JS Agg - Enabled'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('Advanced CSS/JS aggregation is not currently enabled.'),
                'description' => $t('Go to the Advanced CSS/JS aggregation <a href="@settings">settings page</a> and enable it.', array(
                    '@settings' => url('admin/config/advagg'),
                )),
            );
        }
        if (module_exists('css_gzip')) {
            $requirements['advagg_css_gzip'] = array(
                'title' => $t('Adv CSS/JS Agg - CSS Gzip'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The CSS Gzip module is enabled'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('csstidy')) {
            $requirements['advagg_csstidy'] = array(
                'title' => $t('Adv CSS/JS Agg - CSS Tidy'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The CSS Tidy module is enabled'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('javascript_aggregator')) {
            $requirements['advagg_javascript_aggregator'] = array(
                'title' => $t('Adv CSS/JS Agg - Javascript Aggregator'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The Javascript Aggregator is enabled'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed. Once uninstalled be sure to enable the "Use AdvAgg in closure" setting on the <a href="@config">advagg config page</a>', array(
                    '@modules' => url('admin/modules'),
                    '@config' => url('admin/config/advagg/config'),
                )),
            );
        }
        if (module_exists('unlimited_css')) {
            $requirements['advagg_unlimited_css'] = array(
                'title' => $t('Adv CSS/JS Agg - IE Unlimited CSS Loader'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The IE Unlimited CSS Loader module is enabled'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('ie_css_optimizer')) {
            $requirements['advagg_unlimited_css'] = array(
                'title' => $t('Adv CSS/JS Agg - IE CSS Optimizer'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The IE CSS Optimizer module is enabled'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('cmscdn')) {
            $requirements['advagg_cmscdn'] = array(
                'title' => $t('Adv CSS/JS Agg - CMS CDN'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The CMS CDN module is enabled.'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('bundlecache')) {
            $requirements['advagg_bundlecache'] = array(
                'title' => $t('Adv CSS/JS Agg - BundleCache'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('The BundleCache module is enabled.'),
                'description' => $t('On the <a href="@modules">modules page</a> you can disable it, as this module is no longer needed.', array(
                    '@modules' => url('admin/modules'),
                )),
            );
        }
        if (module_exists('css_emimage') && !function_exists('css_emimage_advagg_filenames_alter')) {
            $requirements['advagg_css_emimage'] = array(
                'title' => $t('Adv CSS/JS Agg - CSS Embedded Images'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('CSS Embedded Images module needs a patch.'),
                'description' => $t('You need to apply the latest patch from this issue <a href="@issue">CSS Embedded Images - Add in support for advaggs hooks</a>; otherwise these 2 modules are not compatible with each other.', array(
                    '@issue' => 'http://drupal.org/node/1078060',
                )),
            );
        }
        // @TODO: Remove this check? Is it needed in D7?
        // if (isset($_advagg['closure']) && $_advagg['closure'] == FALSE) {
        //   $requirements['advagg_closure'] = array(
        //     'title' => $t('Adv CSS/JS Agg - Closure'),
        //     'severity' => REQUIREMENT_WARNING,
        //     'value' => $t('Your theme implements its own closure function.'),
        //     'description' => $t('To solve this problem, you unfortunately have to modify your theme. Copy the phptemplate_closure() function found in <a href="@link">advagg.module source code</a> and integrate it into your theme phptemplate_closure() function or <themename>_closure() function.', array('@link' => 'http://drupalcode.org/project/advagg.git/blob/refs/heads/6.x-1.x:/advagg.module#l201')),
        //   );
        // }
        if (module_exists('cdn')) {
            $file_path_blacklist = variable_get(CDN_EXCEPTION_FILE_PATH_BLACKLIST_VARIABLE, CDN_EXCEPTION_FILE_PATH_BLACKLIST_DEFAULT);
            $file_path_blacklist = explode("\n", trim($file_path_blacklist));
            $file_path_blacklist = array_map('trim', $file_path_blacklist);
            $file_path_blacklist = array_filter($file_path_blacklist);
            if (array_search('*.js', $file_path_blacklist) !== FALSE) {
                $requirements['advagg_cdn_js_blacklist'] = array(
                    'title' => $t('Adv CSS/JS Agg - CDN Settings'),
                    'severity' => REQUIREMENT_WARNING,
                    'value' => $t('The CDN module is set to blacklist all *.js files.'),
                    'description' => $t('Check your <a href="@cdn">CDN settings</a> and adjust the blacklist to not include "*.js". Testing is important in this case. "*tiny_mce.js" is a file/pattern we had to add to the blacklist after removing *.js from it.', array(
                        '@cdn' => url('admin/config/cdn/other'),
                    )),
                );
            }
        }
        $hooks = theme_get_registry();
        // Test location of advagg_processor in $hooks['page']['preprocess functions'].
        $function = advagg_install_theme_registry_location($hooks);
        if ($function != '_advagg_process_html') {
            $requirements['advagg_theme'] = array(
                'title' => $t('Adv CSS/JS Agg - Theme Hook'),
                'severity' => REQUIREMENT_ERROR,
                'value' => $t('Theme hook is not in the correct place.'),
                'description' => $t('On the <a href="@performance">performance page</a> clear the cache. If this is still an issue open up a bug on the <a href="http://drupal.org/node/add/project-issue/advagg">advagg issue queue</a> and be sure to include the "Hook Theme Info" output from the Advanced CSS/JS aggregation <a href="@settings">settings page</a>.', array(
                    '@performance' => url('admin/config/development/performance'),
                    '@settings' => url('admin/config/advagg'),
                )),
            );
        }
        // @TODO: Remove this check? Is it needed in D7?
        // // Test closure function.
        // $function = $hooks['closure']['function'];
        // if ($function != 'phptemplate_closure' && variable_get('advagg_closure', ADVAGG_CLOSURE)) {
        //   $requirements['advagg_closure'] = array(
        //     'title' => $t('Adv CSS/JS Agg - Closure'),
        //     'severity' => REQUIREMENT_ERROR,
        //     'value' => $t('Closure theme function issue.') . $function,
        //     'description' => $t('On the <a href="@performance">performance page</a> clear the cache or just the theme registry if you know how to do that. If this is still an issue open up a bug on the <a href="http://drupal.org/node/add/project-issue/advagg">advagg issue queue</a>.', array(
        //       '@performance' => url('admin/config/development/performance'),
        //     )),
        //   );
        // }
        $requirements += advagg_check_missing_handler();
    }
    return $requirements;
}

/**
 * @todo Please document this function.
 * @see http://drupal.org/node/1354
 */
function advagg_install_theme_registry_location($hooks) {
    drupal_theme_initialize();
    $hooks = $hooks['html']['process functions'];
    // Define hooks that we can safely ignore, that get executed after advagg.
    $ignored_hooks = array(
        'rdf_process',
        'labjs_process_html',
        'headjs_process_html',
        'designkit_process_html',
        'cdn_process_html',
        'conditional_styles_process_html',
    );
    // Call hook_advagg_theme_registry_alter().
    drupal_alter('advagg_theme_registry', $ignored_hooks);
    // Removed ignored hooks.
    foreach ($ignored_hooks as $hook) {
        $key = array_search($hook, $hooks);
        if ($key !== FALSE) {
            unset($hooks[$key]);
        }
    }
    $function = array_pop($hooks);
    return $function;
}

/**
 * Check to see if the CSS/JS generator is working.
 */
function advagg_check_missing_handler() {
    drupal_load('module', 'advagg');
    advagg_install_test_async_stream();
    global $base_path;
    $ret = array();
    $async = variable_get('advagg_async_generation', -1);
    $filepath = '/css_missing' . mt_rand() . REQUEST_TIME . '_0';
    // Ensure translations don't break at install time
    $t = get_t();
    // Don't run the test if site is offline
    if (variable_get('site_offline', 0)) {
        $ret['advagg_async_offline'] = array(
            'title' => $t('Adv CSS/JS Agg - Asynchronous Mode'),
            'severity' => REQUIREMENT_WARNING,
            'value' => $t('Unknown. Currently set to @value.', array(
                '@value' => $async ? 'TRUE' : 'FALSE',
            )),
            'description' => $t('This can not be tested while the site is in <a href="@maintenance">offline mode</a>', array(
                '@maintenance' => url('admin/config/development/maintenance'),
            )),
        );
        return $ret;
    }
    // Setup request
    list($css_path, $js_path) = advagg_get_root_files_dir();
    $url = _advagg_build_url($css_path . $filepath . '.css');
    $headers = array(
        'Host' => $_SERVER['HTTP_HOST'],
        'Connection' => 'close',
    );
    // Check that the menu router handler is working. If it's not working the rest
    // of the tests are pointless.
    $item = menu_get_item($css_path . $filepath . '.css');
    if (empty($item['page_callback']) || strpos($item['page_callback'], 'advagg') === FALSE) {
        $item = str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r($item, TRUE))));
        $ret['advagg_async_generation_menu_issue'] = array(
            'title' => $t('Adv CSS/JS Agg - Async Mode'),
            'severity' => REQUIREMENT_WARNING,
            'value' => $t('Flush your caches'),
            'description' => $t('You need to flush your menu cache. This can be done near the bottom of the <a href="@performance">performance page</a>. If this does not fix the issue copy this info below when opening up an <a href="http://drupal.org/node/add/project-issue/advagg">issue for advagg</a>: <br /> !info', array(
                '@performance' => url('admin/config/development/performance'),
                '!info' => $item,
            )),
        );
        return $ret;
    }
    $item = menu_get_item($js_path . $filepath . '.js');
    if (empty($item['page_callback']) || strpos($item['page_callback'], 'advagg') === FALSE) {
        $item = str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(htmlentities(print_r($item, TRUE))));
        $ret['advagg_async_generation_menu_issue'] = array(
            'title' => $t('Adv CSS/JS Agg - Async Mode'),
            'severity' => REQUIREMENT_WARNING,
            'value' => $t('Flush your caches'),
            'description' => $t('You need to flush your menu cache. This can be done near the bottom of the <a href="@performance">performance page</a>. If this does not fix the issue copy this info below when opening up an <a href="http://drupal.org/node/add/project-issue/advagg">issue for advagg</a>: <br /> !info', array(
                '@performance' => url('admin/config/development/performance'),
                '!info' => $item,
            )),
        );
        return $ret;
    }
    // Send request and also time it.
    timer_start(__FUNCTION__ . 'local');
    $data_local = drupal_http_request($url, array(
        'headers' => $headers,
    ));
    $time_local = timer_stop(__FUNCTION__ . 'local');
    // Test CDN module; JS & CSS paths.
    if (module_exists('cdn')) {
        // Make sure CDN module is on.
        $status = variable_get(CDN_STATUS_VARIABLE, CDN_DISABLED);
        if (($status == CDN_ENABLED || $status == CDN_TESTING && user_access(CDN_PERM_ACCESS_TESTING)) && !variable_get(CDN_THEME_LAYER_FALLBACK_VARIABLE, FALSE)) {
            global $conf;
            $path_blacklist = variable_get(CDN_EXCEPTION_DRUPAL_PATH_BLACKLIST_VARIABLE, CDN_EXCEPTION_DRUPAL_PATH_BLACKLIST_DEFAULT);
            $conf[CDN_EXCEPTION_DRUPAL_PATH_BLACKLIST_VARIABLE] = '';
            $url_cdn_css = advagg_build_uri($css_path . $filepath . '.css');
            $parts_css = @parse_url($url_cdn_css);
            // Do not test CDN CSS if the hosts are the same.
            if (!empty($parts_css['host']) && strcmp($parts_css['host'], $_SERVER['HTTP_HOST']) == 0) {
                $parts_css = FALSE;
            }
            $url_cdn_js = advagg_build_uri($js_path . $filepath . '.js');
            $parts_js = @parse_url($url_cdn_js);
            // Do not test CDN JS if the hosts are the same.
            if (!empty($parts_js['host']) && strcmp($parts_js['host'], $_SERVER['HTTP_HOST']) == 0) {
                $parts_js = FALSE;
            }
            $conf[CDN_EXCEPTION_DRUPAL_PATH_BLACKLIST_VARIABLE] = $path_blacklist;
            if (!empty($parts_css)) {
                // Send request and also time it.
                timer_start(__FUNCTION__ . 'cdn_css');
                $data_cdn_css = drupal_http_request($url_cdn_css);
                $time_cdn_css = timer_stop(__FUNCTION__ . 'cdn_css');
            }
            if (!empty($parts_js)) {
                // Send request and also time it.
                timer_start(__FUNCTION__ . 'cdn_js');
                $data_cdn_js = drupal_http_request($url_cdn_js);
                $time_cdn_js = timer_stop(__FUNCTION__ . 'cdn_js');
            }
            $mode = variable_get(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
        }
    }
    $readme = drupal_get_path('module', 'advagg') . '/README.txt';
    if (module_exists('cdn')) {
        $cdn_extra = $t('(both fieldsets)');
    }
    else {
        $cdn_extra = '';
    }
    $extra_404 = $t('If you are still having issues you can go to the <a href="@info">AdvAgg information tab</a> and select Asynchronous debug info. If creating an issue on d.o be sure to include this information @cdn_extra.', array(
        '@info' => url('admin/config/advagg/info'),
        '@cdn_extra' => $cdn_extra,
    ));
    $extra_404 .= module_exists('stage_file_proxy') ? $t('<a href="http://drupal.org/project/stage_file_proxy">Stage File Proxy</a> needs <a href="http://drupal.org/node/1078218">this patch</a> applied to it in order for advagg to work correctly.') : '';
    // Check CDN responses.
    $cdn_failed = FALSE;
    if (isset($parts_css) && empty($parts_css)) {
        $ret['advagg_async_generation_css_cdn'] = array(
            'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
            'severity' => REQUIREMENT_WARNING,
            'value' => $t('CSS CDN Issue'),
            'description' => $t('Your current CDN settings are not rewriting the URL for advagg CSS files to point to your CDN. Most likely you need to adjust your <a href="@cdnother">CDN exceptions</a> to allow CSS files from advagg.', array(
                '@cdnother' => url('admin/config/cdn/other'),
            )),
        );
    }
    if (isset($parts_js) && empty($parts_js)) {
        $ret['advagg_async_generation_js_cdn'] = array(
            'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
            'severity' => REQUIREMENT_WARNING,
            'value' => $t('JS CDN Issue'),
            'description' => $t('Your current CDN settings are not rewriting the URL for advagg JS files to point to your CDN. Most likely you need to adjust your <a href="@cdnother">CDN exceptions</a> to allow JS files from advagg.', array(
                '@cdnother' => url('admin/config/cdn/other'),
            )),
        );
    }
    if (isset($data_cdn_css)) {
        if ($data_cdn_css->code != 200 && $mode == CDN_MODE_BASIC && (!empty($data_cdn_css->headers['X-AdvAgg']) || !empty($data_cdn_css->data) && strpos($data_cdn_css->data, '<!-- advagg_missing_fast404 -->') !== FALSE)) {
            $ret['advagg_async_generation_css_cdn'] = array(
                'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('CSS CDN'),
                'description' => $t('Requests through the CDN are getting back to advagg for CSS files.'),
            );
        }
        else {
            $cdn_failed = TRUE;
            $ret['advagg_async_generation_css_cdn'] = array(
                'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('CSS CDN Issue'),
                'description' => $t('Check your <a href="@cdn">CDN settings</a>; CSS request is not coming back when routed through the CDN. ', array(
                    '@cdn' => url('admin/config/cdn'),
                )) . $extra_404,
            );
        }
    }
    if (isset($data_cdn_js)) {
        if ($data_cdn_js->code != 200 && $mode == CDN_MODE_BASIC && (!empty($data_cdn_js->headers['X-AdvAgg']) || !empty($data_cdn_js->data) && strpos($data_cdn_js->data, '<!-- advagg_missing_fast404 -->') !== FALSE)) {
            $ret['advagg_async_generation_js_cdn'] = array(
                'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('JS CDN'),
                'description' => $t('Requests through the CDN are getting back to advagg for JS files.'),
            );
        }
        else {
            $cdn_failed = TRUE;
            $ret['advagg_async_generation_js_cdn'] = array(
                'title' => $t('Adv CSS/JS Agg - CDN Async Mode'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('JS CDN Issue'),
                'description' => $t('Check your <a href="@cdn">CDN settings</a>; JS request is not coming back when routed through the CDN. ', array(
                    '@cdn' => url('admin/config/cdn'),
                )) . $extra_404,
            );
        }
    }
    // Check normal response and set async variable accordingly.
    if ($data_local->code != 200 && (!empty($data_local->headers['X-AdvAgg']) || strpos($data_local->data, '<!-- advagg_missing_fast404 -->') !== FALSE)) {
        // Hook menu works.
        if ($async == -1 && !$cdn_failed) {
            variable_set('advagg_async_generation', TRUE);
            $ret['advagg_async_generation'] = array(
                'title' => $t('Adv CSS/JS Agg - Asynchronous Mode'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('Is now set to TRUE.'),
            );
        }
        if ($async == 0) {
            $ret['advagg_async_generation'] = array(
                'title' => $t('Adv CSS/JS Agg - Asynchronous Mode'),
                'severity' => REQUIREMENT_WARNING,
                'value' => $t('Could be changed to TRUE.'),
            );
        }
        if ($async == 1) {
            $ret['advagg_async_generation'] = array(
                'title' => $t('Adv CSS/JS Agg - Asynchronous Mode'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('Already set to TRUE'),
            );
        }
        if ($cdn_failed) {
            $ret['advagg_async_generation']['description'] = ' ' . $t('Be careful about enabling Asynchronous Mode. Your CDN is not forwarding 404s back to advagg missing file handling functions. There is a chance a user could have a broken experience.');
        }
    }
    else {
        // Set to FALSE if not.
        if ($async != 0) {
            variable_set('advagg_async_generation', FALSE);
        }
        // Files htaccess check. Make sure RewriteEngine is not off.
        $directory = variable_get('file_' . file_default_scheme() . '_path', conf_path() . '/files');
        if (is_file($directory . '/.htaccess')) {
            $file = file_get_contents($directory . '/.htaccess');
            if (stripos($file, "RewriteEngine off") !== FALSE) {
                $ret['advagg_htaccess'] = array(
                    'title' => $t('Adv CSS/JS Agg - Files Dir htaccess'),
                    'severity' => REQUIREMENT_ERROR,
                    'value' => $t('The htaccess file in %dir is non standard.', array(
                        '%dir' => $directory,
                    )),
                    'description' => $t('You need to modify your htaccess file in your files directory. See <a href="@url">this link</a> for more info.', array(
                        '@url' => 'http://drupal.org/node/1171244#comment-4770544',
                    )),
                );
            }
        }
        // Build error message.
        if (empty($ret['advagg_htaccess'])) {
            $ret['advagg_async_generation'] = array(
                'title' => $t('Adv CSS/JS Agg - Asynchronous Mode'),
                'severity' => REQUIREMENT_ERROR,
                'value' => $t('Set to FALSE.'),
                'description' => $t('Check to see if you have fast 404s, if so create an exception for this module. The <a href="@readme">readme file</a> explains what needs to be changed. You can try flushing the menu cache as well. ', array(
                    '@readme' => url($readme),
                )) . $extra_404,
            );
        }
    }
    // Set socket timeout relative to local round trip.
    $timeout = variable_get('advagg_socket_timeout', -1);
    $new_time = ceil(($time_local['time'] + 51) / 1000);
    if ($async) {
        if ($timeout == -1 || $timeout != $new_time) {
            variable_set('advagg_socket_timeout', $new_time);
            $ret['advagg_socket_timeout'] = array(
                'title' => $t('Adv CSS/JS Agg - Socket Timeout'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('Set to %time seconds. Raw timer: %raw', array(
                    '%time' => $new_time,
                    '%raw' => $time_local['time'],
                )),
            );
        }
        else {
            $ret['advagg_socket_timeout'] = array(
                'title' => $t('Adv CSS/JS Agg - Socket Timeout'),
                'severity' => REQUIREMENT_OK,
                'value' => $t('Already set to %time seconds. Raw timer: %raw', array(
                    '%time' => $new_time,
                    '%raw' => $time_local['time'],
                )),
            );
        }
    }
    return $ret;
}

/**
 * Test if STREAM_CLIENT_ASYNC_CONNECT can be used.
 */
function advagg_install_test_async_stream() {
    global $conf, $base_path;
    if (!function_exists('stream_socket_client') || !function_exists('stream_select')) {
        return FALSE;
    }
    $advagg_async_socket_connect = variable_get('advagg_async_socket_connect', ADVAGG_ASYNC_SOCKET_CONNECT);
    // Build test request.
    $url = _advagg_build_url();
    $headers = array(
        'Host' => $_SERVER['HTTP_HOST'],
        'Connection' => 'close',
    );
    // Request file.
    $conf['advagg_async_socket_connect'] = TRUE;
    advagg_async_connect_http_request($url, array(
        'headers' => $headers,
    ));
    // Send Request off.
    $good = advagg_async_send_http_request();
    if ($good && !$advagg_async_socket_connect) {
        variable_set('advagg_async_socket_connect', TRUE);
        return TRUE;
    }
    else {
        $conf['advagg_async_socket_connect'] = FALSE;
    }
}

/**
 * Implements hook_schema().
 */
function advagg_schema() {
    // Create cache tables.
    $schema['cache_advagg'] = drupal_get_schema_unprocessed('system', 'cache');
    $schema['cache_advagg']['description'] = t('Cache table for Advanced CSS/JS Aggregation. Used to keep timestamps and if the file exists.');
    $schema['cache_advagg_files_data'] = drupal_get_schema_unprocessed('system', 'cache');
    $schema['cache_advagg_files_data']['description'] = t('Cache table for Advanced CSS/JS Aggregation. Used to keep data about files.');
    $schema['cache_advagg_bundle_reuse'] = drupal_get_schema_unprocessed('system', 'cache');
    $schema['cache_advagg_bundle_reuse']['description'] = t('Cache table for Advanced CSS/JS Aggregation. Used to keep data about existing bundles that can be reused.');
    // Create database tables.
    $schema['advagg_files'] = array(
        'description' => 'Files used in CSS/JS aggregation.',
        'fields' => array(
            'filename' => array(
                'description' => 'Path of the file relative to Drupal webroot.',
                'type' => 'text',
                'size' => 'normal',
                'not null' => TRUE,
            ),
            'filename_md5' => array(
                'description' => 'MD5 hash of filename',
                'type' => 'varchar',
                'length' => 32,
                'not null' => TRUE,
                'default' => '',
            ),
            'checksum' => array(
                'description' => 'mtime or md5 of the files content.',
                'type' => 'varchar',
                'length' => 32,
                'not null' => TRUE,
                'default' => '',
            ),
            'filetype' => array(
                'description' => 'Filetype.',
                'type' => 'varchar',
                'length' => 8,
                'not null' => TRUE,
                'default' => '',
            ),
            'filesize' => array(
                'description' => 'The file size in bytes.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
            'counter' => array(
                'description' => 'This is incremented every time a file changes.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
        ),
        'indexes' => array(
            'checksum' => array(
                'checksum',
            ),
            'filetype' => array(
                'filetype',
            ),
            'filesize' => array(
                'filesize',
            ),
        ),
        'primary key' => array(
            'filename_md5',
        ),
    );
    $schema['advagg_bundles'] = array(
        'description' => 'What files are used in what bundles.',
        'fields' => array(
            'bundle_md5' => array(
                'description' => 'MD5 hash of the bundles list of files',
                'type' => 'varchar',
                'length' => 32,
                'not null' => TRUE,
                'default' => '',
            ),
            'filename_md5' => array(
                'description' => 'MD5 hash of filename source',
                'type' => 'varchar',
                'length' => 32,
                'not null' => TRUE,
                'default' => '',
            ),
            'counter' => array(
                'description' => 'This is incremented every time a file in the bundle changes.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
            'porder' => array(
                'description' => 'Processing order.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
            'root' => array(
                'description' => 'If 1 then it is a root file. 0 means not root file.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
            'timestamp' => array(
                'description' => 'Last used timestamp of the bundle.',
                'type' => 'int',
                'not null' => TRUE,
                'default' => 0,
            ),
        ),
        'indexes' => array(
            'root' => array(
                'root',
            ),
            'timestamp' => array(
                'timestamp',
            ),
            'counter' => array(
                'counter',
            ),
            'root_timestamp' => array(
                'root',
                'timestamp',
            ),
        ),
        'primary key' => array(
            'bundle_md5',
            'filename_md5',
        ),
    );
    return $schema;
}

/**
*
* Upgrades Advanced Aggregation from Drupal 6 to Drupal 7
*
*/
function advagg_update_7000(&$sandbox) {
    $variables = array(
        'advagg_checksum_mode' => array(
            'mtime' => 'filemtime',
        ),
    );
    foreach ($variables as $name => $values) {
        foreach ($values as $old => $new) {
            $variable = variable_get($name, $old);
            if ($variable === $old) {
                variable_set($name, $new);
            }
        }
    }
    return t('Upgraded Advanced Aggregation from Drupal 6 to Drupal 7.');
}

Functions

Title Deprecated Summary
advagg_check_missing_handler Check to see if the CSS/JS generator is working.
advagg_disable Implements hook_disable().
advagg_enable Implements hook_enable().
advagg_install Implements hook_install().
advagg_install_test_async_stream Test if STREAM_CLIENT_ASYNC_CONNECT can be used.
advagg_install_theme_registry_location @todo Please document this function.
advagg_requirements Implements hook_requirements().
advagg_schema Implements hook_schema().
advagg_uninstall Implements hook_uninstall().
advagg_update_7000 Upgrades Advanced Aggregation from Drupal 6 to Drupal 7