$theme) { if ($theme->status) { db_query("INSERT INTO {blocks} (visibility, pages, custom, title, module, theme, status, weight, delta, cache) VALUES(%d, '%s', %d, '%s', '%s', '%s', %d, %d, %d, %d)", $form_state['values']['visibility'], trim($form_state['values']['pages']), $form_state['values']['custom'], $form_state['values']['title'], $form_state['values']['module'], $theme->name, 0, 0, $delta, BLOCK_NO_CACHE); } } foreach (array_filter($form_state['values']['roles']) as $rid) { db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_state['values']['module'], $delta); } drupal_set_message(t('The block has been created.')); cache_clear_all(); $form_state['redirect'] = 'admin/build/block'; return; } /** * 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) { foreach (variable_get('menu_block_ids', array()) AS $delta) { $form['menu_block_' . $delta]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete-menu-block/'. $delta)); } } /** * Menu callback: confirm deletion of menu blocks. */ function menu_block_delete(&$form_state, $delta = 0) { $title = _menu_block_format_title(menu_block_get_config($delta)); $form['block_title'] = array('#type' => 'hidden', '#value' => $title); $form['delta'] = array('#type' => 'hidden', '#value' => $delta); return confirm_form($form, t('Are you sure you want to delete the "%name" block?', array('%name' => $title)), 'admin/build/block', NULL, t('Delete'), t('Cancel')); } /** * Deletion of menu blocks. */ function menu_block_delete_submit($form, &$form_state) { // Remove the menu block configuration variables. $delta = $form_state['values']['delta']; $block_ids = variable_get('menu_block_ids', array()); unset($block_ids[array_search($delta, $block_ids)]); sort($block_ids); variable_set('menu_block_ids', $block_ids); 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"); db_query("DELETE FROM {blocks} WHERE module = 'menu_block' AND delta = %d", $delta); db_query("DELETE FROM {blocks_roles} WHERE module = 'menu_block' AND delta = %d", $delta); drupal_set_message(t('The "%name" block has been removed.', array('%name' => $form_state['values']['block_title']))); cache_clear_all(); $form_state['redirect'] = 'admin/build/block'; return; } /** * Returns the 'list' $op info for hook_block(). */ function _menu_block_block_list() { $blocks = array(); foreach (variable_get('menu_block_ids', array()) AS $delta) { $blocks[$delta]['info'] = _menu_block_format_title(menu_block_get_config($delta)); // 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'] = BLOCK_NO_CACHE; } return $blocks; } /** * 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; } /** * Returns the 'configure' $op info for hook_block(). */ 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($form_state); } /** * 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_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. drupal_add_js(drupal_get_path('module', 'menu_block') . '/menu-block.js'); drupal_add_css(drupal_get_path('module', 'menu_block') . '/menu-block-admin.css'); $form['menu-block-wrapper-start'] = array( '#value' => ''); 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']; } } /** * Returns the 'save' $op info for hook_block(). */ function _menu_block_block_save($delta, $edit) { 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']); } /** * Menu block admin settings form. * * @return * The settings form used by Menu block. */ function menu_block_admin_settings_form($form_state) { // Retrieve core's menus. $menus = menu_get_menus(); // Include book support. if (module_exists('book')) { module_load_include('inc', 'menu_block', 'menu_block.book'); } // Retrieve all the menu names provided by hook_menu_block_get_sort_menus(). $menus = array_merge($menus, module_invoke_all('menu_block_get_sort_menus')); asort($menus); // Load stored configuration. $menu_order = variable_get('menu_block_menu_order', array('primary-links' => '', 'secondary-links' => '')); // Remove any menus no longer in the list of all menus. foreach (array_keys($menu_order) as $menu) { if (!isset($menus[$menu])) { unset($menu_order[$menu]); } } // Merge the saved configuration with any un-configured menus. $all_menus = $menu_order + $menus; $form['heading'] = array( '#value' => '

' . t('If a block is configured to use "the menu selected by the page", the block will be generated from the first "available" menu that contains a link to the page.') . '

', ); // Orderable list of menu selections. $form['menu_order'] = array( '#tree' => TRUE, '#theme' => 'menu_block_menu_order', ); $order = 0; $total_menus = count($all_menus); foreach (array_keys($all_menus) as $menu_name) { $form['menu_order'][$menu_name] = array( 'title' => array( '#value' => check_plain($menus[$menu_name]), ), 'available' => array( '#type' => 'checkbox', '#attributes' => array('title' => t('Select from the @menu_name menu', array('@menu_name' => $menus[$menu_name]))), '#default_value' => isset($menu_order[$menu_name]), ), 'weight' => array( '#type' => 'weight', '#default_value' => $order - $total_menus, '#delta' => $total_menus, '#id' => 'edit-menu-block-menus-' . $menu_name, ), ); $order++; } $form['footer_note'] = array( '#value' => '

' . t('The above list will not affect menu blocks that are configured to use a specific menu.') . '

', ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration'), ); return $form; } /** * Form submission handler. */ function menu_block_admin_settings_form_submit($form, &$form_state) { $menu_order = array(); foreach ($form_state['values']['menu_order'] AS $menu_name => $row) { if ($row['available']) { // Add available menu and its weight to list. $menu_order[$menu_name] = (int) $row['weight']; } } // Sort the keys by the weight stored in the value. asort($menu_order); foreach ($menu_order AS $menu_name => $weight) { // Now that the array is sorted, the weight is redundant data. $menu_order[$menu_name] = ''; } variable_set('menu_block_menu_order', $menu_order); } /** * Theme a drag-to-reorder table of menu selection checkboxes. */ function theme_menu_block_menu_order($element) { drupal_add_tabledrag('menu-block-menus', 'order', 'sibling', 'menu-weight'); $header = array( t('Menu'), t('Available'), t('Weight'), ); // Generate table of draggable menu names. $rows = array(); foreach (element_children($element) as $menu_name) { $element[$menu_name]['weight']['#attributes']['class'] = 'menu-weight'; $rows[] = array( 'data' => array( drupal_render($element[$menu_name]['title']), drupal_render($element[$menu_name]['available']), drupal_render($element[$menu_name]['weight']), ), 'class' => 'draggable', ); } return theme('table', $header, $rows, array('id' => 'menu-block-menus')); }