? .DS_Store ? edit-shortcuts.patch ? head.db ? install_drupal.php ? includes/.DS_Store ? modules/.DS_Store ? modules/node/.DS_Store ? modules/toolbar/.DS_Store ? sites/default/files ? sites/default/private ? sites/default/settings.php Index: modules/toolbar/toolbar.admin.css =================================================================== RCS file: modules/toolbar/toolbar.admin.css diff -N modules/toolbar/toolbar.admin.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/toolbar/toolbar.admin.css 31 Aug 2009 01:43:04 -0000 @@ -0,0 +1,10 @@ +h4.shortcuts-set, +div.shortcuts-change-set { + display: inline; +} +.toolbar-slot-hidden { + display: none; +} +div.form-item-set div.form-item-new { + display: inline; +} \ No newline at end of file Index: modules/toolbar/toolbar.admin.inc =================================================================== RCS file: modules/toolbar/toolbar.admin.inc diff -N modules/toolbar/toolbar.admin.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/toolbar/toolbar.admin.inc 31 Aug 2009 01:43:04 -0000 @@ -0,0 +1,294 @@ + t('Using set "@set"', array('@set' => $set['name'])), + '#prefix' => '

', + '#suffix' => '

', + '#weight' => -100, + ); + + $form['change_set'] = array( + '#markup' => l('Change set', 'admin/settings/shortcuts/switch-set'), + '#prefix' => '
(', + '#suffix' => ')
', + '#weight' => -99, + '#access' => user_access('choose toolbar shortcut set'), + ); + + $form['shortcuts']['#tree'] = TRUE; + $form['shortcuts']['#theme'] = 'toolbar_admin_shortcuts_table'; + $form['shortcuts']['enabled'] = $form['shortcuts']['disabled'] = array(); + foreach ($set['shortcuts'] as $shortcut) { + $scid = $shortcut['scid']; + $status = ($shortcut['status'] ? 'enabled' : 'disabled'); + $form['shortcuts'][$status][$scid]['name']['#markup'] = l($shortcut['name'], $shortcut['path']); + $form['shortcuts'][$status][$scid]['weight'] = array( + '#type' => 'weight', + '#title' => t('Weight'), + '#delta' => 50, + '#default_value' => $shortcut['weight'], + '#attributes' => array('class' => array('shortcut-weight')), + ); + $form['shortcuts'][$status][$scid]['status'] = array( + '#type' => 'select', + '#title' => t('Status'), + '#options' => array('disabled' => t('Disabled'), 'enabled' => t('Enabled')), + '#default_value' => $status, + '#attributes' => array('class' => array('shortcut-status-select')), + ); + + $form['shortcuts'][$status][$scid]['edit']['#markup'] = l(t('edit'), 'admin/settings/shortcuts/shortcut/' . $scid); + $form['shortcuts'][$status][$scid]['delete']['#markup'] = l(t('delete'), 'admin/settings/shortcuts/shortcut/' . $scid . '/delete'); + } + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save Changes'), + ); + + return $form; +} + +function toolbar_admin_shortcuts_submit($form, &$form_state) { + $map = array('enabled' => 1, 'disabled' => 0); + foreach (array('enabled', 'disabled') as $status) { + if (!empty($form_state['values']['shortcuts'][$status])) { + foreach ($form_state['values']['shortcuts'][$status] as $scid => $shortcut) { + $loaded_shortcut = toolbar_shortcut_load($scid); + $loaded_shortcut['status'] = $map[$shortcut['status']]; + $loaded_shortcut['weight'] = $shortcut['weight']; + toolbar_shortcut_save($loaded_shortcut); + } + } + } +} + +/** + * Add a new link to the current set. + */ +function toolbar_admin_shortcut_add_link() { + // Knock an enabled one out if we have to. + $set = toolbar_set_load(toolbar_current_set(), TRUE); + // Too many, knock one out. + while (count($set['shortcuts']) >= TOOLBAR_MAX_SLOTS) { + $disable = array_pop($set['shortcuts']); + $disable['status'] = 0; + toolbar_shortcut_save($disable); + } + $largest_weight = -50; + foreach ($set['shortcuts'] as $shortcut) { + $largest_weight = max($shortcut['weight'], $largest_weight); + } + toolbar_shortcut_save(array( + 'sid' => toolbar_current_set(), + 'weight' => $largest_weight + 1, + 'path' => $_GET['link'], + 'name' => $_GET['name'], + 'status' => 1, + )); + drupal_goto('admin/settings/shortcuts'); +} + + +/** + * Switch toolbar sets. + */ +function toolbar_admin_shortcuts_switch_set(&$form_state) { + $form = array(); + $sets = toolbar_set_list(); + $options = array(); + foreach ($sets as $sid => $set) { + $options[$sid] = check_plain($set['name']); + } + // This is translated again in the theme function, so that the textfield can + // be added. + $options['new'] = t('New set: !textfield', array('!textfield' => '')); + $form['set'] = array( + '#type' => 'radios', + '#title' => t('Choose a set'), + '#options' => $options, + '#default_value' => toolbar_current_set(), + ); + + $form['new'] = array( + '#type' => 'textfield', + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save configuration'), + ); + return $form; +} + +function toolbar_admin_shortcuts_switch_set_submit($form, &$form_state) { + global $user; + + if ($form_state['values']['set'] == 'new') { + $set = toolbar_set_save(array( + 'name' => $form_state['values']['new'], + )); + } + else { + $set = $form_state['values']['set']; + } + db_merge('toolbar_set_users') + ->key(array('uid' => $user->uid)) + ->fields(array( + 'sid' => $set, + )) + ->execute(); + + $form_state['redirect'] = 'admin/settings/shortcuts'; +} + +/** + * Shortcut editing screen. + */ +function toolbar_admin_shortcut_edit(&$form_state, $shortcut) { + $form = array(); + drupal_set_title($shortcut['name']); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Name'), + '#description' => t('The name of the shortcut.'), + '#size' => 40, + '#maxlength' => 255, + '#default_value' => $shortcut['name'], + ); + + $form['path'] = array( + '#type' => 'textfield', + '#title' => t('Path'), + '#description' => t('The path to the shortcut.'), + '#size' => 40, + '#maxlength' => 255, + '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), + '#default_value' => $shortcut['path'], + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + $form_state['shortcut'] = $shortcut; + + return $form; +} + +function toolbar_admin_shortcut_edit_submit($form, &$form_state) { + $form_state['shortcut']['path'] = $form_state['values']['path']; + $form_state['shortcut']['name'] = $form_state['values']['name']; + toolbar_shortcut_save($form_state['shortcut']); + $form_state['redirect'] = 'admin/settings/shortcuts'; +} + +/** + * Shortcut deleting screen. + */ +function toolbar_admin_shortcut_delete(&$form_state, $shortcut) { + $form = array(); + + $form['scid'] = array( + '#type' => 'value', + '#value' => $shortcut['scid'], + ); + + return confirm_form( + $form, + t('Are you sure you want to delete the shortcut %name?', array('%name' => $shortcut['name'])), + 'admin/settings/shortcuts', + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') + ); +} + +function toolbar_admin_shortcut_delete_submit($form, &$form_state) { + toolbar_shortcut_delete($form_state['values']['scid']); + $form_state['redirect'] = 'admin/settings/shortcuts'; +} + +/** + * Theme function for set switching page. + * + * @see toolbar_admin_shortcuts_switch_set + * @ingroup themable + */ +function theme_toolbar_admin_shortcuts_switch_set($form) { + drupal_add_css(drupal_get_path('module', 'toolbar') . '/toolbar.admin.css'); + drupal_add_js(drupal_get_path('module', 'toolbar') . '/toolbar.admin.js'); + $form['set']['new']['#title'] = t('New set: !textfield', array('!textfield' => drupal_render($form['new']))); + return drupal_render_children($form); +} + +/** + * Theme function for the main shortcut administration page. + * + * @see toolbar_admin_shortcuts + * @ingroup themable + */ +function theme_toolbar_admin_shortcuts_table($form) { + drupal_add_css(drupal_get_path('module', 'toolbar') . '/toolbar.admin.css'); + drupal_add_js(drupal_get_path('module', 'toolbar') . '/toolbar.admin.js'); + $map = array('disabled' => t('Disabled'), 'enabled' => t('Enabled')); + + $rows = array(); + foreach (array('enabled', 'disabled') as $status) { + drupal_add_tabledrag('shortcuts', 'match', 'sibling', 'shortcut-status-select'); + drupal_add_tabledrag('shortcuts', 'order', 'sibling', 'shortcut-weight'); + $rows[] = array( + 'data' => array(array( + 'colspan' => 5, + 'data' => '' . $map[$status] . '', + )), + 'class' => array('toolbar-status', 'toolbar-status-' . $status), + ); + foreach (element_children($form[$status]) as $key) { + $shortcut = &$form[$status][$key]; + $row = array(); + $row[] = drupal_render($shortcut['name']); + $row[] = drupal_render($shortcut['weight']); + $row[] = drupal_render($shortcut['status']); + $row[] = drupal_render($shortcut['edit']); + $row[] = drupal_render($shortcut['delete']); + $rows[] = array( + 'data' => $row, + 'class' => array('draggable'), + ); + } + if ($status == 'enabled') { + for ($i = 0; $i < TOOLBAR_MAX_SLOTS; $i++) { + $rows['empty-' . $i] = array( + 'data' => array(array( + 'colspan' => 5, + 'data' => '' . t('Empty') . '', + )), + 'class' => array('toolbar-slot-empty'), + ); + } + $count_shortcuts = count(element_children($form[$status])); + if (!empty($count_shortcuts)) { + for ($i = 0; $i < min($count_shortcuts, TOOLBAR_MAX_SLOTS); $i++) { + $rows['empty-' . $i]['class'][] = 'toolbar-slot-hidden'; + } + } + } + } + $header = array(t('Name'), t('Weight'), t('Status'), array('data' => t('Operations'), 'colspan' => 2)); + return theme('table', $header, $rows, array('id' => 'shortcuts')); +} Index: modules/toolbar/toolbar.admin.js =================================================================== RCS file: modules/toolbar/toolbar.admin.js diff -N modules/toolbar/toolbar.admin.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/toolbar/toolbar.admin.js 31 Aug 2009 01:43:04 -0000 @@ -0,0 +1,100 @@ +// $Id: toolbar.js,v 1.10 2009/08/04 06:26:52 webchick Exp $ +(function ($) { + +/** + * Handle the concept of a fixed number of slots. + * + * This behavior is dependent on the tableDrag behavior, since it uses the + * objects initialized in that behavior to update the row. + */ +Drupal.behaviors.shortcutDrag = { + attach: function (context, settings) { + if (Drupal.tableDrag) { + var table = $('table#shortcuts'), + visibleLength = 0, + slots = 0, + tableDrag = Drupal.tableDrag.shortcuts; + $('> tbody > tr, > tr', table) + .filter(':visible') + .filter(':odd').filter('.odd') + .removeClass('odd').addClass('even') + .end().end() + .filter(':even').filter('.even') + .removeClass('even').addClass('odd') + .end().end() + .end() + .filter('.toolbar-slot-empty').each(function(index) { + if ($(this).is(':visible')) { + visibleLength++; + } + slots++; + }); + + // Add a handler for when a row is swapped. + tableDrag.row.prototype.onSwap = function (swappedRow) { + var disabledIndex = $(table).find('tr').index($(table).find('tr.toolbar-status-disabled')) - slots - 2, + count = 0; + $(table).find('tr.toolbar-status-enabled').nextAll().filter(':not(.toolbar-slot-empty)').each(function(index) { + if (index < disabledIndex) { + count++; + } + }); + var total = slots - count; + if (total == -1) { + var disabled = $(table).find('tr.toolbar-status-disabled'); + disabled.after(disabled.prevAll().filter(':not(.toolbar-slot-empty)').get(0)); + } + else if (total != visibleLength) { + if (total > visibleLength) { + // Less slots on screen than needed. + $('.toolbar-slot-empty:hidden:last').show(); + visibleLength++; + } + else { + // More slots on screen than needed. + $('.toolbar-slot-empty:visible:last').hide(); + visibleLength--; + } + } + }; + + // Add a handler so when a row is dropped, update fields dropped into new regions. + tableDrag.onDrop = function () { + // Use "status-message" row instead of "status" row because + // "status-{status_name}-message" is less prone to regexp match errors. + var statusRow = $(this.rowObject.element).prevAll('tr.toolbar-status').get(0); + var statusName = statusRow.className.replace(/([^ ]+[ ]+)*toolbar-status-([^ ]+)([ ]+[^ ]+)*/, '$2'); + var statusField = $('select.shortcut-status-select', this.rowObject.element); + statusField.val(statusName); + return true; + }; + + tableDrag.restripeTable = function () { + // :even and :odd are reversed because jQuery counts from 0 and + // we count from 1, so we're out of sync. + // Match immediate children of the parent element to allow nesting. + $('> tbody > tr:visible, > tr:visible', this.table) + .filter(':odd').filter('.odd') + .removeClass('odd').addClass('even') + .end().end() + .filter(':even').filter('.even') + .removeClass('even').addClass('odd'); + }; + } + } +}; + +/** + * Make it so when you enter text into the "New set" textfield, the + * corresponding radio button gets selected. + */ +Drupal.behaviors.newSet = { + attach: function (context, settings) { + var selectDefault = function() { + $($(this).parents('div.form-item').get(1)).find('> label > input').attr('checked', 'checked'); + }; + $('div.form-item-new input').focus(selectDefault).keyup(selectDefault); + } +}; + +})(jQuery); Index: modules/toolbar/toolbar.css =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.css,v retrieving revision 1.2 diff -u -p -r1.2 toolbar.css --- modules/toolbar/toolbar.css 29 Jul 2009 12:28:41 -0000 1.2 +++ modules/toolbar/toolbar.css 31 Aug 2009 01:43:04 -0000 @@ -123,6 +123,7 @@ div#toolbar div.toolbar-menu ul li a.act div#toolbar div.toolbar-shortcuts { position: relative; padding: 0 10px; + height: 50px; } div#toolbar div.toolbar-shortcuts ul { @@ -161,6 +162,10 @@ div#toolbar div.toolbar-shortcuts span.i -webkit-border-radius: 5px; } +div#toolbar a#toolbar-customize { + float: right; +} + /** * IE 6 Fixes. * Index: modules/toolbar/toolbar.info =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.info,v retrieving revision 1.2 diff -u -p -r1.2 toolbar.info --- modules/toolbar/toolbar.info 6 Jul 2009 13:54:21 -0000 1.2 +++ modules/toolbar/toolbar.info 31 Aug 2009 01:43:04 -0000 @@ -1,9 +1,9 @@ ; $Id: toolbar.info,v 1.2 2009/07/06 13:54:21 dries Exp $ name = Toolbar -description = Toolbar exposing the top level administration menu items +description = Toolbar exposing the top level administration menu items. core = 7.x package = Core version = VERSION files[] = toolbar.install files[] = toolbar.module -dependencies[] = menu +files[] = toolbar.admin.inc Index: modules/toolbar/toolbar.install =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.install,v retrieving revision 1.3 diff -u -p -r1.3 toolbar.install --- modules/toolbar/toolbar.install 30 Jul 2009 19:24:21 -0000 1.3 +++ modules/toolbar/toolbar.install 31 Aug 2009 01:43:04 -0000 @@ -7,51 +7,177 @@ */ /** - * Implementation of hook_install(). - * - * @todo - * Implement role based shortcut bars. + * Implement hook_install(). */ function toolbar_install() { - $t = get_t(); - $query = db_insert('menu_custom') - ->fields(array( - 'menu_name' => 'admin_shortcuts', - 'title' => $t('Administration shortcuts'), - 'description' => $t('The Admininstration shortcuts menu contains commonly used links for administrative tasks.') - )) - ->execute(); - - // Add starter convenience shortcuts. - menu_rebuild(); - $items = array( - 'node/add' => 'Add', - 'admin/content' => 'Find content', - 'admin' => 'Dashboard', + drupal_install_schema('toolbar'); + include_once DRUPAL_ROOT . '/modules/toolbar/toolbar.module'; + $sid = toolbar_set_save(array('name' => t('Default'))); + toolbar_shortcut_save(array( + 'sid' => $sid, + 'weight' => -50, + 'path' => 'node/add', + 'name' => t('Add'), + 'status' => 1, + )); + toolbar_shortcut_save(array( + 'sid' => $sid, + 'weight' => -49, + 'path' => 'admin/content', + 'name' => t('Find Content'), + 'status' => 1, + )); + toolbar_shortcut_save(array( + 'sid' => $sid, + 'weight' => -48, + 'path' => 'admin', + 'name' => t('Dashboard'), + 'status' => 1, + )); +} + +/** + * Implement hook_uninstall(). + */ +function toolbar_uninstall() { + drupal_uninstall_schema('toolbar'); +} + +/** + * Implement hook_schema(). + */ +function toolbar_schema() { + $schema = array(); + + $schema['toolbar_sets'] = array( + 'description' => 'Stores configuration options for toolbar shortcut sets.', + 'fields' => array( + 'sid' => array( + 'description' => 'The primary identifier for the set.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'name' => array( + 'description' => 'The set name.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + ), + 'primary key' => array('sid'), + 'indexes' => array( + 'name' => array('name'), + ), ); - $weight = -20; - foreach ($items as $path => $title) { - $link = array( - 'mlid' => 0, - 'link_title' => $title, - 'link_path' => $path, - 'router_path' => $path, - 'menu_name' => 'admin_shortcuts', - 'module' => 'menu', - 'weight' => $weight, - ); - - // Check for an existing menu item before attempting to create a new one. - $menu_link = db_query("SELECT mlid FROM {menu_links} WHERE link_path = :path AND menu_name = :menu_name", array( - ':path' => $link['link_path'], - ':menu_name' => $link['menu_name'] - )) - ->fetchField(); - if (!$menu_link) { - menu_link_save($link); - } - - // Increment weight so items can be displayed in desired order. - $weight++; - } + + $schema['toolbar_shortcuts'] = array( + 'description' => 'Stores shortcuts in toolbar sets.', + 'fields' => array( + 'scid' => array( + 'description' => 'The primary identifier for the shortcut.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'sid' => array( + 'description' => 'The {toolbar_sets}.sid for this shortcut.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'weight' => array( + 'description' => 'The weight of the set in the shortcut.', + 'type' => 'int', + 'unsigned' => FALSE, + 'not null' => TRUE, + 'default' => 0, + ), + 'path' => array( + 'description' => 'The path of the shortcut.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + 'name' => array( + 'description' => 'The name of the shortcut.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + ), + 'status' => array( + 'description' => 'Boolean indicating whether or not this shortcut is enabled.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('scid'), + 'indexes' => array( + 'sid' => array('sid'), + 'weight' => array('weight'), + ), + 'foreign keys' => array( + 'sid' => array('toolbar_sets' => 'sid'), + ), + ); + + $schema['toolbar_set_users'] = array( + 'description' => 'Maps users to toolbar sets.', + 'fields' => array( + 'uid' => array( + 'description' => 'The {user}.uid for this set.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'sid' => array( + 'description' => 'The {toolbar_sets}.sid for this user.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('uid'), + 'indexes' => array( + 'sid' => array('sid'), + ), + 'foreign keys' => array( + 'sid' => array('toolbar_sets' => 'sid'), + 'uid' => array('users' => 'uid'), + ), + ); + + $schema['toolbar_set_roles'] = array( + 'description' => 'Maps roles to toolbar sets.', + 'fields' => array( + 'rid' => array( + 'description' => 'The {role}.rid for this set.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'sid' => array( + 'description' => 'The {toolbar_sets}.sid for this role.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('rid'), + 'indexes' => array( + 'sid' => array('sid'), + ), + 'foreign keys' => array( + 'sid' => array('toolbar_sets' => 'sid'), + 'rid' => array('role' => 'rid'), + ), + ); + + return $schema; } Index: modules/toolbar/toolbar.module =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v retrieving revision 1.6 diff -u -p -r1.6 toolbar.module --- modules/toolbar/toolbar.module 22 Aug 2009 14:34:22 -0000 1.6 +++ modules/toolbar/toolbar.module 31 Aug 2009 01:43:04 -0000 @@ -7,7 +7,12 @@ */ /** - * Implementation of hook_permission(). + * Maximum number of slots in the toolbar. + */ +define('TOOLBAR_MAX_SLOTS', 7); + +/** + * Implement hook_permission(). */ function toolbar_permission() { return array( @@ -15,6 +20,14 @@ function toolbar_permission() { 'title' => t('Access administration toolbar'), 'description' => t('Access the persistent administration toolbar displayed on all pages.'), ), + 'customize toolbar shortcuts' => array( + 'title' => t('Customize toolbar shortcuts'), + 'description' => t('Customize the shortcuts in the toolbar displayed on all pages.') + ), + 'choose toolbar shortcut set' => array( + 'title' => t('Choose toolbar shortcut set'), + 'description' => t('Choose which set of toolbar shortcuts appear in the user\'s toolbar.') + ), ); } @@ -27,6 +40,77 @@ function toolbar_theme($existing, $type, 'template' => 'toolbar', 'path' => drupal_get_path('module', 'toolbar'), ); + $items['toolbar_admin_shortcuts_table'] = array( + 'arguments' => array('form' => NULL), + 'file' => 'toolbar.admin.inc', + ); + $items['toolbar_admin_shortcuts_switch_set'] = array( + 'arguments' => array('form' => NULL), + 'file' => 'toolbar.admin.inc', + ); + return $items; +} + +/** + * Implement hook_menu(). + */ +function toolbar_menu() { + $items = array(); + + $items['admin/settings/shortcuts'] = array( + 'title' => 'Shortcuts', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('toolbar_admin_shortcuts'), + 'access arguments' => array('customize toolbar shortcuts'), + 'type' => MENU_NORMAL_ITEM, + 'file' => 'toolbar.admin.inc', + ); + + $items['admin/settings/shortcuts/add-link'] = array( + 'title' => 'Add link', + 'page callback' => 'toolbar_admin_shortcut_add_link', + 'access arguments' => array('customize toolbar shortcuts'), + 'type' => MENU_NORMAL_ITEM, + 'file' => 'toolbar.admin.inc', + ); + + $items['admin/settings/shortcuts/switch-set'] = array( + 'title' => 'Switch set', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('toolbar_admin_shortcuts_switch_set'), + 'access arguments' => array('choose toolbar shortcut set'), + 'type' => MENU_NORMAL_ITEM, + 'file' => 'toolbar.admin.inc', + ); + + $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut'] = array( + 'page callback' => 'drupal_get_form', + 'page arguments' => array('toolbar_admin_shortcut_edit', 4), + 'access arguments' => array('customize toolbar shortcuts'), + 'type' => MENU_CALLBACK, + 'file' => 'toolbar.admin.inc', + ); + + $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut/edit'] = array( + 'title' => 'Edit', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('toolbar_admin_shortcut_edit', 4), + 'access arguments' => array('customize toolbar shortcuts'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'file' => 'toolbar.admin.inc', + 'weight' => 0, + ); + + $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut/delete'] = array( + 'title' => 'Delete', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('toolbar_admin_shortcut_delete', 4), + 'access arguments' => array('customize toolbar shortcuts'), + 'type' => MENU_LOCAL_TASK, + 'file' => 'toolbar.admin.inc', + 'weight' => 1, + ); + return $items; } @@ -39,6 +123,20 @@ function toolbar_page_alter(&$page) { if (user_access('access toolbar')) { $page['page_top']['toolbar'] = toolbar_build(); } + if (user_access('customize toolbar shortcuts')) { + // $_GET['q'] is the unaliased version. + $get = $_GET; + unset($get['q']); + $link = $_GET['q']; + if (!empty($get)) { + $link .= '?' . http_build_query($get); + } + $query = array( + 'link' => $link, + 'name' => drupal_get_title(), + ); + $page['content']['add_shortcut']['#markup'] = l('+ Add to shortcuts', 'admin/settings/shortcuts/add-link', array('query' => http_build_query($query))); + } } /** @@ -53,6 +151,121 @@ function toolbar_preprocess_page(&$vars) } /** + * Find the set for the current user. + */ +function toolbar_current_set($account = NULL) { + if (!isset($account)) { + global $user; + $account = $user; + } + $user_set = db_select('toolbar_set_users') + ->fields('toolbar_set_users') + ->condition('uid', $account->uid) + ->execute() + ->fetchAssoc(); + if ($user_set) { + return $user_set['sid']; + } + return 1; +} + +/** + * Load a toolbar shortcut by ID. + */ +function toolbar_shortcut_load($scid) { + return db_select('toolbar_shortcuts') + ->fields('toolbar_shortcuts') + ->condition('scid', $scid) + ->execute() + ->fetchAssoc(); +} + +/** + * Save a toolbar shortcut. + */ +function toolbar_shortcut_save($shortcut) { + if (isset($shortcut['scid'])) { + $scid = $shortcut['scid']; + unset($shortcut['scid']); + db_update('toolbar_shortcuts') + ->fields($shortcut) + ->condition('scid', $scid) + ->execute(); + return $scid; + } + else { + return db_insert('toolbar_shortcuts') + ->fields($shortcut) + ->execute(); + } +} + +/** + * Delete a toolbar shortcut. + */ +function toolbar_shortcut_delete($scid) { + return db_delete('toolbar_shortcuts') + ->condition('scid', $scid) + ->execute(); +} + +/** + * List all toolbar sets. + */ +function toolbar_set_list() { + return db_select('toolbar_sets') + ->fields('toolbar_sets') + ->execute() + ->fetchAllAssoc('sid', PDO::FETCH_ASSOC); +} + +/** + * Load a toolbar set by ID. + * + * @param $sid + * The ID of the set to load. + * @param $enabled_shortcuts + * Whether to return only enabled shortcuts (defaults to FALSE). + */ +function toolbar_set_load($sid, $enabled_shortcuts = FALSE) { + $set = db_select('toolbar_sets') + ->fields('toolbar_sets') + ->condition('sid', $sid) + ->execute() + ->fetchAssoc(); + $query = db_select('toolbar_shortcuts') + ->fields('toolbar_shortcuts') + ->condition('sid', $sid); + if ($enabled_shortcuts) { + $query->condition('status', 1); + } + $set['shortcuts'] = $query->execute() + ->fetchAllAssoc('scid', PDO::FETCH_ASSOC); + uasort($set['shortcuts'], 'drupal_sort_weight'); + return $set; +} + +/** + * Save a toolbar set. + */ +function toolbar_set_save($set) { + if (isset($set['sid'])) { + $sid = $set['sid']; + unset($set['sid']); + db_update('toolbar_sets') + ->fields($set) + ->condition('sid', $sid) + ->execute; + return $sid; + } + else { + return db_insert('toolbar_sets') + ->fields($set) + ->execute(); + } +} + +/** * Build the admin menu as a structured array ready for drupal_render(). */ function toolbar_build() { @@ -96,12 +309,33 @@ function toolbar_build() { ); // Add convenience shortcut links. - $shortcuts = menu_tree_all_data('admin_shortcuts'); - $shortcuts = toolbar_menu_navigation_links($shortcuts); + $set = toolbar_set_load(toolbar_current_set(), TRUE); + $shortcuts = array(); + foreach ($set['shortcuts'] as $shortcut) { + $class = ''; + // Make sure we have a path specific ID in place, so we can attach icons + // and behaviors to the items. + $id = str_replace(array('/', '<', '>'), array('-', '', ''), $shortcut['path']); + $class = ' path-' . $id; + if (toolbar_in_active_trail($shortcut['path'])) { + $class .= ' active-trail'; + } + $shortcuts[$shortcut['scid']] = array( + 'href' => $shortcut['path'], + 'title' => '' . $shortcut['name'], + 'html' => TRUE, + 'attributes' => array('id' => 'toolbar-link-' . $id, 'class' => array('to-overlay')), + ); + } $build['toolbar_shortcuts'] = array( - '#theme' => 'links', - '#links' => $shortcuts, - '#attributes' => array('id' => 'toolbar-shortcuts'), + 'shortcuts' => array( + '#theme' => 'links', + '#links' => $shortcuts, + '#attributes' => array('id' => 'toolbar-shortcuts'), + ), + 'configure' => array( + '#markup' => l(t('edit shortcuts'), 'admin/settings/shortcuts', array('attributes' => array('id' => 'toolbar-customize'))), + ), ); return $build; @@ -153,7 +387,7 @@ function toolbar_menu_navigation_links($ if (toolbar_in_active_trail($item['link']['href'])) { $class .= ' active-trail'; } - $links['menu-' . $item['link']['mlid'] . $class] = $link; + $links[$item['link']['mlid']] = $link; } } return $links;