og_menu_single.module in OG Menu Single 7
Creates a single menu per organic group on a site.
File
og_menu_single.moduleView source
<?php
/**
* @file
* Creates a single menu per organic group on a site.
*/
// Name of the menu the links are stored in.
define('OG_MENU_SINGLE_MENU_NAME', 'og-menu-single');
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function og_menu_single_form_node_type_form_alter(&$form, $form_state) {
$type = $form['#node_type']->type;
$form['menu']['og_menu_single'] = array(
'#type' => 'fieldset',
'#title' => t('Og Menu Single'),
'#collapsible' => TRUE,
'#collapsed' => !og_menu_single_is_enabled_group_content('node', $type) && !og_menu_single_is_enabled_group('node', $type),
);
$form['menu']['og_menu_single']['og_menu_single_group_content__node_'] = array(
'#type' => 'checkbox',
'#title' => t('Content of this type may be placed in a group menu. Must also be a group content type'),
'#default_value' => og_menu_single_is_enabled_group_content('node', $type),
);
$form['menu']['og_menu_single']['og_menu_single_group__node_'] = array(
'#type' => 'checkbox',
'#title' => t('Groups of this type may have a group menu. Must also be a group type'),
'#default_value' => og_menu_single_is_enabled_group('node', $type),
);
}
/**
* Implements hook_node_prepare().
*/
function og_menu_single_node_prepare($node) {
if (og_menu_single_is_enabled_group_content('node', $node->type)) {
// Set PLID for form use later.
$node->group_plid = og_menu_single_get_active_plid();
if ($node->group_plid && !empty($node->nid)) {
if ($mlid = og_menu_single_get_link_mlid('node', $node->nid)) {
$link = menu_link_load($mlid);
$node->menu = $node->menu ? $link + $node->menu : $link;
}
}
}
}
/**
* Implements hook_form_FORMID_alter().
*/
function og_menu_single_form_menu_edit_item_alter(&$form, $form_state) {
$item = menu_get_item();
// @TODO
// Don't want to define new form for menu edit so any contrib editing main one
// edits this also, but no way other than using 'menu_override_parent_selector
// but there's no way to know where else outside of core menu_parent_options
// has been used. Bah!!
if ($item['path'] == 'group/%/%/admin/menu/item/%/edit' || $item['path'] == 'group/%/%/admin/menu/add') {
$plid = og_menu_single_get_link_mlid_or_create($item['map'][1], $item['map'][2]);
$link = $form['original_item']['#value'];
$options[OG_MENU_SINGLE_MENU_NAME . ':' . $plid] = '<' . t('None') . '>';
if ($plid && ($tree = og_menu_single_children_items($plid))) {
_menu_parents_recurse($tree, OG_MENU_SINGLE_MENU_NAME, '--', $options, $link['mlid'] ? $link['mlid'] : 0, 8);
}
$form['parent']['#options'] = $options;
$form['enabled']['#access'] = FALSE;
$form['expanded']['#access'] = FALSE;
$menu_path = 'group/' . $item['map'][1] . '/' . $item['map'][2] . '/admin/menu';
if ($link['mlid']) {
$breadcrumb = drupal_get_breadcrumb();
array_pop($breadcrumb);
$breadcrumb[] = l('Group Menu', 'group/' . $item['map'][1] . '/' . $item['map'][2] . '/admin/menu');
drupal_set_breadcrumb($breadcrumb);
}
$form['#submit'][] = 'og_menu_single_menu_form_new_redirect';
$form['#og_menu_redirect'] = $menu_path;
}
}
/**
* Implements hook_form_FORMID_alter().
*/
function og_menu_single_form_menu_item_delete_form_alter(&$form, $form_state) {
$item = menu_get_item();
if ($item['path'] == 'group/%/%/admin/menu/item/%/delete') {
$menu_path = 'group/' . $item['map'][1] . '/' . $item['map'][2] . '/admin/menu';
$form['#submit'][] = 'og_menu_single_menu_form_new_redirect';
$form['#og_menu_redirect'] = $menu_path;
$form['actions']['cancel']['#href'] = str_replace('admin/structure/menu/manage/' . OG_MENU_SINGLE_MENU_NAME, $menu_path, $form['actions']['cancel']['#href']);
}
}
function og_menu_single_menu_form_new_redirect($form, &$form_state) {
$form_state['redirect'] = $form['#og_menu_redirect'];
}
/**
* Implements hook_form_FORMID_alter().
*/
function og_menu_single_form_node_form_alter(&$form, $form_state) {
if (!og_menu_single_is_enabled_group_content('node', $form['#node']->type) || empty($form['#node']->group_plid)) {
return;
}
$link = $form['#node']->menu;
$type = $form['#node']->type;
$options = array();
$options[OG_MENU_SINGLE_MENU_NAME . ':' . $form['#node']->group_plid] = '<' . t('Group Menu') . '>';
if ($tree = og_menu_single_children_items($form['#node']->group_plid)) {
_menu_parents_recurse($tree, OG_MENU_SINGLE_MENU_NAME, '--', $options, $link['mlid'] ? $link['mlid'] : 0, 8);
}
if (!empty($form['menu'])) {
$form['menu']['link']['parent']['#options'] += $options;
// Restore default if wasn't in menu parents before our alterations..
if (!empty($link['mlid'])) {
$default = $link['menu_name'] . ':' . $link['plid'];
if (isset($form['menu']['link']['parent']['#options'][$default])) {
$form['menu']['link']['parent']['#default_value'] = $default;
}
}
}
else {
// @see menu_form_node_form_alter().
$context = og_context();
$form['menu'] = array(
'#type' => 'fieldset',
'#title' => t('Menu settings'),
'#access' => user_access('administer menu') || $context && og_user_access($context['group_type'], $context['gid'], 'manage menu'),
'#collapsible' => TRUE,
'#collapsed' => !$link['link_title'],
'#group' => 'additional_settings',
'#attached' => array(
'js' => array(
drupal_get_path('module', 'menu') . '/menu.js',
),
),
'#tree' => TRUE,
'#weight' => -2,
'#attributes' => array(
'class' => array(
'menu-link-form',
),
),
);
$form['menu']['enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Provide a menu link'),
'#default_value' => (int) (bool) $link['mlid'],
);
$form['menu']['link'] = array(
'#type' => 'container',
'#parents' => array(
'menu',
),
'#states' => array(
'invisible' => array(
'input[name="menu[enabled]"]' => array(
'checked' => FALSE,
),
),
),
);
// Populate the element with the link data.
foreach (array(
'mlid',
'module',
'hidden',
'has_children',
'customized',
'options',
'expanded',
'hidden',
'parent_depth_limit',
) as $key) {
$form['menu']['link'][$key] = array(
'#type' => 'value',
'#value' => $link[$key],
);
}
$form['menu']['link']['link_title'] = array(
'#type' => 'textfield',
'#title' => t('Menu link title'),
'#default_value' => $link['link_title'],
);
$form['menu']['link']['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#default_value' => isset($link['options']['attributes']['title']) ? $link['options']['attributes']['title'] : '',
'#rows' => 1,
'#description' => t('Shown when hovering over the menu link.'),
);
$default = $link['mlid'] ? $link['menu_name'] . ':' . $link['plid'] : variable_get('menu_parent_' . $type, 'main-menu:0');
// If the current parent menu item is not present in options, use the first
// available option as default value.
// @todo User should not be allowed to access menu link settings in such a
// case.
if (!isset($options[$default])) {
$array = array_keys($options);
$default = reset($array);
}
$form['menu']['link']['parent'] = array(
'#type' => 'select',
'#title' => t('Parent item'),
'#default_value' => $default,
'#options' => $options,
'#attributes' => array(
'class' => array(
'menu-parent-select',
),
),
);
$form['menu']['link']['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#delta' => 50,
'#default_value' => $link['weight'],
'#description' => t('Menu links with smaller weights are displayed before links with larger weights.'),
);
}
}
/**
* Implements hook_node_insert().
*/
function og_menu_single_node_insert($node) {
if (og_menu_single_is_enabled_group('node', $node->type)) {
_og_menu_single_save_group_link($node);
}
}
/**
* Implements hook_node_update().
*/
function og_menu_single_node_update($node) {
if (og_menu_single_is_enabled_group('node', $node->type)) {
_og_menu_single_save_group_link($node, og_menu_single_get_link_mlid('node', $node->nid));
}
}
/**
* Implements hook_block_info().
*/
function og_menu_single_block_info() {
$blocks['menu'] = array(
'info' => t('OG Menu (active space menu)'),
'cache' => DRUPAL_CACHE_PER_PAGE,
);
return $blocks;
}
/**
* Implements hook_menu().
*/
function og_menu_single_menu() {
$items = array();
$items['group/%/%/admin/menu'] = array(
'title callback' => 'og_ui_menu_title_callback',
'title arguments' => array(
'Menu for group @group',
1,
2,
),
'description' => 'Manage group menu for a group.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'og_menu_single_menu_edit_form',
1,
2,
),
'access callback' => 'og_ui_user_access_group',
'access arguments' => array(
'manage menu',
1,
2,
),
'weight' => -8,
'file' => 'og_menu_single.admin.inc',
);
$items['group/%/%/admin/menu/list'] = array(
'title' => 'List links',
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
);
$items['group/%/%/admin/menu/add'] = array(
'title' => 'Add link',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_edit_item',
'add',
NULL,
menu_load(OG_MENU_SINGLE_MENU_NAME),
),
'access callback' => 'og_ui_user_access_group',
'access arguments' => array(
'manage menu',
1,
2,
),
'type' => MENU_LOCAL_ACTION,
'file' => 'menu.admin.inc',
'file path' => drupal_get_path('module', 'menu'),
);
$items['group/%/%/admin/menu/item/%menu_link/edit'] = array(
'title' => 'Edit menu link',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_edit_item',
'edit',
6,
NULL,
),
'access callback' => 'og_ui_user_access_group',
'access arguments' => array(
'manage menu',
1,
2,
),
'file' => 'menu.admin.inc',
'file path' => drupal_get_path('module', 'menu'),
);
$items['group/%/%/admin/menu/item/%menu_link/delete'] = array(
'title' => 'Delete menu link',
'page callback' => 'menu_item_delete_page',
'page arguments' => array(
6,
),
'access callback' => 'og_ui_user_access_group',
'access arguments' => array(
'manage menu',
1,
2,
),
'file' => 'menu.admin.inc',
'file path' => drupal_get_path('module', 'menu'),
);
return $items;
}
/**
* Implement hook_og_permission().
*/
function og_menu_single_og_permission() {
$items = array();
$items['manage menu'] = array(
'title' => t('Manage menu'),
'description' => t('Manage group menu for this group.'),
'default role' => array(
OG_ADMINISTRATOR_ROLE,
),
'restrict access' => TRUE,
);
return $items;
}
/**
* Implements hook_og_ui_get_group_admin()
*/
function og_menu_single_og_ui_get_group_admin($group_type, $gid) {
$items = array();
if (og_user_access($group_type, $gid, 'manage menu')) {
$items['manage_menu'] = array(
'title' => t('Menu'),
'description' => t('Manage group menu'),
'href' => 'admin/menu',
);
}
return $items;
}
/**
* Implements hook_block_configure().
*/
function og_menu_single_block_configure($delta = '') {
// This example comes from node.module.
$form = array();
if ($delta == 'menu') {
$form['settings']['og_menu_single_block_menu_depth'] = array(
'#title' => t('Depth'),
'#type' => 'select',
'#options' => array(
0 => t('All'),
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
),
'#default_value' => variable_get('og_menu_single_block_menu_depth', 0),
'#description' => t('Select how deep/how many levels of the menu to display.'),
);
}
return $form;
}
/**
* Implements hook_block_save().
*/
function og_menu_single_block_save($delta = '', $edit = array()) {
if ($delta == 'menu') {
variable_set('og_menu_single_block_menu_depth', $edit['og_menu_single_block_menu_depth']);
}
}
/**
* Implements hook_block_view().
*/
function og_menu_single_block_view($delta = '') {
$block = array();
if ($plid = og_menu_single_get_active_plid()) {
$tree = og_menu_single_children_items($plid, variable_get('og_menu_single_block_menu_depth', MENU_MAX_DEPTH));
if ($tree && ($output = menu_tree_output($tree))) {
$block['content'] = $output;
}
}
return $block;
}
/**
* Returns whether the group type is a considered group content.
*/
function og_menu_single_is_enabled_group_content($entity_type = 'node', $bundle) {
$is_group_content_type = og_is_group_content_type($entity_type, $bundle);
return $is_group_content_type && variable_get('og_menu_single_group_content__' . $entity_type . '__' . $bundle, $is_group_content_type && !og_is_group_type($entity_type, $bundle));
}
/**
* Returns whether the group type is a considered a group.
*/
function og_menu_single_is_enabled_group($entity_type = 'node', $bundle) {
$is_group_type = og_is_group_type($entity_type, $bundle);
return $is_group_type && variable_get('og_menu_single_group__' . $entity_type . '__' . $bundle, $is_group_type);
}
/**
* Fetches the link for given item in menu.
*
* @param $type
* What type of group it is -- currently only node is supported.
* @param $id
* ID of group.
* @param $reset
* Reset the internal cache for this $type/id.
*
* @return
* A menu link in og menu single menu for given entity if exists.
*/
function og_menu_single_get_link_mlid($type, $id, $reset = FALSE) {
$mlids =& drupal_static(__FUNCTION__, array());
$cid = $type . '_' . $id;
if ($reset || !isset($mlids[$cid])) {
$mlids[$cid] = db_select('menu_links', 'ml')
->fields('ml', array(
'mlid',
))
->orderBy('mlid', 'ASC')
->condition('ml.link_path', 'node/' . $id)
->condition('ml.module', 'menu')
->condition('ml.menu_name', OG_MENU_SINGLE_MENU_NAME)
->range(0, 1)
->execute()
->fetchField();
}
return $mlids[$cid];
}
/**
* Fetched the space mlid of the current space in the menu.
*
* @return
* The active menu link ID for current group.
*/
function og_menu_single_get_active_plid() {
$context = og_context();
// TODO
if (!$context || $context['group_type'] != 'node' || !$context['gid']) {
return NULL;
}
// Set PLID for form use later.
return og_menu_single_get_link_mlid_or_create($context['group_type'], $context['gid']);
}
/**
* Fetched or crate space mlid of an entity.
*
* @return
* The active menu link ID for current group.
*/
function og_menu_single_get_link_mlid_or_create($entity_type, $entity_id) {
$mlid = og_menu_single_get_link_mlid($entity_type, $entity_id);
if (!$mlid && ($entities = entity_load($entity_type, array(
$entity_id,
)))) {
_og_menu_single_save_group_link(reset($entities));
$mlid = og_menu_single_get_link_mlid($entity_type, $entity_id, TRUE);
}
return $mlid;
}
/**
* Fetches all children of a given parent link.
*
* @param $mlid
* Parent link ID to build a tree of menu links below.
* @param $max_depth
* The maxium depth of the tree to fetch, defaults to menu's max depth.
*
* @return
* An array of menu links and their children (as determined by depth).
*/
function og_menu_single_children_items($plid, $max_depth = NULL) {
if (!isset($max_depth)) {
$max_depth = MENU_MAX_DEPTH - 1;
}
$menu_link = og_menu_single_menu_link_load($plid);
return _og_menu_single_children_items($plid, $menu_link['depth'] + 1, $max_depth + 1);
}
/**
* Helper function to populate the menu tree without loading the entire tree.
*/
function _og_menu_single_children_items($plid, $current_depth, $max_depth) {
$menu_links =& drupal_static(__FUNCTION__, array());
$tree = array();
// current depth should always be same for a given plid.
if (!isset($menu_links[$plid])) {
$menu_links[$plid] = menu_build_tree(OG_MENU_SINGLE_MENU_NAME, array(
'expanded' => array(
$plid,
),
'min_depth' => $current_depth,
));
}
foreach ($menu_links[$plid] as $key => $item) {
if (module_exists('i18n_menu')) {
_i18n_menu_link_localize($item['link']);
}
$tree[$key] = $item;
if ($current_depth < $max_depth) {
$tree[$key]['below'] = _og_menu_single_children_items($item['link']['mlid'], $current_depth + 1, $max_depth);
}
}
return $tree;
}
/**
* Cached menu_link_load as may call for same mlid during same page load.
*/
function og_menu_single_menu_link_load($mlid) {
$menu_links =& drupal_static(__FUNCTION__, array());
if (!isset($menu_links[$mlid])) {
$menu_links[$mlid] = menu_link_load($mlid);
}
return $menu_links[$mlid];
}
/**
* Saves menu link to single menu for group.
*
* @param $node
* A group node object that link will be created/updated for.
* @param $mlid
* Current link ID if exists for that group.
*/
function _og_menu_single_save_group_link($node, $mlid = null) {
if (og_menu_single_is_enabled_group('node', $node->type)) {
$link = array(
'mlid' => $mlid,
'link_title' => $node->title,
'link_path' => 'node/' . $node->nid,
'menu_name' => OG_MENU_SINGLE_MENU_NAME,
'options' => array(
'attributes' => array(
'title' => t('Menu for group') . ' ' . $node->title,
),
),
);
menu_link_save($link);
}
}
/*
* Implements hook_ctools_plugin_directory
*/
function og_menu_single_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'ctools' && $plugin_type == 'content_types') {
return 'plugins/content_types';
}
}
Functions
Constants
Name | Description |
---|---|
OG_MENU_SINGLE_MENU_NAME |