diff --git a/menu_block.admin.inc b/menu_block.admin.inc index 98f3bbb..ed9c6aa 100644 --- a/menu_block.admin.inc +++ b/menu_block.admin.inc @@ -33,94 +33,25 @@ function _menu_block_theme(&$existing, $type, $theme, $path) { * Implements hook_ctools_plugin_directory(). */ function _menu_block_ctools_plugin_directory($module, $plugin) { - if ($plugin == 'content_types') { - return 'plugins/' . $plugin; + if ($module == 'ctools' && !empty($plugin)) { + return "plugins/{$plugin}"; } } /** - * Menu callback: display the menu block addition form. - * - * @see menu_block_add_block_form_submit() - */ -function menu_block_add_block_form($form, &$form_state) { - module_load_include('inc', 'block', 'block.admin'); - $form = block_admin_configure($form, $form_state, 'menu_block', NULL); - - // Other modules should be able to use hook_form_block_add_block_form_alter() - // to modify this form, so add a base form ID. - $form_state['build_info']['base_form_id'] = 'block_add_block_form'; - - // Prevent block_add_block_form_validate/submit() from being automatically - // added because of the base form ID by providing these handlers manually. - $form['#validate'] = array(); - $form['#submit'] = array('menu_block_add_block_form_submit'); - - return $form; -} - -/** - * Save the new menu block. - */ -function menu_block_add_block_form_submit($form, &$form_state) { - // Determine the delta of the new block. - $block_ids = variable_get('menu_block_ids', array()); - $delta = empty($block_ids) ? 1 : max($block_ids) + 1; - $form_state['values']['delta'] = $delta; - - // Save the new array of blocks IDs. - $block_ids[] = $delta; - variable_set('menu_block_ids', $block_ids); - - // Save the block configuration. - menu_block_block_save($delta, $form_state['values']); - - // Run the normal new block submission (borrowed from block_add_block_form_submit). - $query = db_insert('block')->fields(array('visibility', 'pages', 'custom', 'title', 'module', 'theme', 'region', 'status', 'weight', 'delta', 'cache')); - foreach (list_themes() as $key => $theme) { - if ($theme->status) { - $region = !empty($form_state['values']['regions'][$theme->name]) ? $form_state['values']['regions'][$theme->name] : BLOCK_REGION_NONE; - $query->values(array( - 'visibility' => (int) $form_state['values']['visibility'], - 'pages' => trim($form_state['values']['pages']), - 'custom' => (int) $form_state['values']['custom'], - 'title' => $form_state['values']['title'], - 'module' => $form_state['values']['module'], - 'theme' => $theme->name, - 'region' => ($region == BLOCK_REGION_NONE ? '' : $region), - 'status' => 0, - 'status' => (int) ($region != BLOCK_REGION_NONE), - 'weight' => 0, - 'delta' => $delta, - 'cache' => DRUPAL_NO_CACHE, - )); - } - } - $query->execute(); - - $query = db_insert('block_role')->fields(array('rid', 'module', 'delta')); - foreach (array_filter($form_state['values']['roles']) as $rid) { - $query->values(array( - 'rid' => $rid, - 'module' => $form_state['values']['module'], - 'delta' => $delta, - )); - } - $query->execute(); - - drupal_set_message(t('The block has been created.')); - cache_clear_all(); - $form_state['redirect'] = 'admin/structure/block'; -} - -/** * Alters the block admin form to add delete links next to menu blocks. */ function _menu_block_form_block_admin_display_form_alter(&$form, $form_state) { - $blocks = module_invoke_all('menu_block_blocks'); - foreach (variable_get('menu_block_ids', array()) AS $delta) { - if (empty($blocks[$delta])) { - $form['blocks']['menu_block_' . $delta]['delete'] = array('#type' => 'link', '#title' => t('delete'), '#href' => 'admin/structure/block/delete-menu-block/' . $delta); + foreach (menu_block_load_all() as $delta => $menu_block) { + if ('Default' !== $menu_block->type) { + $form['blocks']['menu_block_' . $delta]['delete'] = array( + '#type' => 'link', + '#title' => $menu_block->type == 'Overridden' ? t('revert') : t('delete'), + '#href' => url('admin/structure/menu_block/list/' . $delta . '/' . ($menu_block->type == 'Overridden' ? 'revert' : 'delete'), array( + 'absolute' => TRUE, + 'query' => array('destination' => ltrim(request_uri(), '/')), + )), + ); } } if (variable_get('menu_block_suppress_core')) { @@ -186,12 +117,8 @@ function menu_block_delete_submit($form, &$form_state) { */ function _menu_block_block_info() { $blocks = array(); - $deltas = variable_get('menu_block_ids', array()); - foreach (array_keys(module_invoke_all('menu_block_blocks')) as $delta) { - $deltas[] = $delta; - } - foreach ($deltas AS $delta) { - $blocks[$delta]['info'] = _menu_block_format_title(menu_block_get_config($delta)); + foreach (menu_block_load_all() as $delta => $menu_block) { + $blocks[$delta]['info'] = check_plain($menu_block->label); // Menu blocks can't be cached because each menu item can have // a custom access callback. menu.inc manages its own caching. $blocks[$delta]['cache'] = DRUPAL_NO_CACHE; @@ -200,299 +127,35 @@ function _menu_block_block_info() { } /** - * Return the title of the block. - * - * @param $config - * array The configuration of the menu block. - * @return - * string The title of the block. - */ -function _menu_block_format_title($config) { - // If an administrative title is specified, use it. - if (!empty($config['admin_title'])) { - return check_plain($config['admin_title']); - } - $menus = menu_block_get_all_menus(); - $menus[MENU_TREE__CURRENT_PAGE_MENU] = t('Current menu'); - if (empty($config['menu_name']) || empty($menus[$config['menu_name']])) { - $title = t('Unconfigured menu block'); - } - else { - // Show the configured levels in the block info - $replacements = array( - '@menu_name' => $menus[$config['menu_name']], - '@level1' => $config['level'], - '@level2' => $config['level'] + $config['depth'] - 1, - ); - if ($config['parent_mlid']) { - $parent_item = menu_link_load($config['parent_mlid']); - $replacements['@menu_name'] = $parent_item['title']; - } - if ($config['follow']) { - $title = t('@menu_name (active menu item)', $replacements); - } - elseif ($config['depth'] == 1) { - $title = t('@menu_name (level @level1)', $replacements); - } - elseif ($config['depth']) { - if ($config['expanded']) { - $title = t('@menu_name (expanded levels @level1-@level2)', $replacements); - } - else { - $title = t('@menu_name (levels @level1-@level2)', $replacements); - } - } - else { - if ($config['expanded']) { - $title = t('@menu_name (expanded levels @level1+)', $replacements); - } - else { - $title = t('@menu_name (levels @level1+)', $replacements); - } - } - } - return $title; -} - -/** * Implements hook_block_configure(). */ function _menu_block_block_configure($delta = '') { - // Create a pseudo form state. - $form_state = array('values' => menu_block_get_config($delta)); - return menu_block_configure_form(array(), $form_state); -} + ctools_include('export'); + module_load_include('inc', 'menu_block', 'plugins/export_ui/menu_block'); -/** - * Returns the configuration form for a menu tree. - * - * @param $form_state - * array An associated array of configuration options should be present in the - * 'values' key. If none are given, default configuration is assumed. - * @return - * array The form in Form API format. - */ -function menu_block_configure_form($form, &$form_state) { - $config = array(); - // Get the config from the form state. - if (!empty($form_state['values'])) { - $config = $form_state['values']; - if (!empty($config['parent'])) { - list($config['menu_name'], $config['parent_mlid']) = explode(':', $config['parent']); - } - } - // Merge in the default configuration. - $config += menu_block_get_config(); - - // Don't display the config form if this delta is exported to code. - if (!empty($config['exported_to_code'])) { - $form['exported_message'] = array( - '#markup' => '

' . t('Configuration is being provided by code.') . '

', - ); - return $form; - } - - // Build the standard form. - $form['#attached']['js'][] = drupal_get_path('module', 'menu_block') . '/menu-block.js'; - $form['#attached']['css'][] = drupal_get_path('module', 'menu_block') . '/menu-block-admin.css'; - $form['#attached']['library'][] = array('system', 'ui.button'); - - $form['menu-block-wrapper-start'] = array( - '#markup' => ''); - - // Set visibility of advanced options. - foreach (array('title_link', 'follow', 'follow_parent', 'expanded', 'sort', 'parent_mlid') as $key) { - $form[$key]['#states']['visible'][':input[name=display_options]'] = array('value' => 'advanced'); - } - if ($config['title_link'] || $follow || $config['expanded'] || $config['sort'] || $config['parent_mlid']) { - $form['display_options']['#default_value'] = 'advanced'; - } + menu_block_export_ui_form($form, $form_state); return $form; } /** - * Validates the parent element of the block configuration form. - */ -function menu_block_configure_form_parent_validate($element, &$form_state) { - // Determine the fixed parent item's menu and mlid. - list($menu_name, $parent_mlid) = explode(':', $form_state['values']['parent_mlid']); - if ($parent_mlid) { - // If mlid is set, its menu overrides the menu_name option. - $form_state['values']['menu_name'] = $menu_name; - } - else { - // Otherwise the menu_name overrides the parent item option. - $form_state['values']['parent_mlid'] = $menu_name . ':0'; - } - // The value of "parent" stored in the database/config array is the menu name - // combined with the optional parent menu item's mlid. - $form_state['values']['parent'] = $form_state['values']['parent_mlid']; -} - -/** - * Validates the follow element of the block configuration form. - */ -function menu_block_configure_form_follow_validate($element, &$form_state) { - // The value of "follow" stored in the database/config array is either FALSE - // or the value of the "follow_parent" form element. - if ($form_state['values']['follow'] && !empty($form_state['values']['follow_parent'])) { - $form_state['values']['follow'] = $form_state['values']['follow_parent']; - } -} - -/** * Implements hook_block_save(). */ function _menu_block_block_save($delta = '', $edit = array()) { if (!empty($delta)) { - // Don't save values for an exported block. - $config = menu_block_get_config($delta); - if (empty($config['exported_to_code'])) { - variable_set("menu_block_{$delta}_title_link", $edit['title_link']); - variable_set("menu_block_{$delta}_admin_title", $edit['admin_title']); - variable_set("menu_block_{$delta}_parent", $edit['parent']); - variable_set("menu_block_{$delta}_level", $edit['level']); - variable_set("menu_block_{$delta}_follow", $edit['follow']); - variable_set("menu_block_{$delta}_depth", $edit['depth']); - variable_set("menu_block_{$delta}_expanded", $edit['expanded']); - variable_set("menu_block_{$delta}_sort", $edit['sort']); + ctools_include('export'); + $menu_block = ctools_export_crud_load('menu_blocks', $delta); + foreach (array_keys((array) $menu_block) as $key) { + if (isset($edit[$key])) { + $menu_block->{$key} = $edit[$key]; + } } + ctools_export_crud_save('menu_blocks', $menu_block); } } diff --git a/menu_block.info b/menu_block.info index 72cd37d..641c012 100644 --- a/menu_block.info +++ b/menu_block.info @@ -2,6 +2,7 @@ name = "Menu Block" description = "Provides configurable blocks of menu items." core = 7.x +dependencies[] = ctools dependencies[] = menu (>7.11) files[] = menu_block.module diff --git a/menu_block.install b/menu_block.install index 8132465..25a85c5 100644 --- a/menu_block.install +++ b/menu_block.install @@ -5,23 +5,103 @@ */ /** + * Implements hook_install(). + */ +function menu_block_schema() { + $schema['menu_blocks'] = array( + 'export' => array( + 'key' => 'name', + 'key name' => 'Name', + 'primary key' => 'name', + 'identifier' => 'menu_block', + 'default hook' => 'menu_block_defaults', + 'api' => array( + 'owner' => 'menu_block', + 'api' => 'menu_block', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'name' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ), + 'label' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ), + 'description' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => FALSE, + 'default' => '', + ), + 'depth' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'expanded' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'follow' => array( + 'type' => 'varchar', + 'length' => 16, + 'default' => '', + ), + 'level' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 1, + ), + 'parent' => array( + 'type' => 'varchar', + 'length' => 64, + 'default' => '', + ), + 'sort' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'title_link' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + ), + 'primary key' => array('name'), + ); + + return $schema; +} + +/** * Implements hook_uninstall(). */ function menu_block_uninstall() { // Delete menu block variables. - foreach (variable_get('menu_block_ids', array()) AS $delta) { - variable_del("menu_block_{$delta}_title_link"); - variable_del("menu_block_{$delta}_admin_title"); - variable_del("menu_block_{$delta}_parent"); - variable_del("menu_block_{$delta}_level"); - variable_del("menu_block_{$delta}_follow"); - variable_del("menu_block_{$delta}_depth"); - variable_del("menu_block_{$delta}_expanded"); - variable_del("menu_block_{$delta}_sort"); - } - variable_del('menu_block_ids'); + // foreach (variable_get('menu_block_ids', array()) AS $delta) { + // variable_del("menu_block_{$delta}_title_link"); + // variable_del("menu_block_{$delta}_admin_title"); + // variable_del("menu_block_{$delta}_parent"); + // variable_del("menu_block_{$delta}_level"); + // variable_del("menu_block_{$delta}_follow"); + // variable_del("menu_block_{$delta}_depth"); + // variable_del("menu_block_{$delta}_expanded"); + // variable_del("menu_block_{$delta}_sort"); + // } + // variable_del('menu_block_ids'); variable_del('menu_block_suppress_core'); variable_del('menu_block_menu_order'); + // Remove block configurations. db_delete('block') ->condition('module', 'menu_block') @@ -29,6 +109,8 @@ function menu_block_uninstall() { db_delete('block_role') ->condition('module', 'menu_block') ->execute(); + + // Clear all cache. cache_clear_all(); } @@ -40,13 +122,6 @@ function menu_block_enable() { } /** - * Implements hook_install(). - */ -function menu_block_install() { - // No-op. -} - -/** * Converts pre-5.x-1.0 block names to the new format. */ function menu_block_update_5100() { @@ -196,3 +271,110 @@ function menu_block_fix_custom_menus() { function menu_block_update_7202() { menu_block_fix_custom_menus(); } + +/** + * Add database table, migrate variables into database and enable CTools if + * availble. + */ +function menu_block_update_7203() { + // Add database table. + $schema['menu_blocks'] = array( + 'fields' => array( + 'name' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ), + 'label' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ), + 'description' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => FALSE, + 'default' => '', + ), + 'depth' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'expanded' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'follow' => array( + 'type' => 'varchar', + 'length' => 16, + 'default' => '', + ), + 'level' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 1, + ), + 'parent' => array( + 'type' => 'varchar', + 'length' => 64, + 'default' => '', + ), + 'sort' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + 'title_link' => array( + 'type' => 'int', + 'length' => 1, + 'default' => 0, + ), + ), + 'primary key' => array('name'), + ); + db_create_table('menu_blocks', $schema['menu_blocks']); + + // Migrate variables into database. + foreach (variable_get('menu_block_ids', array()) AS $delta) { + $config = menu_block_get_config($delta); + db_insert('menu_blocks') + ->fields(array( + 'name' => $delta, + 'label' => $config['admin_title'], + 'description' => NULL, + 'depth' => $config['depth'], + 'expanded' => $config['expanded'], + 'follow' => $config['active'], + 'level' => $config['level'], + 'parent' => "{$config['menu_name']}:{$config['parent_mlid']}", + 'sort' => $config['sort'], + 'title_link' => $config['title_link'], + )) + ->execute(); + + // Delete old variables. + variable_del("menu_block_{$delta}_title_link"); + variable_del("menu_block_{$delta}_admin_title"); + variable_del("menu_block_{$delta}_parent"); + variable_del("menu_block_{$delta}_level"); + variable_del("menu_block_{$delta}_follow"); + variable_del("menu_block_{$delta}_depth"); + variable_del("menu_block_{$delta}_expanded"); + variable_del("menu_block_{$delta}_sort"); + } + variable_del('menu_block_ids'); + + // Enable CTools if availble. + if (!module_exists('ctools')) { + module_enable(array('ctools')); + if (!module_exists('ctools')) { + drupal_set_message(t('The Chaos tool suite (ctools) module is required for Menu Block. Menu Block has been disabled.')); + module_disable(array('menu_block')); + } + } + drupal_flush_all_caches(); +} diff --git a/menu_block.module b/menu_block.module index 83cf0c9..0de3a64 100644 --- a/menu_block.module +++ b/menu_block.module @@ -39,13 +39,12 @@ function menu_block_ctools_plugin_directory($module, $plugin) { * Implements hook_menu(). */ function menu_block_menu() { - // @todo Remove this check if block module is re-added as a dependency. if (module_exists('block')) { $items['admin/structure/block/add-menu-block'] = array( 'title' => 'Add menu block', 'description' => 'Add a new menu block.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('menu_block_add_block_form'), + 'page callback' => 'drupal_goto', + 'page arguments' => array('admin/structure/menu_block/add'), 'access arguments' => array('administer blocks'), 'type' => MENU_LOCAL_ACTION, 'file' => 'menu_block.admin.inc', @@ -56,31 +55,23 @@ function menu_block_menu() { $items['admin/structure/block/list/' . $key . '/add-menu-block'] = array( 'title' => 'Add menu block', 'description' => 'Add a new menu block.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('menu_block_add_block_form'), + 'page callback' => 'drupal_goto', + 'page arguments' => array('admin/structure/menu_block/add'), 'access arguments' => array('administer blocks'), 'type' => MENU_LOCAL_ACTION, 'file' => 'menu_block.admin.inc', ); } } - $items['admin/structure/block/delete-menu-block'] = array( - 'title' => 'Delete menu block', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('menu_block_delete'), - 'access arguments' => array('administer blocks'), - 'type' => MENU_CALLBACK, - 'file' => 'menu_block.admin.inc', - ); } - $items['admin/config/user-interface/menu-block'] = array( - 'title' => 'Menu block', + $items['admin/structure/menu_block/settings'] = array( + 'title' => 'Settings', 'description' => 'Configure menu block.', 'page callback' => 'drupal_get_form', 'page arguments' => array('menu_block_admin_settings_form'), 'access arguments' => array('administer blocks'), - 'type' => MENU_NORMAL_ITEM, + 'type' => MENU_LOCAL_TASK, 'file' => 'menu_block.admin.inc', ); return $items; @@ -133,6 +124,22 @@ function menu_block_block_view($delta = '') { } /** + * CRUD function; Load all menu blocks. + */ +function menu_block_load_all($disabled = FALSE) { + $menu_blocks = array(); + + ctools_include('export'); + foreach (ctools_export_crud_load_all('menu_blocks') as $menu_block) { + if (empty($menu_block->disabled) || TRUE == $disabled) { + $menu_blocks[$menu_block->name] = $menu_block; + } + } + + return $menu_blocks; +} + +/** * Process variables for menu-block-wrapper.tpl.php. * * @see menu-block-wrapper.tpl.php @@ -181,6 +188,8 @@ function menu_block_get_all_menus() { * array An associated array of configuration options. */ function menu_block_get_config($delta = NULL) { + watchdog('menu_block', 'menu_block_get_config() is deprecated and will be removed in the future'); + $config = array( 'delta' => $delta, 'menu_name' => 'main-menu', diff --git a/plugins/export_ui/menu_block.inc b/plugins/export_ui/menu_block.inc new file mode 100755 index 0000000..0a516ea --- /dev/null +++ b/plugins/export_ui/menu_block.inc @@ -0,0 +1,218 @@ + 'menu_blocks', + + 'menu' => array( + 'menu prefix' => 'admin/structure', + 'menu item' => 'menu_block', + 'menu title' => 'Menu Blocks', + 'menu description' => 'Administer Menu Blocks.', + ), + + 'title singular' => t('menu block'), + 'title singular proper' => t('Menu Block'), + 'title plural' => t('menu blocks'), + 'title plural proper' => t('Menu Blocks'), + + 'form' => array( + 'settings' => 'menu_block_export_ui_form', + ), + + 'export' => array( + 'admin_title' => 'label', + 'admin_description' => 'description', + ), + ); +} + +/** + * Menu Block settings form. + */ +function menu_block_export_ui_form(&$form, &$form_state) { + list($form_state['item']->menu_name, $form_state['item']->parent_mlid) = explode(':', !empty($form_state['item']->parent) ? $form_state['item']->parent : 'main-menu:0'); + + $form['#attached']['js'][] = drupal_get_path('module', 'menu_block') . '/menu-block.js'; + $form['#attached']['css'][] = drupal_get_path('module', 'menu_block') . '/menu-block-admin.css'; + $form['#attached']['library'][] = array('system', 'ui.button'); + + $form['menu-block-wrapper-start'] = array( + '#markup' => ''); + + // Set visibility of advanced options. + foreach (array('title_link', 'follow', 'follow_parent', 'expanded', 'sort', 'parent_mlid') as $key) { + $form[$key]['#states']['visible'][':input[name=display_options]'] = array('value' => 'advanced'); + } + if ($form_state['item']->title_link || $form_state['item']->follow || $form_state['item']->expanded || $form_state['item']->sort || $form_state['item']->parent) { + $form['display_options']['#default_value'] = 'advanced'; + } +} + +/** + * Validates the parent element of the block configuration form. + */ +function menu_block_configure_form_parent_validate($element, &$form_state) { + // Determine the fixed parent item's menu and mlid. + list($menu_name, $parent_mlid) = explode(':', $form_state['values']['parent_mlid']); + if ($parent_mlid) { + // If mlid is set, its menu overrides the menu_name option. + $form_state['values']['menu_name'] = $menu_name; + } + else { + // Otherwise the menu_name overrides the parent item option. + $form_state['values']['parent_mlid'] = $menu_name . ':0'; + } + // The value of "parent" stored in the database/config array is the menu name + // combined with the optional parent menu item's mlid. + $form_state['values']['parent'] = $form_state['values']['parent_mlid']; +} + +/** + * Validates the follow element of the block configuration form. + */ +function menu_block_configure_form_follow_validate($element, &$form_state) { + // The value of "follow" stored in the database/config array is either FALSE + // or the value of the "follow_parent" form element. + if ($form_state['values']['follow'] && !empty($form_state['values']['follow_parent'])) { + $form_state['values']['follow'] = $form_state['values']['follow_parent']; + } +}