'] = array(
'page callback' => 'drupal_not_found',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_permission().
*/
function menu_views_permission() {
return array(
'administer menu views' => array(
'title' => t('Administer menu views'),
'description' => t('Allows administrators to attach views to individual menu items and alter the view\'s configuration.'),
),
);
}
/**
* Implements hook_theme_registry_alter().
* Intercepts theme_menu_link().
*/
function menu_views_theme_registry_alter(&$registry) {
// Save previous value from registry in case another module/theme overwrites theme_menu_link() as well.
$registry['menu_views_menu_link_default'] = $registry['menu_link'];
$registry['menu_link']['function'] = 'menu_views_menu_link';
// Provide Superfish support.
if (isset($registry['superfish_menu_item_link'])) {
$registry['menu_views_superfish_menu_item_link_default'] = $registry['superfish_menu_item_link'];
$registry['superfish_menu_item_link']['function'] = 'menu_views_superfish_menu_item_link';
}
}
/**
* Implements theme_menu_link().
* Overrides default theming function to intercept views.
*/
function menu_views_menu_link(array $variables) {
// Only intercept if this menu link is a view.
if (isset($variables['element']) && $view = _menu_views_replace_menu_item($variables['element'])) {
return '
' . $view . "\n";
}
// Otherwise, use the default theming function.
return theme('menu_views_menu_link_default', $variables);
}
/**
* Implements theme_superfish_menu_item_link().
* Overrides default theming function to intercept views.
*/
function menu_views_superfish_menu_item_link(array $variables) {
// Only intercept if this menu item link is a view.
if (isset($variables['menu_item']['link']) && $view = _menu_views_replace_menu_item($variables['menu_item']['link'])) {
return '';
}
// Otherwise, use the default theming function.
return theme('menu_views_superfish_menu_item_link_default', $variables);
}
function _menu_views_replace_menu_item($element) {
$output = FALSE;
// Only process menu links that are not on admin pages (see: http://drupal.org/node/1790444).
if (!path_is_admin(current_path())) {
$item = _menu_views_item($element);
if ($item['type'] == 'view' && $item['view']['name'] && $item['view']['display']) {
$element['#attributes']['class'][] = 'menu-views';
if ($view = views_get_view($item['view']['name'])) {
if ($view->access($item['view']['display']) && $view->set_display($item['view']['display'])) {
$output = '';
$view->set_arguments(explode('/', _menu_views_tokenize_arguments($item)));
// Provide title options for the view.
if ((bool)$item['view']['settings']['title']) {
$title = $item['view']['settings']['title_override'];
if (empty($title)) {
$title = $view->get_title();
}
if (!empty($title)) {
$wrapper = $item['view']['settings']['title_wrapper'];
if ($wrapper === '0') {
$wrapper = FALSE;
}
elseif ($wrapper === '') {
$wrapper = 'h3';
}
if ($wrapper) {
$output .= '<' . $wrapper . (!empty($item['view']['settings']['title_classes']) ? ' class="' . $item['view']['settings']['title_classes'] . '"' : '') . '>';
}
$output .= $title;
if ($wrapper) {
$output .= '' . $wrapper . '>';
}
}
}
$output .= $view->preview();
}
}
}
}
return $output;
}
function _menu_views_item(&$element = array(), &$form_state = array()) {
// Default values.
$item = $default = array(
'mlid' => 0,
'type' => 'link',
'tree' => FALSE,
'original_path' => '',
'view' => array(
'name' => FALSE,
'display' => FALSE,
'arguments' => '',
'settings' => array(
'title' => FALSE,
'title_wrapper' => '',
'title_classes' => '',
'title_override' => '',
),
),
);
$provided = FALSE;
// Attempt to load the menu view element for a link.
if (isset($element['menu_views'])) {
$provided = &$element['menu_views'];
}
if (!$provided && isset($element['localized_options']['menu_views'])) {
$provided = &$element['localized_options']['menu_views'];
}
if (!$provided && isset($element['#localized_options']['menu_views'])) {
$provided = &$element['#localized_options']['menu_views'];
}
// If the menu view element were not set, attempt to determine if this is a form.
if (!$provided && isset($element['options'])) {
if (isset($element['options']['#tree']) && $element['options']['#tree']) {
$item['tree'] = TRUE;
}
if (isset($element['original_item']['#value']['options']['menu_views'])) {
$provided = &$element['original_item']['#value']['options']['menu_views'];
}
if ($item['tree'] && isset($form_state['values']['options']['menu_views'])) {
$provided = &$form_state['values']['options']['menu_views'];
}
elseif (isset($form_state['values']['menu_views'])) {
$provided = &$form_state['values']['menu_views'];
}
if (isset($form_state['values']['menu_item_type'])) {
$item['type'] = $form_state['values']['menu_item_type'];
}
}
// By default, the menu view returns default values (no view). If settings were provided by an element or form item, then use those.
if ($provided) {
// Extract available element settings to use for this menu view.
foreach (array('mlid', 'type', 'original_path', 'view') as $property) {
if (isset($provided[$property]) && !empty($provided[$property])) {
if (is_array($item[$property])) {
$item[$property] = array_merge($item[$property], (array)$provided[$property]);
}
else {
$item[$property] = $provided[$property];
}
}
}
}
// Filter out any disabled views.
$views = array_keys(views_get_enabled_views());
if (!in_array($item['view']['name'], $views)) {
$item['view'] = $default['view'];
}
return $item;
}
/**
* Helper function to remove the attached view options from a menu item.
*/
function _menu_views_remove_element($item) {
if ($item['element']) {
unset($item['element']);
}
}
/**
* Helper function to tokenize an attached menu item view's arguments.
*/
function _menu_views_tokenize_arguments($item, $human_readable = FALSE) {
$args = explode('/', $item['view']['arguments']);
if (count($args) && $item['mlid']) {
$context['menu-link'] = menu_link_load($item['mlid']);
$options = array(
'callback' => '_menu_views_tokens_callback',
'clear' => TRUE,
'human_readable' => $human_readable,
);
foreach ($args as $key => $arg) {
$args[$key] = token_replace($arg, $context, $options);
}
}
return implode('/', $args);
}
/**
* Implements hook_token_info().
*/
function menu_views_token_info() {
$tokens['tokens']['menu-link']['node'] = array(
'name' => t('Node'),
'description' => t('The node of the menu link.'),
'type' => 'node',
);
$tokens['tokens']['menu-link']['parent']['node'] = array(
'name' => t('Node'),
'description' => t('The node of the menu link\'s parent.'),
'type' => 'node',
);
return $tokens;
}
/**
* Implements hook_tokens().
*/
function menu_views_tokens($type, $tokens, array $data = array(), array $options = array()) {
$url_options = array('absolute' => TRUE);
if (isset($options['language'])) {
$url_options['language'] = $options['language'];
$language_code = $options['language']->language;
}
else {
$language_code = NULL;
}
$sanitize = !empty($options['sanitize']);
$replacements = array();
$node = FALSE;
$parent = FALSE;
// Menu link tokens.
if ($type == 'menu-link' && !empty($data['menu-link'])) {
$link = (array) $data['menu-link'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'node':
$node = menu_get_object('node', 1, $link['link_path']);
if ($node && $node->nid) {
$title = $node->title;
$replacements[$original] = $sanitize ? filter_xss($title) : $title;
}
else {
$replacements[$original] = NULL;
}
break;
case 'parent':
if (isset($link['plid']) &&
!empty($link['plid']) &&
($parent = menu_link_load($link['plid'])) &&
($node = menu_get_object('node', 1, $parent['link_path'])) &&
$node->nid
) {
$title = $node->title;
$replacements[$original] = $sanitize ? filter_xss($title) : $title;
}
else {
$replacements[$original] = NULL;
}
break;
}
}
// Chained token relationships.
if (($node_tokens = token_find_with_prefix($tokens, 'node')) &&
$node = menu_get_object('node', 1, $link['link_path'])
) {
$replacements += token_generate('node', $node_tokens, array('node' => $node), $options);
}
if (($parent_tokens = token_find_with_prefix($tokens, 'parent')) &&
isset($link['plid']) &&
!empty($link['plid']) &&
($parent = menu_link_load($link['plid'])) &&
($node = menu_get_object('node', 1, $parent['link_path'])) &&
$node->nid
) {
$replacements += token_generate('node', $parent_tokens, array('node' => $node), $options);
}
}
return $replacements;
}
/**
* Callback for human-readable token value replacements.
*/
function _menu_views_tokens_callback(&$replacements, $data, $options) {
foreach ($replacements as $token => $value) {
if ($options['human_readable']) {
if (is_bool($value)) {
$value = $value ? t('TRUE') : t('FALSE');
}
elseif (is_object($value)) {
$value = t('Object');
}
elseif (is_array($value)) {
$value = t('Array');
}
elseif (is_null($value)) {
$value = t('NULL');
}
else {
$value = (string) $value;
}
if ($value === '') {
$value = t('NULL');
}
}
$replacements[$token] = urlencode($value);
}
}