729 lines
27 KiB
PHP
729 lines
27 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Admin page callbacks for the advanced CSS/JS aggregation module.
|
|
*/
|
|
|
|
/**
|
|
* Page generation function for admin/settings/advagg
|
|
*/
|
|
function advagg_admin_page() {
|
|
$output = '';
|
|
$file_path = drupal_get_path('module', 'advagg');
|
|
drupal_add_js(array('advagg' => array('key' => md5(drupal_get_private_key()))), 'setting');
|
|
drupal_add_js($file_path . '/advagg.admin.js');
|
|
|
|
$output .= drupal_get_form('advagg_admin_settings_form');
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Page generation function for admin/settings/advagg/info
|
|
*/
|
|
function advagg_admin_info_page() {
|
|
$output = '';
|
|
return $output . drupal_get_form('advagg_admin_info_form');
|
|
}
|
|
|
|
/**
|
|
* Form builder; Configure advagg settings.
|
|
*
|
|
* @ingroup forms
|
|
* @see system_settings_form()
|
|
*/
|
|
function advagg_admin_info_form() {
|
|
$form = array();
|
|
|
|
$form['info'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Hook Theme Info'),
|
|
);
|
|
init_theme();
|
|
$hooks = theme_get_registry();
|
|
$data = implode("\n", $hooks['page']['preprocess functions']);
|
|
$form['info']['advagg_debug_info'] = array(
|
|
'#type' => 'textarea',
|
|
'#default_value' => $data,
|
|
'#rows' => count($hooks['page']['preprocess functions']) + 1,
|
|
);
|
|
|
|
$types = db_query("SELECT DISTINCT(filetype) FROM {advagg_files}");
|
|
while ($type = db_result($types)) {
|
|
$form[$type] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('@type files', array('@type' => drupal_strtoupper($type))),
|
|
);
|
|
// filename filename_md5 checksum filetype counter data
|
|
$results = db_query("SELECT * FROM {advagg_files} WHERE filetype = '%s'", $type);
|
|
while ($row = db_fetch_array($results)) {
|
|
$data = advagg_get_file_data($row['filename_md5']);
|
|
if (!empty($data)) {
|
|
list($data, $rows) = advagg_form_print_r($data);
|
|
|
|
$form[$type][$row['filename_md5']] = array(
|
|
'#type' => 'textarea',
|
|
'#title' => check_plain($row['filename']),
|
|
'#default_value' => $data,
|
|
'#rows' => $rows -1,
|
|
'#description' => t('File has changed %counter times', array('%counter' => $row['counter'])),
|
|
);
|
|
}
|
|
else {
|
|
$form[$type][$row['filename_md5']] = array(
|
|
'#type' => 'markup',
|
|
'#value' => '<div>' . format_plural($row['counter'], 'changed 1 time - %file<br />', 'changed %counter times - %file<br /></div>', array(
|
|
'%counter' => $row['counter'],
|
|
'%file' => $row['filename'],
|
|
)),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get hooks in use.
|
|
$hooks = array(
|
|
'advagg_css_alter' => array(),
|
|
'advagg_css_inline_alter' => array(),
|
|
'advagg_css_pre_alter' => array(),
|
|
'advagg_css_extra_alter' => array(),
|
|
'advagg_js_alter' => array(),
|
|
'advagg_js_inline_alter' => array(),
|
|
'advagg_js_pre_alter' => array(),
|
|
'advagg_js_extra_alter' => array(),
|
|
'advagg_js_header_footer_alter' => array(),
|
|
'advagg_filenames_alter' => array(),
|
|
'advagg_files_table' => array(),
|
|
'advagg_master_reset' => array(),
|
|
'advagg_disable_processor' => array(),
|
|
'advagg_disable_page_cache' => array(),
|
|
'advagg_bundler_analysis_alter' => array(),
|
|
);
|
|
foreach ($hooks as $hook => $values) {
|
|
$hooks[$hook] = module_implements($hook);
|
|
}
|
|
// Record function overrides. Not working currently.
|
|
// $hooks['advagg_css_render_function'] = array(variable_get('advagg_css_render_function', ADVAGG_CSS_RENDER_FUNCTION));
|
|
// $hooks['advagg_js_render_function'] = array(variable_get('advagg_js_render_function', ADVAGG_JS_RENDER_FUNCTION));
|
|
// $hooks['advagg_file_save_function'] = array(variable_get('advagg_file_save_function', ADVAGG_FILE_SAVE_FUNCTION));
|
|
|
|
// Output hooks in form.
|
|
foreach ($hooks as $hook => $values) {
|
|
if (empty($values)) {
|
|
$form['hooks_implemented'][$hook] = array(
|
|
'#type' => 'markup',
|
|
'#value' => '<div><strong>' . check_plain($hook) . ':</strong><br /> ' . t('None') . '</div>',
|
|
);
|
|
}
|
|
else {
|
|
$form['hooks_implemented'][$hook] = array(
|
|
'#type' => 'markup',
|
|
'#value' => '<div><strong>' . check_plain($hook) . ':</strong><br /> ' . filter_xss(implode('<br /> ', $values)) . '</div>',
|
|
);
|
|
}
|
|
}
|
|
$form['hooks_implemented'] += array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Modules implementing advagg hooks'),
|
|
);
|
|
|
|
// If any files are missing list them.
|
|
// TODO: Reset missing files list.
|
|
$results = db_query("SELECT * FROM {advagg_files} WHERE checksum = '-1' ORDER BY filetype ASC");
|
|
while ($row = db_fetch_array($results)) {
|
|
$form['missing'][$row['filename_md5']] = array(
|
|
'#type' => 'markup',
|
|
'#value' => '<div>' . check_plain($row['filename']) . '<br /></div>',
|
|
);
|
|
}
|
|
if (!empty($form['missing'])) {
|
|
$form['missing'] += array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => FALSE,
|
|
'#title' => t('Missing files'),
|
|
);
|
|
}
|
|
|
|
// Asynchronous raw output
|
|
$form['async'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Asynchronous debug info'),
|
|
);
|
|
|
|
list($css_path, $js_path) = advagg_get_root_files_dir();
|
|
|
|
$filepath = $css_path . '/css_missing' . mt_rand() . time() . '_0.css';
|
|
$url = _advagg_build_url($filepath);
|
|
$htauth_user = variable_get('advagg_async_test_username', '');
|
|
$htauth_pass = variable_get('advagg_async_test_password', '');
|
|
$headers = array(
|
|
'Host' => $_SERVER['HTTP_HOST'],
|
|
'Connection' => 'close',
|
|
);
|
|
if ($htauth_user && $htauth_pass) {
|
|
$headers['Authorization'] = 'Basic ' . base64_encode($htauth_user . ':' . $htauth_pass);
|
|
}
|
|
|
|
timer_start(__FUNCTION__ . 'local');
|
|
$data_local = drupal_http_request($url, $headers);
|
|
$data_local->timer = timer_stop(__FUNCTION__ . 'local');
|
|
list($data, $rows) = advagg_form_print_r($data_local);
|
|
$form['async']['normal'] = array(
|
|
'#type' => 'textarea',
|
|
'#title' => check_plain($url),
|
|
'#default_value' => $data,
|
|
'#rows' => min($rows + 1, 50),
|
|
);
|
|
|
|
if (module_exists('cdn')) {
|
|
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 = advagg_build_uri($filepath);
|
|
|
|
$conf[CDN_EXCEPTION_DRUPAL_PATH_BLACKLIST_VARIABLE] = $path_blacklist;
|
|
// Send request and also time it.
|
|
timer_start(__FUNCTION__ . 'cdn');
|
|
$data_cdn = drupal_http_request($url_cdn);
|
|
$data_cdn->timer = timer_stop(__FUNCTION__ . 'cdn');
|
|
list($data, $rows) = advagg_form_print_r($data_cdn);
|
|
$form['async']['cdn'] = array(
|
|
'#type' => 'textarea',
|
|
'#title' => check_plain($url_cdn),
|
|
'#default_value' => $data,
|
|
'#rows' => min($rows + 1, 50),
|
|
);
|
|
}
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Form builder; Configure advagg settings.
|
|
*
|
|
* @ingroup forms
|
|
* @see system_settings_form()
|
|
*/
|
|
function advagg_admin_settings_form() {
|
|
$form = array();
|
|
$bundle_count = db_result(db_query("SELECT COUNT(*) FROM (SELECT bundle_md5 FROM {advagg_bundles} GROUP BY bundle_md5) as temp"));
|
|
|
|
$form['advagg_enabled'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Enable Advanced Aggregation'),
|
|
'#default_value' => variable_get('advagg_enabled', ADVAGG_ENABLED),
|
|
);
|
|
$form['advagg_closure'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Use AdvAgg in closure'),
|
|
'#default_value' => variable_get('advagg_closure', ADVAGG_CLOSURE),
|
|
'#description' => t('If enabled javascript files in the closure region will be aggregated.'),
|
|
);
|
|
// Make sure the advagg_check_missing_handler function is available.
|
|
module_load_install('advagg');
|
|
$ret = advagg_check_missing_handler();
|
|
$form['advagg_async_generation'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Generate CSS/JS files on request (async mode)'),
|
|
'#default_value' => variable_get('advagg_async_generation', ADVAGG_ASYNC_GENERATION),
|
|
'#disabled' => $ret['advagg_async_generation']['severity'] == REQUIREMENT_ERROR ? TRUE : FALSE,
|
|
'#description' => t('Current State: !value', array(
|
|
'!value' => filter_xss(' '
|
|
. $ret['advagg_async_generation']['value'] . ' '
|
|
. (!empty($ret['advagg_async_generation']['description']) ? $ret['advagg_async_generation']['description'] : '') . ' '
|
|
),
|
|
)),
|
|
);
|
|
$form['advagg_async_test'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Async Test HTTP Basic Credentials'),
|
|
'#collapsed' => TRUE,
|
|
'#collapsible' => TRUE,
|
|
);
|
|
$form['advagg_async_test']['advagg_async_test_username'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('Username'),
|
|
'#default_value' => variable_get('advagg_async_test_username', ''),
|
|
);
|
|
$form['advagg_async_test']['advagg_async_test_password'] = array(
|
|
'#type' => 'password',
|
|
'#title' => t('Password'),
|
|
);
|
|
$form['advagg_gzip_compression'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Gzip CSS/JS files'),
|
|
'#default_value' => variable_get('advagg_gzip_compression', ADVAGG_GZIP_COMPRESSION),
|
|
'#description' => t('This might break CSS/JS handling at the Apache level. If it does, use the rules for your webroot level htaccess file before re-enabling. In short, be sure to test this out.'),
|
|
);
|
|
$form['advagg_dir_htaccess'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Generate .htaccess files in the advagg_* dirs'),
|
|
'#default_value' => variable_get('advagg_dir_htaccess', ADVAGG_DIR_HTACCESS),
|
|
'#description' => t('Disable if you are using the documented rules in your webroot level htaccess file.'),
|
|
);
|
|
$form['advagg_rebuild_on_flush'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Regenerate flushed bundles in the cache flush request'),
|
|
'#default_value' => variable_get('advagg_rebuild_on_flush', ADVAGG_REBUILD_ON_FLUSH),
|
|
'#description' => t('You can enable if your server will not timeout on a request. This will call advagg_rebuild_bundle() as a <a href="http://php.net/register-shutdown-function">shutdown function</a> for every bundle that has been marked as expired; thus rebuilding that bundle in the same request as the flush.'),
|
|
);
|
|
$public_downloads = (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);
|
|
if (!$public_downloads) {
|
|
$extra = module_exists('boost') ? t('If boost is installed, you can use the cache directory for advagg files.') : '';
|
|
$form['advagg_custom_files_dir'] = array(
|
|
'#type' => 'textfield',
|
|
'#field_prefix' => '<div>' . t('You are using a private file system. You must serve aggregated files via a public folder.') . '</div>',
|
|
'#title' => t('Use a different directory for storing advagg files'),
|
|
'#default_value' => variable_get('advagg_custom_files_dir', ADVAGG_CUSTOM_FILES_DIR),
|
|
'#description' => check_plain(t('You need to create a publicly writable directory (same permissions as Drupals files folder) and it needs to be relative to the Drupal index.php file.') . ' ' . $extra . ' ' . t('If you do not need this, you can put a space in this box.')),
|
|
'#required' => TRUE,
|
|
);
|
|
}
|
|
$options = array(
|
|
0 => t('Wait for locks'),
|
|
1 => t('Do not wait for locks'),
|
|
2 => t('Only serve aggregated files if they are already built (only works if async is enabled)'),
|
|
);
|
|
$form['advagg_aggregate_mode'] = array(
|
|
'#type' => 'radios',
|
|
'#title' => t('Aggregation Inclusion Mode'),
|
|
'#default_value' => variable_get('advagg_aggregate_mode', ADVAGG_AGGREGATE_MODE),
|
|
'#options' => $options,
|
|
'#description' => t('Should the page wait for the aggregate to be built before including the file, or should it send out the page with aggregates not included.'),
|
|
);
|
|
$form['advagg_page_cache_mode'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Disable page caching if all aggregates are not included on the page.'),
|
|
'#default_value' => variable_get('advagg_page_cache_mode', ADVAGG_PAGE_CACHE_MODE),
|
|
);
|
|
$form['advagg_checksum_mode'] = array(
|
|
'#type' => 'radios',
|
|
'#title' => t('File Checksum Mode'),
|
|
'#default_value' => variable_get('advagg_checksum_mode', ADVAGG_CHECKSUM_MODE),
|
|
'#options' => array(
|
|
'mtime' => 'mtime',
|
|
'md5' => 'md5',
|
|
),
|
|
'#description' => t('If Drupal is on multiple servers and the file system is not shared; using md5 is recommended. The file modification time (mtime) could be different with this type of setup. WARNING: Changing this value will invalidate all bundles and new ones will have to be built.'),
|
|
);
|
|
$form['advagg_server_addr'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('IP Address to send all asynchronous requests to'),
|
|
'#default_value' => variable_get('advagg_server_addr', FALSE),
|
|
'#description' => t('If left blank it will use the same server as the request. If set to -1 it will use the host name instead of an IP address.'),
|
|
);
|
|
// $form['advagg_debug'] = array(
|
|
// '#type' => 'checkbox',
|
|
// '#title' => t('Debug to watchdog.'),
|
|
// '#default_value' => variable_get('advagg_debug', ADVAGG_DEBUG),
|
|
// );
|
|
|
|
$form['flush'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Smart cache flush'),
|
|
'#description' => t('Scan all files referenced in aggregated files. If any of them have changed, increment the counters containing that file and rebuild the bundle.'),
|
|
);
|
|
$form['flush']['advagg_flush'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Flush AdvAgg Cache'),
|
|
'#submit' => array('advagg_admin_flush_cache_button'),
|
|
);
|
|
$form['rebuild'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Cache Rebuild'),
|
|
'#description' => t('Recreate all aggregated files. Useful if JS or CSS compression was just enabled. %count Files', array('%count' => $bundle_count)),
|
|
);
|
|
$form['rebuild']['advagg_rebuild'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Rebuild AdvAgg Cache'),
|
|
'#submit' => array('advagg_admin_batch_rebuild'),
|
|
);
|
|
$form['forced_rebuild'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Forced Cache Rebuild'),
|
|
'#description' => t('Recreate all aggregated files by incrementing internal counter for every bundle. %count Files', array('%count' => $bundle_count)),
|
|
);
|
|
$form['forced_rebuild']['advagg_forced_build'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Force all counters to be increment by one'),
|
|
'#submit' => array('advagg_admin_batch_rebuild'),
|
|
);
|
|
$form['master_reset'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Master Reset'),
|
|
'#description' => t('Clean Slate - Truncate all advagg tables and delete all advagg files. Useful for testing purposes. Running this on a production site is not a good idea.'),
|
|
);
|
|
$form['master_reset']['advagg_reset'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Master Reset'),
|
|
'#submit' => array('advagg_admin_master_reset'),
|
|
);
|
|
$form['htaccess'] = array(
|
|
'#type' => 'fieldset',
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => TRUE,
|
|
'#title' => t('Rebuild htaccess files'),
|
|
'#description' => t('This will recreate the htaccess files located in the advagg_* directories.'),
|
|
);
|
|
$form['htaccess']['advagg_recreate_htaccess'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Recreate htaccess files'),
|
|
'#submit' => array('advagg_admin_recreate_htaccess'),
|
|
);
|
|
$form['bypass'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Aggregation Bypass Cookie'),
|
|
'#description' => t('This will set or remove a cookie that disables aggregation for the remainder of the browser session.'),
|
|
);
|
|
$form['bypass']['submit'] = array(
|
|
'#type' => 'submit',
|
|
#'#button_type' => 'button',
|
|
'#value' => t('Toggle the "aggregation bypass cookie" for this browser'),
|
|
'#attributes' => array('onclick' => 'javascript:return advagg_toggle_cookie()'),
|
|
'#submit' => array('advagg_admin_toggle_bypass_cookie'),
|
|
);
|
|
|
|
$form['#submit'][] = 'advagg_admin_settings_form_submit';
|
|
return system_settings_form($form);
|
|
}
|
|
|
|
/**
|
|
* Validate form values. Used to unset variables before they get saved.
|
|
*/
|
|
function advagg_admin_settings_form_validate($form, &$form_state) {
|
|
global $conf;
|
|
|
|
// Custom directory handling.
|
|
if (!empty($form_state['values']['advagg_custom_files_dir'])) {
|
|
$form_state['values']['advagg_custom_files_dir'] = trim($form_state['values']['advagg_custom_files_dir']);
|
|
$files_dir = $form_state['values']['advagg_custom_files_dir'];
|
|
if (!empty($files_dir) && $files_dir != $conf['advagg_custom_files_dir']) {
|
|
|
|
// Try to create dir structure.
|
|
$cumulative = '';
|
|
$path_array = explode('/', $files_dir);
|
|
foreach ($path_array as $dir) {
|
|
if (empty($cumulative)) {
|
|
$cumulative = $dir;
|
|
}
|
|
else {
|
|
$cumulative .= '/' . $dir;
|
|
}
|
|
// If dir creation fails, bail out of loop.
|
|
if (!file_check_directory($cumulative, FILE_CREATE_DIRECTORY)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// See if dir exists and is writable.
|
|
if (file_check_directory($files_dir) == TRUE) {
|
|
|
|
// Remove old files.
|
|
list($css_path, $js_path) = advagg_get_root_files_dir();
|
|
file_scan_directory($css_path, '.*', array('.', '..', 'CVS'), 'file_delete', TRUE);
|
|
@unlink($css_path);
|
|
file_scan_directory($js_path, '.*', array('.', '..', 'CVS'), 'file_delete', TRUE);
|
|
@unlink($js_path);
|
|
|
|
// Set new path.
|
|
$conf['advagg_custom_files_dir'] = $files_dir;
|
|
advagg_get_root_files_dir(TRUE);
|
|
menu_rebuild();
|
|
}
|
|
else {
|
|
form_set_error('advagg_custom_files_dir', t('%dir is not a directory or is not writable by the web server.', array('%dir' => $files_dir)));
|
|
}
|
|
}
|
|
}
|
|
|
|
// If the IP field is not blank, check that its a valid address.
|
|
if (!empty($form_state['values']['advagg_server_addr']) && $form_state['values']['advagg_server_addr'] != -1 && ip2long($form_state['values']['advagg_server_addr']) === FALSE) {
|
|
form_set_error('advagg_server_addr', t('Must be a valid IP address.'));
|
|
}
|
|
|
|
// Remove non variable form info.
|
|
unset($form_state['values']['advagg_flush']);
|
|
unset($form_state['values']['advagg_rebuild']);
|
|
unset($form_state['values']['advagg_forced_build']);
|
|
unset($form_state['values']['advagg_recreate_htaccess']);
|
|
unset($form_state['values']['advagg_reset']);
|
|
}
|
|
|
|
/**
|
|
* Validate form values. Used to unset variables before they get saved.
|
|
*/
|
|
function advagg_admin_settings_form_submit($form, &$form_state) {
|
|
global $conf;
|
|
|
|
// Pull the old password if it wasn't changed by the user.
|
|
if (!empty($form_state['values']['advagg_async_test_username']) && empty($form_state['values']['advagg_async_test_password'])) {
|
|
$form_state['values']['advagg_async_test_password'] = variable_get('advagg_async_test_password', '');
|
|
}
|
|
|
|
// Gzip & htaccess checks.
|
|
list($css_path, $js_path) = advagg_get_root_files_dir();
|
|
$css_path .= '/.htaccess';
|
|
$js_path .= '/.htaccess';
|
|
|
|
if ($conf['advagg_gzip_compression'] != $form_state['values']['advagg_gzip_compression'] && $form_state['values']['advagg_dir_htaccess']) {
|
|
$conf['advagg_gzip_compression'] = $form_state['values']['advagg_gzip_compression'];
|
|
$conf['advagg_dir_htaccess'] = $form_state['values']['advagg_dir_htaccess'];
|
|
advagg_admin_recreate_htaccess();
|
|
}
|
|
if ($form_state['values']['advagg_dir_htaccess'] == FALSE) {
|
|
$conf['advagg_dir_htaccess'] = FALSE;
|
|
advagg_clearstatcache(TRUE, $css_path);
|
|
advagg_clearstatcache(TRUE, $js_path);
|
|
if (file_exists($css_path) || file_exists($js_path)) {
|
|
file_delete($css_path);
|
|
file_delete($js_path);
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation directory level htaccess files have been removed.'));
|
|
}
|
|
}
|
|
elseif ($conf['advagg_dir_htaccess'] != $form_state['values']['advagg_dir_htaccess']) {
|
|
$conf['advagg_dir_htaccess'] = $form_state['values']['advagg_dir_htaccess'];
|
|
advagg_admin_recreate_htaccess();
|
|
}
|
|
advagg_clearstatcache(TRUE, $css_path);
|
|
advagg_clearstatcache(TRUE, $js_path);
|
|
if ($conf['advagg_dir_htaccess'] && (!file_exists($css_path) || !file_exists($js_path))) {
|
|
advagg_admin_recreate_htaccess();
|
|
}
|
|
|
|
// If checksum mode changed, smart flush cache with new checksum mode selected.
|
|
if ($conf['advagg_checksum_mode'] != $form_state['values']['advagg_checksum_mode']) {
|
|
$conf['advagg_checksum_mode'] = $form_state['values']['advagg_checksum_mode'];
|
|
advagg_admin_flush_cache_button();
|
|
}
|
|
|
|
// If advagg is enabled/disabled, smart flush the cache.
|
|
if ($conf['advagg_enabled'] != $form_state['values']['advagg_enabled']) {
|
|
advagg_admin_flush_cache_button();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Master reset button.
|
|
*/
|
|
function advagg_admin_master_reset() {
|
|
cache_clear_all('*', 'cache_advagg', TRUE);
|
|
cache_clear_all('*', 'cache_advagg_files_data', TRUE);
|
|
cache_clear_all('*', 'cache_advagg_bundle_reuse', TRUE);
|
|
db_query("TRUNCATE TABLE {advagg_files}");
|
|
db_query("TRUNCATE TABLE {advagg_bundles}");
|
|
|
|
module_invoke_all('advagg_master_reset');
|
|
|
|
list($css_path, $js_path) = advagg_get_root_files_dir();
|
|
file_scan_directory($css_path, '.*', array('.', '..', 'CVS'), 'file_delete', TRUE);
|
|
file_scan_directory($js_path, '.*', array('.', '..', 'CVS'), 'file_delete', TRUE);
|
|
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation has been reset.'));
|
|
}
|
|
|
|
/**
|
|
* Cache clear button.
|
|
*/
|
|
function advagg_admin_flush_cache_button() {
|
|
global $_advagg;
|
|
_drupal_flush_css_js();
|
|
$cache_tables = advagg_flush_caches();
|
|
foreach ($cache_tables as $table) {
|
|
cache_clear_all('*', $table, TRUE);
|
|
}
|
|
|
|
if (empty($_advagg['files'])) {
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation cache scanned and no out of date bundles detected.'));
|
|
}
|
|
else {
|
|
if (empty($_advagg['rebuilt'])) {
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation cache scanned and out of date bundles have been marked. <br />Old Files: <br />!files <br />Marked Bundles Count: %count', array(
|
|
'!files' => nl2br(filter_xss(implode("\n", $_advagg['files']))),
|
|
'%count' => count($_advagg['bundles']),
|
|
)
|
|
));
|
|
}
|
|
else {
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation cache scanned and out of date bundles have been incremented and rebuilt. <br />Old Files: <br />%files <br />%count done.', array(
|
|
'%files' => implode('<br />', $_advagg['files']),
|
|
'%count' => count($_advagg['rebuilt']),
|
|
)
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cache clear callback for admin_menu/flush-cache/advagg.
|
|
*/
|
|
function advagg_admin_flush_cache() {
|
|
advagg_admin_flush_cache_button();
|
|
drupal_goto();
|
|
}
|
|
|
|
/**
|
|
* Set up batch for first and last name loading.
|
|
*
|
|
* This is where Drupal's Batch API comes into play.
|
|
* It's as simple as defining $batch, and then calling batch_set($batch)
|
|
*/
|
|
function advagg_admin_batch_rebuild($form, &$form_state) {
|
|
$batch = array();
|
|
|
|
// Set up the type of batch operation we will do.
|
|
if ($form_state['clicked_button']['#post']['op'] == t('Force all counters to be increment by one')) {
|
|
$increment = TRUE;
|
|
$batch['title'] = t('Increment and rebuild aggregated files');
|
|
|
|
}
|
|
else {
|
|
$increment = FALSE;
|
|
$batch['title'] = t('Rebuilding aggregated files');
|
|
}
|
|
|
|
// Build batch operational data.
|
|
$batch += array(
|
|
'operations' => array(
|
|
array('advagg_admin_rebuild_bundles', array($increment)),
|
|
),
|
|
'finished' => 'advagg_admin_rebuild_bundles_done',
|
|
'init_message' => t('Initializing...'),
|
|
'progress_message' => t('@current of @total batch operations done.'),
|
|
'error_message' => t('Rebuilding aggregated files encountered an error.'),
|
|
'file' => drupal_get_path('module', 'advagg') . '/advagg.admin.inc',
|
|
);
|
|
|
|
// Run it
|
|
batch_set($batch);
|
|
batch_process('admin/settings/advagg');
|
|
}
|
|
|
|
/**
|
|
* Rebuild bundles.
|
|
*/
|
|
function advagg_admin_rebuild_bundles($increment, &$context) {
|
|
// init batch.
|
|
if (!isset($context['sandbox']['progress'])) {
|
|
$context['sandbox']['progress'] = 0;
|
|
$context['sandbox']['max'] = db_result(db_query("SELECT COUNT(*) FROM (SELECT bundle_md5 FROM {advagg_bundles} GROUP BY bundle_md5) as temp"));
|
|
|
|
// Increment All Counters.
|
|
if ($increment) {
|
|
db_query("UPDATE {advagg_bundles} SET counter = counter + 1");
|
|
}
|
|
}
|
|
|
|
// Set limit.
|
|
$limit = 1;
|
|
|
|
// Get list of all bundles.
|
|
$result = db_query_range("SELECT bundle_md5 FROM {advagg_bundles} GROUP BY bundle_md5", $context['sandbox']['progress'], $limit);
|
|
while ($bundle_md5 = db_result($result)) {
|
|
$filenames = advagg_rebuild_bundle($bundle_md5, '', TRUE);
|
|
$filename = array();
|
|
foreach ($filenames as $name => $data) {
|
|
$filename[] = $name;
|
|
}
|
|
|
|
// Update our progress information.
|
|
$context['sandbox']['progress']++;
|
|
$context['message'] = t('%md5 Created', array('%md5' => $bundle_md5));
|
|
$context['results'][] = $filename;
|
|
}
|
|
|
|
// Inform the batch engine that we are not finished,
|
|
// and provide an estimation of the completion level we reached.
|
|
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
|
|
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
|
|
}
|
|
}
|
|
|
|
function advagg_admin_rebuild_bundles_done($success, $results, $operations) {
|
|
if ($success) {
|
|
// Here we do something meaningful with the results.
|
|
$message = count($results) . ' files generated.';
|
|
$message .= theme('item_list', $results);
|
|
}
|
|
else {
|
|
// An error occurred.
|
|
// $operations contains the operations that remained unprocessed.
|
|
$error_operation = reset($operations);
|
|
$message = t('An error occurred while processing %error_operation with arguments: @arguments', array('%error_operation' => $error_operation[0], '@arguments' => print_r($error_operation[1], TRUE)));
|
|
}
|
|
drupal_set_message($message);
|
|
}
|
|
|
|
/**
|
|
* Rebuild htaccess files.
|
|
*/
|
|
function advagg_admin_recreate_htaccess() {
|
|
list($css_path, $js_path) = advagg_get_root_files_dir();
|
|
$css_path .= '/.htaccess';
|
|
$js_path .= '/.htaccess';
|
|
|
|
file_delete($css_path);
|
|
advagg_htaccess_check_generate($css_path, TRUE);
|
|
|
|
file_delete($js_path);
|
|
advagg_htaccess_check_generate($js_path, TRUE);
|
|
|
|
drupal_set_message(t('Advanced CSS/JS Aggregation htaccess files rebuilt.'));
|
|
}
|
|
|
|
/**
|
|
* Set or remove the AdvAggDisabled cookie.
|
|
*/
|
|
function advagg_admin_toggle_bypass_cookie() {
|
|
global $base_path;
|
|
$cookie_name = 'AdvAggDisabled';
|
|
$key = md5(drupal_get_private_key());
|
|
|
|
// If the cookie does exist then remove it.
|
|
if (!empty($_COOKIE[$cookie_name]) && $_COOKIE[$cookie_name] == $key) {
|
|
setcookie($cookie_name, '', -1, $base_path, '.' . $_SERVER['HTTP_HOST']);
|
|
unset($_COOKIE[$cookie_name]);
|
|
drupal_set_message(t('AdvAgg Bypass Cookie Removed.'));
|
|
}
|
|
// If the cookie does not exist then set it.
|
|
else {
|
|
setcookie($cookie_name, $key, 0, $base_path, '.' . $_SERVER['HTTP_HOST']);
|
|
$_COOKIE[$cookie_name] = $key;
|
|
drupal_set_message(t('AdvAgg Bypass Cookie Set.'));
|
|
}
|
|
}
|
|
|
|
function advagg_form_print_r($data) {
|
|
$data = print_r($data, TRUE);
|
|
$data = explode("\n", $data);
|
|
$new_data = '';
|
|
foreach ($data as $text) {
|
|
$new_text = str_replace(' ', '', $text);
|
|
if ($new_text == "(") {
|
|
$new_data .= ' ' . $new_text;
|
|
}
|
|
else {
|
|
$new_data .= "\n" . $text;
|
|
}
|
|
}
|
|
$new_data = explode("\n", $new_data);
|
|
$new_data = array_filter($new_data);
|
|
$rows = count($new_data);
|
|
$new_data = implode("\n", $new_data);
|
|
return array($new_data, $rows);
|
|
}
|