t('Quicktab')),
array('data' => t('Operations'), 'colspan' => 3),
);
$rows = array();
while ($row = db_fetch_object($result)) {
$tablerow = array(
array('data' => $row->title),
array('data' => l('Edit', 'admin/build/quicktabs/'. $row->qtid .'/edit')),
array('data' => l('Clone', 'admin/build/quicktabs/'. $row->qtid .'/clone')),
array('data' => l('Delete', 'admin/build/quicktabs/'. $row->qtid .'/delete')),
);
$rows[] = $tablerow;
}
if (!empty($rows)) {
$output = theme('table', $header, $rows, array('id' => 'quicktabs'));
}
else {
$output = '
'. t('Click on the "New QT block" tab to get started.') .'
';
}
return $output;
}
/**
* Clone QuickTabs.
*/
function quicktabs_clone($quicktabs) {
$quicktabs['qtid'] = 0;
$quicktabs['title'] = '';
return drupal_get_form('quicktabs_form', 'clone', $quicktabs);
}
/**
* Build the quicktab creation and edit form.
*/
function quicktabs_form($form_state, $formtype, $quicktabs = array()) {
$form = _qt_admin_main_form($form_state, $quicktabs);
if ($formtype == 'edit') {
$form['qtid'] = array(
'#type' => 'hidden',
'#value' => isset($quicktabs['qtid']) ? $quicktabs['qtid'] : 0,
);
}
if (empty($quicktabs['tabs'])) {
$quicktabs['tabs'] = array(
0 => array(),
1 => array(),
);
}
// Add the current tabs to the form.
foreach ($quicktabs['tabs'] as $delta => $details) {
$details['delta'] = $delta;
$form['qt_wrapper']['tabs'][$delta] = _quicktabs_form($details);
}
return $form;
}
/*
* The main section of admin page.
*/
function _qt_admin_main_form($form_state, &$quicktabs) {
$form['#cache'] = TRUE;
// the contents of $quicktabs will either come from the db or from $form_state
if (isset($form_state['quicktabs'])) {
$quicktabs = $form_state['quicktabs'] + (array)$quicktabs;
}
$form['title'] = array(
'#title' => t('Block title'),
'#type' => 'textfield',
'#description' => t('This will appear as the name of this block in administer >> site building >> blocks.'),
'#default_value' => (isset($quicktabs['title']) ? $quicktabs['title'] : ''),
'#weight' => -7
);
$styles = module_invoke_all('quicktabs_tabstyles');
// The keys used for options must be valid html id-s.
foreach ($styles as $style) {
$style_options[$style] = $style;
}
ksort($style_options);
$form['style'] = array(
'#type' => 'select',
'#title' => t('Style'),
'#options' => array('nostyle' => t('No style')) + array('default' => t('Default style')) + $style_options,
'#default_value' => isset($quicktabs['style']) ? $quicktabs['style'] : 'default',
'#description' => t('Choose the quicktab style.'),
'#weight' => -6,
);
$form['ajax'] = array(
'#type' => 'radios',
'#title' => t('Ajax'),
'#options' => array(
TRUE => t('Yes') .': '. t('Tab content will be loaded at tab click.'),
FALSE => t('No') .': '. t('All tabs will be loaded at page load.'),
),
'#default_value' => isset($quicktabs['ajax']) ? $quicktabs['ajax'] : 0,
'#description' => t('Choose how the content of tabs should be loaded.'),
'#weight' => -5,
);
// Add a wrapper for the tabs and Add Another Tab button.
$form['qt_wrapper'] = array(
'#tree' => FALSE,
'#weight' => -4,
'#prefix' => '',
'#suffix' => '
',
);
$form['qt_wrapper']['tabs'] = array(
'#tree' => TRUE,
'#prefix' => '',
'#suffix' => '
',
'#theme' => 'quicktabs_admin_form_tabs',
);
$form['qt_wrapper']['tabs_more'] = array(
'#type' => 'submit',
'#prefix' => '',
'#suffix' => '
',
'#value' => t('More tabs'),
'#attributes' => array('class' => 'add-tab', 'title' => t('Click here to add more tabs.')),
'#weight' => 1,
'#submit' => array('qt_more_tabs_submit'), // If no javascript action.
'#ahah' => array(
'path' => 'quicktabs/ahah',
'wrapper' => 'quicktabs-tabs',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['submit_form'] = array(
'#type' => 'submit',
'#weight' => 10,
'#value' => t('Save'),
);
return $form;
}
/*
* Build one row (one tabpage) on the QT admin form.
*/
function _quicktabs_form($details) {
$form['#tree'] = TRUE;
$delta = $details['delta'];
$form['weight'] = array(
'#type' => 'weight',
'#default_value' => isset($details['weight']) ? $details['weight'] : $delta-10,
);
$form['title'] = array(
'#type' => 'textfield',
'#size' => '10',
'#default_value' => isset($details['title']) ? $details['title'] : '',
);
$tabtypes = array(
'block' => t('Block'),
'node' => t('Node'),
'qtabs' => t('QTab'),
);
if (module_exists('views')) {
$views = quicktabs_get_views();
$views_keys = array_keys($views);
$tabtypes['view'] = t('View');
$selected_view = (isset($details['vid']) ? $details['vid'] : (isset($views_keys[0]) ? $views_keys[0] : ''));
$form['view']['vid'] = array(
'#type' => 'select',
'#options' => $views,
'#default_value' => $selected_view,
'#title' => t('Select a view'),
'#ahah' => array(
'path' => 'quicktabs/ahah/',
'wrapper' => 'quicktabs-tabs',
'method' => 'replace',
'event' => 'change',
),
);
$form['view']['display'] = array(
'#type' => 'select',
'#title' => 'display',
'#options' => _quicktabs_get_views_displays($selected_view),
'#default_value' => isset($details['display']) ? $details['display'] : '',
);
$form['view']['args'] = array(
'#type' => 'textfield',
'#title' => 'arguments',
'#size' => '40',
'#required' => FALSE,
'#default_value' => isset($details['args']) ? $details['args'] : '',
'#description' => t('Provide a comma separated list of arguments to pass to the view.'),
);
$form['view']['get_displays'] = array(
'#type' => 'submit',
'#value' => 'vdisp_'. $delta,
'#submit' => array('qt_get_displays_submit'),
);
}
$form['block']['bid'] = array(
'#type' => 'select',
'#options' => quicktabs_get_blocks(),
'#default_value' => isset($details['bid']) ? $details['bid'] : '',
'#title' => t('Select a block'),
);
$form['block']['hide_title'] = array(
'#type' => 'checkbox',
'#title' => t('Hide the title of this block'),
'#default_value' => isset($details['hide_title']) ? $details['hide_title'] : 1,
);
$form['node']['nid'] = array(
'#type' => 'textfield',
'#title' => t('Node'),
'#description' => t('The node ID of the node.'),
'#maxlength' => 10,
'#size' => 20,
'#default_value' => isset($details['nid']) ? $details['nid'] : '',
);
$form['node']['teaser'] = array(
'#type' => 'checkbox',
'#title' => t('Teaser view'),
'#default_value' => isset($details['teaser']) ? $details['teaser'] : 0,
);
$form['node']['hide_title'] = array(
'#type' => 'checkbox',
'#title' => t('Hide the title of this node'),
'#default_value' => isset($details['hide_title']) ? $details['hide_title'] : 1,
);
$form['qtabs']['qtid'] = array(
'#type' => 'textfield',
'#title' => t('Quicktab'),
'#description' => t('The quicktab ID.') .' '. t('Different styles may not work when putting an ajax quicktab inside ajax quicktab.'),
'#maxlength' => 10,
'#size' => 20,
'#default_value' => isset($details['qtid']) ? $details['qtid'] : '',
);
$form['type'] = array(
'#type' => 'radios',
'#options' => $tabtypes,
'#default_value' => isset($details['type']) ? $details['type'] : 'block',
);
$form['remove'] = array(
'#type' => 'submit',
'#prefix' => '',
'#suffix' => '
',
'#value' => 'remove_'. $delta,
'#attributes' => array('class' => 'delete-tab', 'title' => t('Click here to delete this tab.')),
'#submit' => array('qt_remove_tab_submit'),
'#ahah' => array(
'path' => 'quicktabs/ahah',
'wrapper' => 'quicktabs-tabs',
'method' => 'replace',
'effect' => 'fade',
),
);
return $form;
}
/**
* Theme function for quicktabs admin page.
* Theme the form elements for the tabs as draggable table rows.
*
* @ingroup themeable
*/
function theme_quicktabs_admin_form_tabs($form) {
drupal_add_tabledrag('qt-tablist-table', 'order', 'sibling', 'qt-tabs-weight');
$rows = array();
$headers = array(
t('Tab title'),
t('Tab weight'),
t('Tab type'),
t('Tab content'),
t('Operations'),
);
foreach (element_children($form) as $key) {
$form[$key]['weight']['#attributes']['class'] = 'qt-tabs-weight';
// Build the table row.
$row = array(
'data' => array(
array('data' => drupal_render($form[$key]['title']), 'class' => 'qt-tab-title'),
array('data' => drupal_render($form[$key]['weight']), 'class' => 'qt-tab-weight'),
array('data' => drupal_render($form[$key]['type']), 'class' => 'qt-tab-type'),
// tab content (only 1 tab content (block, node or view) will be displayed. see: quicktabs_form.js)
array('data' => drupal_render($form[$key]['block']), 'class' => 'qt-tab-block-content'),
array('data' => (module_exists('views') ? drupal_render($form[$key]['view']) : ''), 'class' => 'qt-tab-view-content'),
array('data' => drupal_render($form[$key]['node']), 'class' => 'qt-tab-node-content'),
array('data' => drupal_render($form[$key]['qtabs']), 'class' => 'qt-tab-qtabs-content'),
array('data' => drupal_render($form[$key]['remove']), 'class' => 'qt-tab-remove'),
),
'class' => 'draggable',
);
// Add additional attributes to the row, such as a class for this row.
if (isset($form[$key]['#attributes'])) {
$row = array_merge($row, $form[$key]['#attributes']);
}
$rows[] = $row;
}
$output = theme('table', $headers, $rows, array('id' => 'qt-tablist-table'));
$output .= drupal_render($form);
// Add our JS file, which has some Drupal core JS overrides, and ensures ahah behaviours get re-attached
drupal_add_js(drupal_get_path('module', 'quicktabs') .'/js/quicktabs_ahah.js', 'module', 'footer');
drupal_add_js(drupal_get_path('module', 'quicktabs') .'/js/quicktabs_form.js');
drupal_add_css(drupal_get_path('module', 'quicktabs') .'/css/quicktabs-admin.css');
return $output;
}
/**
* Submit handler for the "Add Tab" button.
*/
function qt_more_tabs_submit($form, &$form_state) {
$quicktabs = _quicktabs_convert_form_to_quicktabs($form_state);
// Add an empty tab at the end.
$quicktabs['tabs'][] = array();
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$form_state['quicktabs'] = $quicktabs;
$form_state['rebuild'] = TRUE;
}
/**
* Submit handler for the "Remove Tab" button.
*/
function qt_remove_tab_submit($form, &$form_state) {
// Get the tab delta for the clicked button.
$delta = $form_state['clicked_button']['#parents'][1];
// Copy the form_state because unset() does not work on variable
// that is passed by reference.
$form_state_copy = $form_state;
unset($form_state_copy['values']['tabs'][$delta]);
$quicktabs = _quicktabs_convert_form_to_quicktabs($form_state_copy);
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$form_state['quicktabs'] = $quicktabs;
$form_state['rebuild'] = TRUE;
}
/**
* Submit handler for the Views drop down.
*/
function qt_get_displays_submit($form, &$form_state) {
$quicktabs = _quicktabs_convert_form_to_quicktabs($form_state);
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$form_state['quicktabs'] = $quicktabs;
$form_state['rebuild'] = TRUE;
}
/**
* ahah callback.
*/
function quicktabs_ahah() {
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$qt_form = $form['qt_wrapper']['tabs'];
unset($qt_form['#prefix'], $qt_form['#suffix']); // Prevent duplicate wrappers.
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . drupal_render($qt_form),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
/**
* Validation handler for quicktabs admin page.
*/
function quicktabs_form_validate($form, &$form_state) {
// We don't want it to validate when we're just adding or removing tabs.
if ($form_state['clicked_button']['#id'] == 'edit-submit-form') {
if (empty($form_state['values']['title'])) {
form_set_error('title', t('Title is required for the quicktab block.'));
}
else {
if (!isset($form_state['values']['tabs'])) {
form_set_error('', t('At least one tab should be created.'));
}
foreach ($form_state['values']['tabs'] as $j => $tab) {
if (empty($tab['title'])) {
form_set_error('tabs]['. $j .'][title', t('Title is required for each tab.'));
}
elseif ($tab['type'] == 'qtabs' && $tab['qtabs']['qtid'] == $form_state['values']['qtid']) {
form_set_error('tabs]['. $j .'][qtabs][qtid', t('You cannot put a quicktab inside itself.'));
}
}
}
}
}
/**
* Submit handler for quicktabs admin page.
*/
function quicktabs_form_submit($form, &$form_state) {
// We don't want it to submit when we're just adding or removing tabs.
if ($form_state['clicked_button']['#id'] == 'edit-submit-form') {
$quicktabs = _quicktabs_convert_form_to_quicktabs($form_state);
if ($quicktabs['qtid'] > 0) {
quicktabs_updateblock($quicktabs);
drupal_set_message(t('The quicktab block has been updated.'));
}
else {
quicktabs_createblock($quicktabs);
drupal_set_message(t('The quicktab block has been created.'));
}
drupal_goto('admin/build/quicktabs');
}
}
/**
* Insert db record.
*/
function quicktabs_createblock($quicktabs) {
$quicktabs['tabs'] = serialize($quicktabs['tabs']);
db_query("INSERT INTO {quicktabs} (ajax, title, tabs, style) VALUES(%d, '%s', '%s', '%s')", $quicktabs['ajax'], $quicktabs['title'], $quicktabs['tabs'], $quicktabs['style']);
}
/**
* Update db record.
*/
function quicktabs_updateblock($quicktabs) {
$quicktabs['tabs'] = serialize($quicktabs['tabs']);
db_query("UPDATE {quicktabs} SET ajax = %d, title = '%s', tabs = '%s', style = '%s' WHERE qtid = %d", $quicktabs['ajax'], $quicktabs['title'], $quicktabs['tabs'], $quicktabs['style'], $quicktabs['qtid']);
}
/**
* Deletion of quicktab block.
*/
function quicktabs_block_delete(&$form_state, $quicktabs) {
$form['qtid'] = array('#type' => 'hidden', '#value' => $quicktabs['qtid']);
$form['qt_name'] = array('#type' => 'hidden', '#value' => $quicktabs['title']);
return confirm_form($form, t('Are you sure you want to delete the quicktab block %name?', array('%name' => $quicktabs['title'])), 'admin/build/quicktabs', '', t('Delete'), t('Cancel'));
}
/**
* Submit handler for quicktab block deletion.
*/
function quicktabs_block_delete_submit($form, &$form_state) {
db_query('DELETE FROM {quicktabs} WHERE qtid = %d', $form_state['values']['qtid']);
drupal_set_message(t('The quicktab block %name has been removed.', array('%name' => $form_state['values']['qt_name'])));
cache_clear_all();
$form_state['redirect'] = 'admin/build/quicktabs';
};
/**
* Callback function for admin/settings/quicktabs. Display the settings form.
*/
function quicktabs_settings() {
$styles = module_invoke_all('quicktabs_tabstyles');
// The keys used for options must be valid html id-s.
// Removing the css file path, because that can't be used.
foreach ($styles as $style) {
$options[$style] = $style;
}
ksort($options);
$form['quicktabs_tabstyle'] = array(
'#type' => 'radios',
'#title' => t('Quicktab styles'),
'#options' => array('nostyle' => t('No style')) + $options,
'#default_value' => variable_get('quicktabs_tabstyle', 'nostyle'),
'#description' => t('Select the default style for quicktabs.'),
'#attributes' => array('class' => 'quicktabs-tabstyles clear-block'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Submit handler for QuickTabs settings.
*/
function quicktabs_settings_submit($form, &$form_state) {
variable_set('quicktabs_tabstyle', $form_state['values']['quicktabs_tabstyle']);
drupal_set_message(t('The default quicktab style has been saved.'));
}
/**
* Theme function for quicktabs settings page.
*
* @ingroup themeable
*/
function theme_quicktabs_settings($form) {
drupal_add_css(drupal_get_path('module', 'quicktabs') .'/css/quicktabs-admin.css');
$tabs['one'] = array('title' => t('One'), 'type' => 'freetext', 'text' => t('First tab'));
$tabs['two'] = array('title' => t('Two'), 'type' => 'freetext', 'text' => t('Second tab'));
$tabs['three'] = array('title' => t('Three'), 'type' => 'freetext', 'text' => t('Third tab'));
$quicktabs['tabs'] = $tabs;
$quicktabs['ajax'] = FALSE;
// Preview for each style.
foreach ($form['quicktabs_tabstyle']['#options'] as $style => $style_title) {
$quicktabs['style'] = $style;
$quicktabs['qtid'] = drupal_strtolower($style);
$preview = ''. theme('quicktabs', $quicktabs) .'
';
$form['quicktabs_tabstyle'][$style]['#description'] = t('%style preview', array('%style' => $style_title)) .':
'. $preview;
}
return drupal_render($form);
}
/**
* Helper function to get all views.
*/
function quicktabs_get_views() {
$enabled_views = array();
$views = views_get_all_views();
foreach ($views as $view) {
// Skip disabled views.
if (!empty($views[$view->name]->disabled)) {
continue;
}
$enabled_views[$view->name] = $view->name;
}
ksort($enabled_views);
return $enabled_views;
}
/**
* Helper function to get all blocks.
*/
function quicktabs_get_blocks() {
static $blocksarray;
if (empty($blocksarray)) {
global $theme_key;
init_theme();
$result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme_key);
$old_blocks = array();
while ($old_block = db_fetch_array($result)) {
$old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
}
$blocks = array();
foreach (module_list() as $module) {
$module_blocks = module_invoke($module, 'block', 'list');
if ($module_blocks) {
foreach ($module_blocks as $delta => $block) {
if (empty($old_blocks[$module][$delta])) {
// If it's a new block, add identifiers.
$block['module'] = $module;
$block['delta'] = $delta;
$block['theme'] = $theme_key;
$blocks[] = $block;
}
else {
$old_blocks[$module][$delta]['info'] = $block['info'];
// Add this block to the list of blocks we return.
$blocks[] = $old_blocks[$module][$delta];
}
}
}
}
$blocksarray = array();
foreach ($blocks as $i => $block) {
if ($block['module'] != 'quicktabs') {
$key = $block['module'] .'_delta_'. $block['delta'];
$blocksarray[$key] = $block['info'];
}
}
}
return $blocksarray;
}
/**
* Helper function to get all view displays.
*/
function _quicktabs_get_views_displays($view_name) {
$displays = array();
if (empty($view_name)) {
// No view.
return $displays;
}
$views = views_get_all_views();
$view = $views[$view_name];
if (empty($view->display)) {
// This view is broken.
return $displays;
}
foreach ($view->display as $id => $display) {
$displays[$id] = $id .': '. $display->display_title;
}
return $displays;
}
/**
* Helper function to convert the data on admin form into quicktabs presentation.
*/
function _quicktabs_convert_form_to_quicktabs($form_state) {
$formvalues_tabs = array();
if (isset($form_state['values']['tabs'])) {
foreach ($form_state['values']['tabs'] as $j => $tab) {
$formvalues_tabs[$j] = $tab[$tab['type']];
$formvalues_tabs[$j]['title'] = $tab['title'];
$formvalues_tabs[$j]['weight'] = $tab['weight'];
$formvalues_tabs[$j]['type'] = $tab['type'];
$weight[$j] = $tab['weight'];
}
array_multisort($weight, SORT_ASC, $formvalues_tabs);
}
$quicktabs = array(
'title' => $form_state['values']['title'],
'ajax' => $form_state['values']['ajax'],
'style' => $form_state['values']['style'],
'tabs' => $formvalues_tabs,
);
if (isset($form_state['values']['qtid'])) {
$quicktabs['qtid'] = $form_state['values']['qtid'];
}
else {
$quicktabs['qtid'] = 0;
}
return $quicktabs;
}