View source
<?php
define('DYNAMICLOAD_HTML', 1);
define('DYNAMICLOAD_APPEND', 2);
define('DYNAMICLOAD_PREPEND', 3);
define('DYNAMICLOAD_BEFORE', 4);
define('DYNAMICLOAD_AFTER', 5);
function dynamicload_help($section) {
$return = array();
if ($section == $_GET['q']) {
$return[] = '<div id="dynamicload-content-marker"></div>';
}
if ($section == 'admin/settings/dynamicload') {
$return[] = t('<p>Full dynamic loading is <em>experimental</em> and may break sites at this point. The options on this page are not recommended for use on production sites. Work is ongoing to identify and fix remaining issues.</p>
<p>Configure dynamic loading of individual blocks on the <a href="@config">block configuration</a> pages.</p>', array(
'@config' => url('admin/build/block'),
));
}
if (!empty($return)) {
return implode('', $return);
}
}
function dynamicload_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'dynamicload/js',
'title' => t('Dynamicload page'),
'access' => user_access('access content'),
'type' => MENU_CALLBACK,
'callback' => 'dynamicload_js',
);
$items[] = array(
'path' => 'dynamicload/block',
'title' => t('Dynamicload block'),
'access' => user_access('access content'),
'type' => MENU_CALLBACK,
'callback' => 'dynamicload_fetch_block',
);
$items[] = array(
'path' => 'admin/settings/dynamicload',
'title' => t('Dynamicload'),
'description' => t('Configuration for dynamic loading'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'dynamicload_admin_settings',
),
);
}
else {
dynamicload_load();
}
return $items;
}
function dynamicload_admin_settings() {
$form = array();
$form['jstools_history_remote'] = array(
'#type' => 'radios',
'#title' => t('History plugin'),
'#description' => t('Load the history_remote plugin, which ties dynamic loading to browser history. Dynamicload will be missing some functionality if this is disabled. However, the plugin can cause errors in combination with certain other Javascript functionality. Disable to avoid such errors. Note that disabling this setting will affect other modules if you enable them: Active Search and Tabs.'),
'#default_value' => variable_get('jstools_history_remote', 0),
'#options' => array(
t('disabled'),
t('enabled'),
),
);
$form['dynamicload_all'] = array(
'#type' => 'checkbox',
'#title' => t('Process all links for dynamic loading'),
'#description' => t('Check this option to make all links on the page dynamically load into the main content area. Links processed through block configuraiton will be skipped. You can also configure by paths, below.'),
'#default_value' => variable_get('dynamicload_all', 0),
);
$form['dynamicload_paths_type'] = array(
'#type' => 'radios',
'#title' => t('Path processing'),
'#options' => array(
t('Apply dynamic loading to all links except those to the listed pages.'),
t('Apply dynamic loading only on links to the listed pages.'),
),
'#default_value' => variable_get('dynamicload_paths_type', 0),
);
$form['dynamicload_paths'] = array(
'#type' => 'textarea',
'#title' => t('Paths'),
'#default_value' => variable_get('dynamicload_paths', 'admin*'),
'#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog and %admin for all admin pages. Put the wildcard at the both ends of a path fragment to match any path containing that fragment. The front page is automatically skipped.", array(
'%blog' => 'blog',
'%blog-wildcard' => 'blog/*',
'%admin' => 'admin*',
)),
);
include_once drupal_get_path('module', 'dynamicload') . '/paths.inc';
$paths = module_invoke_all('dynamicload_paths');
if (is_array($paths) && !empty($paths)) {
$form['dynamicload_paths']['#description'] .= t(' If Path processing is set to "Apply dynamic loading to all links except those to the listed pages" above, the following paths will be used automatically and so don\'t need to be entered here: %paths.', array(
'%paths' => implode(', ', $paths),
));
}
$form['dynamicload_regions'] = array(
'#type' => 'checkboxes',
'#title' => t('Load region data'),
'#description' => t('If you wish to refresh block regions with page loads, select the regions here. Only selected regions will be loaded.'),
'#options' => system_region_list(variable_get('theme_default', 'garland')),
'#default_value' => variable_get('dynamicload_regions', array()),
);
$form = system_settings_form($form);
return $form;
}
function dynamicload_load() {
static $loaded = FALSE;
if (!$loaded) {
jstools_modules_includes('dynamicload');
$path = drupal_get_path('module', 'dynamicload');
jstools_add_js(array(
$path . '/dynamicload.js',
'misc/progress.js',
));
drupal_add_js(drupal_get_path('module', 'jstools') . '/jquery.history_remote.pack.js');
_dynamicload_set_region_markers(array(
'left',
'right',
));
drupal_add_css(drupal_get_path('module', 'block') . '/block.css');
$loaded = TRUE;
}
}
function dynamicload_footer() {
global $theme;
static $loaded = FALSE;
if (!$loaded) {
$regions = array_keys(system_region_list($theme));
unset($regions['left'], $regions['right']);
_dynamicload_set_region_markers($regions);
$settings = dynamicload_block_data();
foreach (module_invoke_all('dynamicload') as $setting) {
$settings = array_merge($settings, $setting);
}
$theme_data = module_invoke('jstools', 'theme_data', 'dynamicload');
if (is_array($theme_data)) {
foreach ($theme_data as $key => $selector) {
if ($source = array_search($key, $settings)) {
$settings[$source] = $selector;
}
else {
unset($settings[$source]);
}
}
}
$paths_type = variable_get('dynamicload_paths_type', 0);
$paths = variable_get('dynamicload_paths', 'admin*');
if ($paths_type == 0) {
include_once drupal_get_path('module', 'dynamicload') . '/paths.inc';
$paths .= "\n" . implode("\n", module_invoke_all('dynamicload_paths'));
}
drupal_add_js(array(
'dynamicload' => array(
'all' => (bool) variable_get('dynamicload_all', 0),
'paths_type' => $paths_type,
'paths' => $paths,
'content' => $theme_data['content'] ? $theme_data['content'] : '#main',
'settings' => $settings,
),
), 'setting');
$loaded = TRUE;
}
return '';
}
function _dynamicload_set_region_markers($regions) {
foreach ($regions as $region) {
drupal_set_content($region, '<div id="dynamicload-region-' . $region . '" class="dynamicload-region"></div>');
}
}
function dynamicload_form_alter($form_id, &$form) {
if ($form_id == 'block_admin_configure') {
$options = array(
'content' => t('Main content area'),
);
$result = db_query('SELECT module, delta FROM {blocks} WHERE status = 1 AND NOT (module = "%s" AND delta = "%s")', $form['module']['#value'], $form['delta']['#value']);
while ($block = db_fetch_object($result)) {
$module_blocks = module_invoke($block->module, 'block', 'list');
$options['#block-' . $block->module . '-' . $block->delta] = t('Block: !info', array(
'!info' => $module_blocks[$block->delta]['info'],
));
}
$regions = system_region_list(variable_get('theme_default', 'garland'));
foreach ($regions as $key => $value) {
drupal_set_content($key, '<div class="block-region">' . $value . '</div>');
$options['region-' . $key] = t('Region: !name', array(
'!name' => $value,
));
}
$settings = dynamicload_block_data($form['module']['#value'], $form['delta']['#value']);
$form['#submit']['dynamicload_submit'] = array();
$form['dynamicload'] = array(
'#type' => 'fieldset',
'#title' => t('Dynamic loading'),
'#collapsible' => true,
'#weight' => -5,
);
$form['dynamicload']['dynamicload_apply'] = array(
'#type' => 'checkbox',
'#title' => t('Apply dynamic loading'),
'#description' => t('Check if you want links on this block to be loaded dynamically rather than through a regular page refresh. If you enable this functionality for a block, make sure that you thoroughly test the result, as not all pages will perform as expected when loaded dynamically.'),
'#default_value' => $settings['apply'] ? 1 : 0,
);
$form['dynamicload']['dynamicload_target'] = array(
'#type' => 'select',
'#title' => t('Target area'),
'#default_value' => $settings['target'] ? $settings['target'] : '#main',
'#options' => $options,
'#description' => t('Select the page area for this block\'s links to load into. Only enabled blocks are available.'),
);
$options = array(
DYNAMICLOAD_HTML => t('replace existing content'),
DYNAMICLOAD_APPEND => t('append: add at end of existing content'),
DYNAMICLOAD_PREPEND => t('prepend: add at beginning of existing content'),
DYNAMICLOAD_BEFORE => t('before: add before target element'),
DYNAMICLOAD_AFTER => t('after: add after target element'),
);
$form['dynamicload']['dynamicload_method'] = array(
'#type' => 'select',
'#title' => t('Appending method'),
'#default_value' => $settings['method'] ? $settings['method'] : 1,
'#options' => $options,
'#description' => t('Select the way you want newly loaded content to be written to the target area.'),
);
$form['dynamicload']['dynamicload_refresh'] = array(
'#type' => 'checkbox',
'#title' => t('Automatically refresh this block'),
'#default_value' => $settings['refresh'] ? 1 : 0,
);
$form['dynamicload']['dynamicload_refresh_interval'] = array(
'#type' => 'select',
'#title' => t('Block refresh interval'),
'#description' => t('Select the interval at which this block should refresh.'),
'#default_value' => $settings['refresh_interval'] ? $settings['refresh_interval'] : 30000,
'#options' => array(
5000 => t('five seconds'),
10000 => t('ten seconds'),
30000 => t('thirty seconds'),
60000 => t('one minute'),
120000 => t('two minutes'),
180000 => t('three minutes'),
300000 => t('five minutes'),
600000 => t('ten minutes'),
),
);
$form['dynamicload']['dynamicload_scroll'] = array(
'#type' => 'checkbox',
'#title' => t('Scroll in new items'),
'#description' => t('Check if you want new items for this block to scroll in ticker-style as they arrive (with the oldest item scrolling out). If this option is not checked, the whole block will refresh. Note: only works for items that come in as a list (using an HTML ul element).)'),
'#default_value' => $settings['scroll'] ? 1 : 0,
);
}
}
function dynamicload_submit($form_id, $form_values) {
if (db_num_rows(db_query("SELECT * FROM {dynamicload_blocks} WHERE module = '%s' AND delta = '%s'", $form_values['module'], $form_values['delta']))) {
db_query("UPDATE {dynamicload_blocks} SET refresh = %d, refresh_interval = %d, scroll = %d, apply = %d, target = '%s', method = %d WHERE module = '%s' AND delta = '%s'", $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_scroll'], $form_values['dynamicload_apply'], $form_values['dynamicload_target'], $form_values['dynamicload_method'], $form_values['module'], $form_values['delta']);
drupal_set_message(t('Dynamic loading block data updated.'));
}
else {
db_query("INSERT INTO {dynamicload_blocks} (module, delta, refresh, refresh_interval, scroll, apply, target, method) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d)", $form_values['module'], $form_values['delta'], $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_scroll'], $form_values['dynamicload_apply'], $form_values['dynamicload_target'], $form_values['dynamicload_method']);
drupal_set_message(t('Dynamic loading block data saved.'));
}
}
function dynamicload_block_data($module = NULL, $delta = NULL) {
static $blocks = NULL;
if ($blocks == NULL) {
$blocks = array();
$result = db_query("SELECT * FROM {dynamicload_blocks}");
while ($block = db_fetch_array($result)) {
foreach (array(
'refresh',
'apply',
) as $key) {
$block[$key] = (bool) $block[$key];
}
$block['type'] = 'block';
$block['selector'] = '#block-' . $block['module'] . '-' . $block['delta'];
$blocks[$block['module'] . '_' . $block['delta']] = $block;
}
}
if ($module !== NULL && $delta !== NULL) {
return $blocks[$module . '_' . $delta] ? $blocks[$module . '_' . $delta] : array();
}
else {
return $blocks;
}
}
function dynamicload_block_list() {
global $theme_key;
$blocks = array();
if ($theme_key) {
$regions = system_region_list($theme_key);
foreach (array_keys($regions) as $region) {
$block_list = block_list($region);
$blocks = array_merge($blocks, $block_list);
}
}
return $blocks;
}
function dynamicload_fetch_block($module, $delta) {
global $theme_key;
if (!isset($theme_key)) {
init_theme();
}
$region = db_result(db_query("SELECT region FROM {blocks} WHERE module = '%s' AND delta = %d AND theme = '%s'", $module, $delta, $theme_key));
$blocks = block_list($region);
if (isset($blocks[$module . '_' . $delta])) {
print drupal_to_js(array(
'result' => TRUE,
'content' => theme('block', $blocks[$module . '_' . $delta]),
));
}
else {
print drupal_to_js(array(
'result' => FALSE,
'content' => NULL,
));
}
exit;
}
function dynamicload_js() {
if ($path = substr($_GET['q'], 15)) {
$return = module_invoke('pagearray', 'page', $path);
if ($return['status'] === FALSE) {
switch ($return['value']) {
case MENU_NOT_FOUND:
case NULL:
$result = array(
'result' => FALSE,
'message' => t('Item was not found.'),
);
break;
case MENU_ACCESS_DENIED:
$result = array(
'result' => FALSE,
'message' => t('Access denied.'),
);
break;
case MENU_SITE_OFFLINE:
$result = array(
'result' => FALSE,
'message' => t('Site offline.'),
);
break;
}
}
else {
$extra = '<h1>' . $return['page']['title'] . '</h1>';
$extra = $return['page']['breadcrumb'] . $extra;
if ($tabs = theme('menu_local_tasks')) {
$extra .= $tabs;
}
$extra .= $return['page']['help'];
$extra .= theme('status_messages');
$result = array(
'result' => TRUE,
'extra' => $extra,
'content' => $return['page']['content'],
'title' => $return['page']['head_title'],
'scripts' => $return['page']['raw_scripts'],
'css' => $return['page']['css'],
);
$regions = array_filter(variable_get('dynamicload_regions', array()));
if (!empty($regions)) {
$result['regions'] = array();
foreach ($regions as $region) {
if (isset($return['page']['regions'][$region])) {
$result['regions'][$region] = $return['page']['regions'][$region];
}
}
}
}
}
else {
$result = array(
'result' => FALSE,
'message' => t('No request found.'),
);
}
print drupal_to_js($result);
exit;
}