? quicktabs_ctools_export.patch
Index: quicktabs.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/quicktabs.install,v
retrieving revision 1.4.2.11
diff -u -p -r1.4.2.11 quicktabs.install
--- quicktabs.install 10 Jan 2010 01:06:40 -0000 1.4.2.11
+++ quicktabs.install 26 May 2010 13:24:14 -0000
@@ -7,14 +7,24 @@
function quicktabs_schema() {
$schema['quicktabs'] = array(
'description' => 'The quicktabs table.',
+ // Optional CTools export.inc integration
+ 'export' => array(
+ 'key' => 'qtid',
+ 'identifier' => 'quicktabs',
+ 'default hook' => 'quicktabs_default_quicktabs',
+ 'api' => array(
+ 'owner' => 'quicktabs',
+ 'api' => 'quicktabs',
+ 'minimum_version' => 1,
+ 'current_version' => 1,
+ ),
+ ),
'fields' => array(
'qtid' => array(
'description' => 'The primary identifier for a qt block.',
- 'type' => 'serial',
- 'unsigned' => TRUE,
- 'size' => 'big',
+ 'type' => 'varchar',
+ 'length' => 255,
'not null' => TRUE,
- 'disp-width' => '10',
),
'ajax' => array(
'description' => 'Whether this is an ajax views block.',
@@ -215,3 +225,41 @@ function quicktabs_update_6206() {
return $ret;
}
+/**
+ * Migrate existing quicktabs over to new schema.
+ */
+function quicktabs_update_6207() {
+ $ret = array();
+
+ // Pull all existing quicktabs, and then delete existing quicktabs. We will reinsert.
+ $result = db_query("SELECT * FROM {quicktabs}");
+ $ret[] = update_sql("DELETE FROM {quicktabs}");
+
+ db_drop_field($ret, 'quicktabs', 'qtid');
+ $new_field = array(
+ 'description' => 'The primary identifier for a qt block.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ );
+ db_add_field($ret, 'quicktabs', 'qtid', $new_field);
+ db_add_primary_key($ret, 'quicktabs', array('qtid'));
+
+ $used = array();
+ while ($row = db_fetch_array($result)) {
+ // Generate a machine-readable string
+ $qtid = strtolower(preg_replace('/[^a-zA-Z0-9_]+/', '_', $row['title']));
+ $i = 0;
+ while (in_array($i == 0 ? $qtid : "{$qtid}_{$i}", $used)) {
+ $i++;
+ }
+ $row['qtid'] = $i == 0 ? $qtid : "{$qtid}_{$i}";
+
+ $placeholders = implode(', ', array_keys($row));
+ $tokens = implode(', ', array_fill(0, count($row), "'%s'"));
+ db_query("INSERT INTO {quicktabs} ($placeholders) VALUES($tokens)", $row);
+
+ $ret[] = "Converted quicktab {$row['qtid']}.";
+ }
+ return $ret;
+}
Index: quicktabs.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/quicktabs.module,v
retrieving revision 1.10.2.80
diff -u -p -r1.10.2.80 quicktabs.module
--- quicktabs.module 8 May 2010 22:38:26 -0000 1.10.2.80
+++ quicktabs.module 26 May 2010 13:24:15 -0000
@@ -69,8 +69,8 @@ function quicktabs_menu() {
'type' => MENU_LOCAL_TASK,
'file' => 'includes/admin.inc',
);
- $items['admin/build/quicktabs/%quicktabs/edit'] = array(
- 'title' => 'Edit QT block',
+ $items['admin/build/quicktabs/%quicktabs'] = array(
+ 'title' => 'Edit',
'page callback' => 'drupal_get_form',
'page arguments' => array('quicktabs_form', 'edit', 3),
'access arguments' => array('administer quicktabs'),
@@ -78,22 +78,38 @@ function quicktabs_menu() {
'type' => MENU_CALLBACK,
'file' => 'includes/admin.inc',
);
+ $items['admin/build/quicktabs/%quicktabs/edit'] = array(
+ 'title' => 'Edit',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('quicktabs_form', 'edit', 3),
+ 'access arguments' => array('administer quicktabs'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'file' => 'includes/admin.inc',
+ );
$items['admin/build/quicktabs/%quicktabs/delete'] = array(
- 'title' => 'Delete QT block',
+ 'title' => 'Delete',
'page callback' => 'drupal_get_form',
'page arguments' => array('quicktabs_block_delete', 3),
'access arguments' => array('administer quicktabs'),
'load arguments' => array('delete'),
- 'type' => MENU_CALLBACK,
+ 'type' => MENU_LOCAL_TASK,
'file' => 'includes/admin.inc',
);
$items['admin/build/quicktabs/%quicktabs/clone'] = array(
- 'title' => 'Clone QT block',
+ 'title' => 'Clone',
'page callback' => 'quicktabs_clone',
'page arguments' => array(3),
'access arguments' => array('administer quicktabs'),
'load arguments' => array('clone'),
- 'type' => MENU_CALLBACK,
+ 'type' => MENU_LOCAL_TASK,
+ 'file' => 'includes/admin.inc',
+ );
+ $items['admin/build/quicktabs/%quicktabs/export'] = array(
+ 'title' => 'Export',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('quicktabs_export_form', 3),
+ 'access arguments' => array('administer quicktabs'),
+ 'type' => MENU_LOCAL_TASK,
'file' => 'includes/admin.inc',
);
@@ -137,10 +153,9 @@ function quicktabs_block($op = 'list', $
switch ($op) {
case 'list':
$blocks = array();
- $result = db_query('SELECT qtid, title FROM {quicktabs}');
- while ($row = db_fetch_object($result)) {
- $blocks[$row->qtid]['info'] = $row->title;
- $blocks[$row->qtid]['cache'] = BLOCK_NO_CACHE;
+ foreach (quicktabs_get_all_quicktabs() as $qtid => $quicktabs) {
+ $blocks[$qtid]['info'] = $quicktabs['title'];
+ $blocks[$qtid]['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
break;
@@ -463,15 +478,54 @@ function quicktabs_style_options($includ
}
/**
+ * Load all from defaults and database quicktabs.
+ */
+function quicktabs_get_all_quicktabs() {
+ $quicktabs = array();
+
+ // Load quicktabs via ctools is present.
+ if (module_exists('ctools')) {
+ ctools_include('export');
+ $loaded = ctools_export_load_object('quicktabs', 'all');
+ foreach ($loaded as $qtid => $quicktab) {
+ $quicktabs[$qtid] = (array) $quicktab;
+ }
+ return $quicktabs;
+ }
+
+ // Otherwise, load from DB
+ $result = db_query('SELECT qtid, title FROM {quicktabs} ORDER BY title');
+ while ($quicktab = db_fetch_array($result)) {
+ $quicktabs[$quicktab['qtid']] = _quicktabs_unpack($quicktab);
+ }
+ return $quicktabs;
+}
+
+/**
* Load the quicktabs data.
*/
function quicktabs_load($qtid, $op = 'view') {
+ // Load quicktabs via ctools is present.
+ if (module_exists('ctools')) {
+ ctools_include('export');
+ $defaults = ctools_export_load_object('quicktabs', 'names', array($qtid));
+ return isset($defaults[$qtid]) ? (array) $defaults[$qtid] : FALSE;
+ }
+
+ // Load quicktabs from the database.
$quicktabs = db_fetch_array(db_query('SELECT qtid, title, tabs, ajax, hide_empty_tabs, default_tab, style FROM {quicktabs} WHERE qtid = %d', $qtid));
- if (!$quicktabs) {
- return FALSE;
+ if ($quicktabs) {
+ return _quicktabs_unpack($quicktabs);
}
+ return FALSE;
+}
+/**
+ * Unpack a quicktabs row array from the database.
+ */
+function _quicktabs_unpack($quicktabs) {
$tabs = unserialize($quicktabs['tabs']);
+ $weight = array();
foreach ($tabs as $key => $tab) {
$weight[$key] = $tab['weight'];
if ($tab['type'] == 'qtabs' && $tab['qtid'] == $qtid) {
Index: includes/admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/includes/Attic/admin.inc,v
retrieving revision 1.1.2.54
diff -u -p -r1.1.2.54 admin.inc
--- includes/admin.inc 20 Apr 2010 18:24:05 -0000 1.1.2.54
+++ includes/admin.inc 26 May 2010 13:24:15 -0000
@@ -5,19 +5,49 @@
* Page callback for quicktabs admin landing page.
*/
function quicktabs_list() {
- $result = db_query('SELECT qtid, title FROM {quicktabs} ORDER BY title');
$header = array(
array('data' => t('Quicktab')),
- array('data' => t('Operations'), 'colspan' => 3),
+ array('data' => t('Storage')),
+ array('data' => t('Operations'), 'colspan' => module_exists('ctools') ? 4 : 3),
);
$rows = array();
- while ($row = db_fetch_object($result)) {
- $tablerow = array(
- array('data' => $row->title),
- array('data' => l(t('Edit'), 'admin/build/quicktabs/'. $row->qtid .'/edit')),
- array('data' => l(t('Clone'), 'admin/build/quicktabs/'. $row->qtid .'/clone')),
- array('data' => l(t('Delete'), 'admin/build/quicktabs/'. $row->qtid .'/delete')),
- );
+
+ foreach (quicktabs_get_all_quicktabs() as $quicktabs) {
+ if (module_exists('ctools')) {
+ // Determine storage
+ switch ($quicktabs['export_type']) {
+ case EXPORT_IN_DATABASE | EXPORT_IN_CODE:
+ $storage = t('Overridden');
+ $delete = l(t('Revert'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/delete');
+ break;
+ case EXPORT_IN_DATABASE:
+ $storage = t('Normal');
+ $delete = l(t('Delete'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/delete');
+ break;
+ case EXPORT_IN_CODE:
+ $storage = t('Default');
+ $delete = '';
+ break;
+ }
+
+ $tablerow = array(
+ array('data' => $quicktabs['title']),
+ array('data' => $storage),
+ array('data' => l(t('Edit'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/edit')),
+ array('data' => l(t('Export'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/export')),
+ array('data' => l(t('Clone'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/clone')),
+ array('data' => $delete),
+ );
+ }
+ else {
+ $tablerow = array(
+ array('data' => $quicktabs['title']),
+ array('data' => t('Normal')),
+ array('data' => l(t('Edit'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/edit')),
+ array('data' => l(t('Clone'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/clone')),
+ array('data' => l(t('Delete'), 'admin/build/quicktabs/'. $quicktabs['qtid'] .'/delete')),
+ );
+ }
$rows[] = $tablerow;
}
if (!empty($rows)) {
@@ -44,12 +74,6 @@ function quicktabs_clone($quicktabs) {
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,
- );
- }
$no_tabs = TRUE;
if (empty($quicktabs['tabs'])) {
$quicktabs['tabs'] = array(
@@ -95,6 +119,27 @@ function _qt_admin_main_form($form_state
$quicktabs = $form_state['quicktabs'] + (array)$quicktabs;
}
+ if (empty($quicktabs['qtid'])) {
+ $form['qtid'] = array(
+ '#title' => t('Quicktabs ID'),
+ '#type' => 'textfield',
+ '#description' => t('A unique ID that will be used internally and in the CSS ID of your quicktabs block. must contain only lowercase letters, numbers, and underscores.'),
+ '#default_value' => '',
+ '#weight' => -8,
+ '#required' => TRUE,
+ );
+ }
+ else {
+ $form['qtid'] = array('#type' => 'value', '#value' => $quicktabs['qtid']);
+ $form['qtid_display'] = array(
+ '#title' => t('Quicktabs ID'),
+ '#type' => 'item',
+ '#value' => "{$quicktabs['qtid']}",
+ '#description' => t('This ID will be used internally by quicktabs and will be used in the CSS ID of your quicktabs block.'),
+ '#weight' => -8,
+ );
+ }
+
$form['title'] = array(
'#title' => t('Block title'),
'#type' => 'textfield',
@@ -427,6 +472,12 @@ function quicktabs_ahah() {
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']['qtid'])) {
+ form_set_error('qtid', t('The quicktabs ID is required.'));
+ }
+ else if (!preg_match('!^[a-z0-9_]+$!', $form_state['values']['qtid'])) {
+ form_set_error('type', t('The quicktabs ID must contain only lowercase letters, numbers, and underscores.'));
+ }
if (empty($form_state['values']['title'])) {
form_set_error('title', t('Title is required for the quicktab block.'));
}
@@ -459,7 +510,8 @@ function quicktabs_form_submit($form, &$
$quicktabs = _quicktabs_convert_form_to_quicktabs($form_state);
drupal_alter('quicktabs', $quicktabs, 'presave');
- if ($quicktabs['qtid'] > 0) {
+ $exists = quicktabs_load($quicktabs['qtid']);
+ if ($exists && empty($exists['in_code_only'])) {
$ret = drupal_write_record('quicktabs', $quicktabs, 'qtid');
if ($ret == SAVED_UPDATED) {
drupal_set_message(t('The quicktab block has been updated.'));
@@ -488,13 +540,43 @@ function quicktabs_block_delete(&$form_s
* 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']);
+ db_query("DELETE FROM {quicktabs} WHERE qtid = '%s'", $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';
};
/**
+ * Export form for quicktabs.
+ */
+function quicktabs_export_form(&$form_state, $quicktabs) {
+ ctools_include('export');
+
+ // Generate export code
+ $code = '$items = array();' ."\n";
+ $code .= ctools_export_object('quicktabs', (object) $quicktabs, '');
+ $code .= '$items["'. $quicktabs['qtid'] .'"] = $quicktabs;' ."\n";
+ $code .= 'return $items;';
+
+ // Create form
+ $form = array();
+ $form['export'] = array(
+ '#type' => 'textarea',
+ '#default_value' => $code,
+ '#rows' => substr_count($code, "\n") + 1,
+ '#resizable' => FALSE,
+ '#description' => t('Place this code in your module\'s implementation of hook_quicktabs_default_quicktabs() to provide it as a default quicktab.'),
+ );
+ $form['done'] = array(
+ '#type' => 'submit',
+ '#value' => t('Done'),
+ );
+ $form['#redirect'] = 'admin/build/quicktabs';
+
+ return $form;
+}
+
+/**
* Callback function for admin/settings/quicktabs. Display the settings form.
*/
function quicktabs_settings() {