Version 1
[yaffs-website] / web / modules / custom / menu_views / menu_views.admin.inc
diff --git a/web/modules/custom/menu_views/menu_views.admin.inc b/web/modules/custom/menu_views/menu_views.admin.inc
new file mode 100644 (file)
index 0000000..838c625
--- /dev/null
@@ -0,0 +1,803 @@
+<?php
+
+
+
+/**
+ * @file
+ * Form hooks for the menu_views module.
+ */
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Appends the attached view to the title of the menu item.
+ */
+function menu_views_form_menu_overview_form_alter(&$form, &$form_state) {
+  $attached = FALSE;
+  $elements = \Drupal\Core\Render\Element::children($form);
+  foreach ($elements as $mlid) {
+    $element = &$form[$mlid];
+    // Only process menu items
+    if (isset($element['#item'])) {
+      $menu_item = &$element['#item'];
+      // Only change the title for attached views
+      $item = _menu_views_get_item($menu_item);
+      _menu_views_tokenize($item, TRUE);
+      
+      if ($item['type'] == 'view' && $item['view']['name'] && $item['view']['display']) {
+        if (!$attached) {
+          $form['#attached']['css'][] = drupal_get_path('module', 'menu_views') . '/menu_views.admin.css';
+          $attached = TRUE;
+        }
+        $title = '';
+        if ($view = views_get_view($item['view']['name'])) {
+          if ($view->access($item['view']['display']) && $view->set_display($item['view']['display'])) {
+            $view->set_arguments(explode('/', $item['view']['arguments']));
+            // Provide title options for the view.
+            $title = \Drupal\Component\Utility\Xss::filterAdmin($item['view']['settings']['title_override']);
+            if (empty($title)) {
+              $title = \Drupal\Component\Utility\Xss::filterAdmin($view->get_title());
+            }
+          }
+          $view->destroy();
+        }
+        if (empty($title)) {
+          $title = t($item['view']['name']) . '-' . t($item['view']['display']);
+        }
+        $element['title'] = array(
+          '#prefix' => '<div class="view" title="View: ' . $item['view']['name'] . '-' . $item['view']['display'] . '">',
+          '#suffix' => '</div>',
+          '#markup' => '<strong>View:</strong> ' . $title . ($menu_item['hidden'] ? ' (' . t('disabled') . ')' : ''),
+        );
+      }
+    }
+  }
+}
+
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Adds menu views options to the menu edit item form.
+ *
+ * @see _menu_views_form_alter()
+ */
+function menu_views_form_menu_link_edit_alter(&$form, &$form_state, $form_id) {
+  // @FIXME
+// drupal_set_title() has been removed. There are now a few ways to set the title
+// dynamically, depending on the situation.
+// 
+// 
+// @see https://www.drupal.org/node/2067859
+// drupal_set_title(t('Edit menu item'));
+// Moved into form_alter - jeff
+
+
+  _menu_views_form_alter($form, $form, $form_state, $form_id);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Adds menu views options to the node's edit menu item form.
+ *
+ * @see _menu_views_form_alter()
+ */
+function menu_views_form_node_form_alter(&$form, &$form_state, $form_id) {
+  if (isset($form['menu']['link'])) {
+    _menu_views_form_alter($form['menu']['link'], $form, $form_state, $form_id);
+  }
+}
+
+/**
+ * Helper function to determine where form values for menu views are located.
+ *
+ * @return
+ *  Array of parents to the menu views form elements.
+ */
+function _menu_views_form_parents($form) {
+  $parents = array();
+  if (isset($form['#node'])) {
+    $parents[] = 'menu';
+    $parents[] = 'options';
+  }
+  elseif (_menu_views_options_tree($form)) {
+    $parents[] = 'options';
+  }
+  $parents[] = 'menu_views';
+  $parents[] = 'view';
+  return $parents;
+}
+
+/**
+ * Helper function that inserts a fieldset containing available replacement tokens.
+ *
+ * @see _menu_views_form()
+ */
+function _menu_views_form_tokens_ui(array &$element) {
+  static $enabled;
+  if (!isset($enabled)) {
+    $enabled = \Drupal::moduleHandler()->moduleExists('token'); 
+  }
+  if ($enabled) {
+    $i = 0;
+    while (isset($element['tokens_' . $i])) {
+      $i++;
+    }
+    $element['tokens_' . $i] = array(
+      '#type' => 'container',
+    );
+    $element['tokens_' . $i]['tokens'] = array(
+      '#theme' => 'token_tree',
+      '#token_types' => array('menu-link'),
+      '#dialog' => TRUE,
+    );
+  }
+}
+
+/**
+ * Alters existing forms in preparation for adding Menu Views to it.
+ *
+ * @param $element
+ *   The top level menu item edit form element passed by reference.
+ * @param $form
+ *   The complete form array passed by reference.
+ * @param $form_state
+ *   The complete form state array passed by reference.
+ */
+function _menu_views_form_alter(array &$element, array &$form, array &$form_state, $form_id) {
+  // Still need to render the form, just hide it for those who don't have access.
+  $access = \Drupal::currentUser()->hasPermission('administer menu views');
+  // Only need to attach or alter form if user has access.
+  if ($access) {
+    $form['#title'] = t('Edit menu item');
+
+    // Unset the previous values so that the new values can get saved.
+    if (isset($element['options']['#value']['menu_views'])) {
+      unset($element['options']['#value']['menu_views']);
+    }
+    $module_path = drupal_get_path('module', 'menu_views');
+    // Attach CSS.
+    $element['#attached']['css'][] = array(
+      'data' => $module_path . '/menu_views.admin.css',
+      'type' => 'file',
+      'group' => CSS_THEME,
+      'weight' => 100
+    );
+    // Attach JavaScript.
+    // @FIXME
+// // @FIXME
+// // This looks like another module's variable. You'll need to rewrite this call
+// // to ensure that it uses the correct configuration object.
+// $element['#attached']['js'][] = array(
+//       'data' => array('menu_views' => array(
+//         'admin_theme' => variable_get('admin_theme', 'bartik'),
+//         'node_form' => isset($form['#node']),
+//       )),
+//       'type' => 'setting',
+//     );
+
+    $element['#attached']['js'][] = array(
+      'data' => $module_path . '/menu_views.admin.js',
+      'type' => 'file',
+      'group' => JS_THEME,
+      'weight' => 100,
+    );
+    // Create AJAX wrapper around the menu edit form element.
+    $element['#prefix'] = '<div id="menu-edit-item-wrapper">';
+    $element['#suffix'] = '</div>';
+  }
+    
+  // Get values for the new menu views item, existing menu views item or submitted form values.
+  $item = _menu_views_get_item($form, $form_state);
+  // Use the loaded node if it exists.
+  $node = isset($form['#node']) ? $form['#node'] : FALSE;
+  
+  // Get the original menu link, if it exists.
+  $menu_link = array();
+  if (isset($form['original_item']['#value'])) {
+    $menu_link = $form['original_item']['#value'];
+  }
+  elseif ($node && isset($node->menu)) {
+    $menu_link = $node->menu;
+  }
+  
+  // Determine which menu item type is visible.
+  $visible = !('view' === $item['type']);
+  
+  // Determine the correct link path to show or set values for.
+  if (isset($element['link_path'])) {
+    if ('link' === $item['type'] && !empty($element['link_path']['#default_value']) && '<view>' === $element['link_path']['#default_value']) {
+      $element['link_path']['#default_value'] = $item['original_path'];
+    }
+    elseif ('view' === $item['type']) {
+      if (!empty($element['link_path']['#default_value']) && '<view>' !== $element['link_path']['#default_value']) {
+        $item['original_path'] = $element['link_path']['#default_value'];
+      }
+      $element['link_path']['#default_value'] = '<view>';
+    }
+  }
+  elseif ($node) {
+    if ('view' === $item['type']) {
+      $element['link_path'] = array(
+        '#type' => 'value',
+        '#value' => '<view>',
+      );
+    }
+    else {
+      $element['link_path'] = array(
+        '#type' => 'value',
+        '#value' => $node && isset($node->nid) ? 'node/' . $node->nid : '',
+      );
+    }
+  }
+  
+  // If the original path is empty and this is a node, use the node path.
+  if (empty($item['original_path']) && $node && isset($node->nid) && $node->nid) {
+    $item['original_path'] = 'node/' . $node->nid;
+  }
+  
+  // If this menu item is a view and user does not have permissions to administer menu views, restrict access to the form.
+  // Cannot use drupal_access_denied() because this form can also be inside a node edit form.
+  if ($item['type'] == 'view' && !$access) {
+    $element['disabled'] = array(
+      '#prefix' => '<div class="messages error">',
+      '#suffix' => '</div>',
+      '#markup' => t('You do not have access to edit this type of menu item.'),
+      '#weight' => -9999,
+    );
+    $visible = FALSE;
+    // Hide the action buttons on menu item edit forms.
+    if (isset($element['actions'])) {
+      $element['actions']['#access'] = $access;
+    }
+    // Hide the checkbox toggle on node edit forms.
+    if (isset($form['menu']['enabled'])) {
+      $form['menu']['enabled']['#access'] = $access;
+    }
+  }
+  
+  // Replace Parent Menu Options
+  $options = _menu_views_parent_options(menu_get_menus(), $menu_link);
+  if ($node && isset($node->type)) {
+    $options = _menu_views_parent_options(menu_get_menus(), $menu_link['mlid'] ? $menu_link : $node->type, $node->type);
+  }
+  $element['parent']['#title'] = t('Parent Item');
+  $element['parent']['#options'] = $options;
+
+  // Move general menu item settings into a container.
+  if ($access) {
+    $element['menu_item_settings'] = array(
+      '#access' => $access,
+      '#type' => 'fieldset',
+      '#title' => t('Menu item settings'),
+      '#parents' => isset($form['#node']) ? array('menu') : array(),
+      '#weight' => $item['type'] == 'view' ? 50 : 1,
+      '#attributes' => array('id' => 'menu_item_settings', 'class' => array('menu-item-settings')),
+    );
+    if (isset($element['enabled'])) {
+      $element['menu_item_settings']['enabled'] = $element['enabled'];
+      unset($element['enabled']);
+    }
+    $element['menu_item_settings']['expanded'] = $element['expanded'];
+    unset($element['expanded']);
+    $element['menu_item_settings']['parent'] = $element['parent'];
+    unset($element['parent']);
+    $element['menu_item_settings']['weight'] = $element['weight'];
+    unset($element['weight']);
+  }
+
+  // Add support for the xmlsitemap_menu module.
+  if (\Drupal::moduleHandler()->moduleExists('xmlsitemap_menu')) {
+    $element['xmlsitemap']['#weight'] = $item['type'] === 'view' ? 51 : 30;
+  }
+
+  // Create a radio toggle for menu item types: link or view.
+  $element['menu_item_type'] = array(
+    '#access' => $access,
+    '#type' => 'radios',
+    '#title' => t('Menu item type'),
+    '#options' => array('link' => t('Link'), 'view' => t('View')),
+    '#default_value' => $item['type'],
+    // Add container-inline style for admin themes like Rubik.
+    '#prefix' => '<div id="menu-item-type" class="form-item container-inline">',
+    '#suffix' => '</div>',
+    '#ajax' => array(
+      'callback' => '_menu_views_form_ajax',
+      'wrapper' => 'menu-edit-item-wrapper',
+    ),
+    // Ensure this is rendered at the top of the form.
+    '#weight' => -1000,
+  );
+  
+  // Determine if menu_attributes is enabled.
+  $menu_attributes = \Drupal::moduleHandler()->moduleExists('menu_attributes');
+
+  // Show/Hide the core link form elements based on menu item type of: link or view.
+  foreach (\Drupal\Core\Render\Element::children($element) as $child) {
+    // Skip options (handled below) and actions.
+    $type = isset($element[$child]['#type']) ? $element[$child]['#type'] : '';
+
+    // Ensure necessary children are always present (regardless of their type).
+    $ignore_children = array(
+      'menu_item_type', 'disabled', 'menu_item_settings',
+      'form_build_id', 'form_token', 'form_id',
+      'xmlsitemap',
+    );
+
+    // Allow the menu_attributes module to control the description field.
+    if ($menu_attributes) {
+      $ignore_children[] = 'description';
+    }
+
+    $ignore_types = array('actions', 'hidden', 'value', 'token');
+    if (in_array($child, $ignore_children) || !$type || in_array($type, $ignore_types)) {
+      continue;
+    }
+    $element[$child]['#access'] = $visible;
+  }
+  // Show/Hide the link options form elements based on menu item type of: link or view.
+  foreach (\Drupal\Core\Render\Element::children($element['options']) as $child) {
+    // Skip menu_view options.
+    $type = isset($element['options'][$child]['#type']) ? $element['options'][$child]['#type'] : '';
+    // Ensure necessary children are always present (regardless of their type).
+    $ignore_children = array('menu_views');
+    $ignore_types = array('hidden', 'value', 'token');
+    if (in_array($child, $ignore_children) || !$type || in_array($type, $ignore_types)) {
+      continue;
+    }
+    $element['options'][$child]['#access'] = $visible;
+  }
+  
+  // Place menu views in the options array.
+  $element['options']['menu_views'] = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#weight' => 10,
+    '#access' => $access,
+  );
+  
+  // Create the actual Menu Views form.
+  _menu_views_form($item, $element['options']['menu_views'], $form, $form_state, $form_id);
+  
+  // Add menu views form handlers.
+  array_unshift($form['#validate'], '_menu_views_form_validate');
+  array_unshift($form['#submit'], '_menu_views_form_submit');
+}
+
+
+/**
+ * Adds Menu Views settings to an existing form.
+ *
+ * @param $item
+ *   The menu views item array passed by reference.
+ *   @see _menu_views_get_item()
+ * @param $element
+ *   The top level menu item edit form element passed by reference.
+ * @param $form
+ *   The complete form array passed by reference.
+ * @param $form_state
+ *   The complete form state array passed by reference.
+ */
+function _menu_views_form(&$item, &$element, &$form, &$form_state, $form_id) {
+  $element['mlid'] = array(
+    '#type' => 'value',
+    '#value' => $item['mlid'],
+  );
+  $element['type'] = array(
+    '#type' => 'value',
+    '#value' => $item['type'],
+  );
+  $element['original_path'] = array(
+    '#type' => 'value',
+    '#value' => $item['original_path'],
+  );
+  
+  // Container for the actual view settings.
+  $element['view'] = array(
+    '#type' => 'container',
+    '#access' => $item['type'] == 'view' ? TRUE : FALSE,
+  );
+
+  $view_options = array();
+  $display_options = array();
+  foreach (views_get_enabled_views() as $view_name => $view) {
+    $view_options[$view_name] = $view->human_name . ' (' . $view_name . ')';
+    foreach ($view->display as $display_name => $display) {
+      if ('default' !== $display_name && 'page' !== $display_name && 'rss' !== $display_name) {
+        $display_options[$view_name][$display_name] = $display->display_title . ' (' . $display_name . ')';
+      }
+    }
+    // If view has no compatiable displays, remove the view as an option.
+    if (empty($display_options[$view_name])) {
+      unset($view_options[$view_name]);
+    }
+    else {
+      // Sort the displays for the view.
+      ksort($display_options[$view_name]);
+    }
+  }
+  ksort($view_options);
+  $element['view']['container'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('View'),
+    '#parents' => _menu_views_form_parents($form),
+  );
+  $element['view']['container']['name'] = array(
+    '#type' => 'select',
+    '#title' => t('Name'),
+    '#empty_option' => t('- Select View -'),
+    '#description' => t('Select the name of a view to use. The following view displays cannot be used: Master (default), Page and RSS. If the view or display you are looking for does not exist, create a block display in that view.'),
+    '#required' => TRUE,
+    '#default_value' => $item['view']['name'],
+    '#options' => $view_options,
+    '#ajax' => array(
+      'callback' => '_menu_views_form_ajax',
+      'wrapper' => 'menu-edit-item-wrapper',
+    ),
+  );
+  if ($item['view']['name'] && !empty($display_options[$item['view']['name']])) {
+    $element['view']['container']['display'] = array(
+      '#type' => 'select',
+      '#title' => t('Display'),
+      '#description' => t('Select the name of a view display to use. The following view displays cannot be used: Master (default), Page and RSS. If the view or display you are looking for does not exist, create a block display in that view.'),
+      '#required' => TRUE,
+      '#empty_option' => t('- Select Display -'),
+      '#default_value' => $item['view']['display'],
+      '#options' => $display_options[$item['view']['name']],
+      '#ajax' => array(
+        'callback' => '_menu_views_form_ajax',
+        'wrapper' => 'menu-edit-item-wrapper',
+      ),
+    );
+    if ($item['view']['display']) {
+      $element['view']['container']['arguments'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Arguments'),
+        '#description' => t('You can reference the node associated with this menu link by using <code>[menu-link:node:nid]</code>.<br />You can reference the node associated with the parent of this menu link by using <code>[menu-link:parent:node:nid]</code>.'),
+        '#default_value' => $item['view']['arguments'],
+      );
+      _menu_views_form_tokens_ui($element['view']['container']);
+      
+      // Advanced Settings.
+      $element['view']['settings'] = array(
+        '#type' => 'container',
+      );
+      $parents = _menu_views_form_parents($form);
+      $parents[] = 'settings';
+      
+      $parents_name = $parents;
+      $parents_name_first = array_shift($parents_name);
+      $parents_name = $parents_name_first . '[' . implode('][', $parents_name);
+      
+      $settings = &$element['view']['settings'];
+
+      // Wrapper Class
+      $settings['wrapper_classes'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Wrapper Classes'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#parents' => $parents,
+      );
+      $settings['wrapper_classes']['wrapper_classes'] = array(
+        '#type' => 'textfield',
+        '#description' => t('Provide any additional classes, separated by spaces.'),
+        '#default_value' => $item['view']['settings']['wrapper_classes'],
+      );
+
+      // View Title
+      $settings['title'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('View Title'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#parents' => $parents,
+      );
+      $settings['title']['title'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Show view title'),
+        '#default_value' => $item['view']['settings']['title'],
+      );
+      $settings['title']['title_settings'] = array(
+        '#type' => 'container',
+        '#parents' => $parents,
+        '#states' => array(
+          'visible' => array(
+           ':input[name="' . $parents_name . '][title]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $title = &$settings['title']['title_settings'];
+      // @FIXME
+// // @FIXME
+// // This looks like another module's variable. You'll need to rewrite this call
+// // to ensure that it uses the correct configuration object.
+// $title['title_wrapper'] = array(
+//         '#type' => 'select',
+//         '#title' => t('Element Wrapper'),
+//         '#description' => t('Choose which element wrapper to use around the title of the view. Default: H3'),
+//         '#default_value' => $item['view']['settings']['title_wrapper'],
+//         '#options' => variable_get('views_field_rewrite_elements', array(
+//           '' => t('- Use default -'),
+//           '0' => t('- None -'),
+//           'div' => 'DIV',
+//           'span' => 'SPAN',
+//           'h1' => 'H1',
+//           'h2' => 'H2',
+//           'h3' => 'H3',
+//           'h4' => 'H4',
+//           'h5' => 'H5',
+//           'h6' => 'H6',
+//           'p' => 'P',
+//           'strong' => 'STRONG',
+//           'em' => 'EM',
+//         )),
+//       );
+
+      $title['title_classes'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Classes'),
+        '#description' => t('Provide any additional classes, separated by spaces. Title must use the element wrapper above for this take effect.'),
+        '#default_value' => $item['view']['settings']['title_classes'],
+      );
+      $title['title_override'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Override Title'),
+        '#description' => t('Enter custom text to override title output. Default: Title will be provided from the view.'),
+        '#default_value' => $item['view']['settings']['title_override'],
+      );
+      _menu_views_form_tokens_ui($title);
+
+      // Breadcrumb
+      $settings['breadcrumb'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Breadcrumb'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#parents' => $parents,
+      );
+      $settings['breadcrumb']['breadcrumb'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Show breadcrumb link'),
+        '#default_value' => $item['view']['settings']['breadcrumb'],
+      );
+      $settings['breadcrumb']['breadcrumb_settings'] = array(
+        '#type' => 'container',
+        '#parents' => $parents,
+        '#states' => array(
+          'visible' => array(
+           ':input[name="' . $parents_name . '][breadcrumb]"]' => array('checked' => TRUE),
+          ),
+        ),
+      );
+      $breadcrumb = &$settings['breadcrumb']['breadcrumb_settings'];
+      $breadcrumb['breadcrumb_title'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Link Title'),
+        '#description' => t('Title to use for the breadcrumb link. Note: If there is not a title provided by the view then the breadcrumb will not be displayed. Default: View Title'),
+        '#default_value' => $item['view']['settings']['breadcrumb_title'],
+      );
+      _menu_views_form_tokens_ui($breadcrumb);
+      $breadcrumb['breadcrumb_path'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Link Path'),
+        '#description' => t('Path to use for the breadcrumb link. Default: %front.', array('%front' => '<front>')),
+        '#default_value' => $item['view']['settings']['breadcrumb_path'],
+      );      
+      _menu_views_form_tokens_ui($breadcrumb);
+    }
+  }
+}
+
+
+/**
+ * Ajax callback for re-rendering the attach views portion of the form.
+ */
+function _menu_views_form_ajax(&$form, &$form_state, $form_id) {
+  if (isset($form['#node'])) {
+    return $form['menu']['link'];
+  }
+  return $form;
+}
+
+
+/**
+ * Validate handler for menu_edit_item form.
+ */
+function _menu_views_form_validate($form, &$form_state) {
+  // Only run this validation when the form is fully submitted.
+  if ($form_state['submitted']) {
+    $item = _menu_views_get_item($form, $form_state);
+    if ($item['type'] == 'view') {
+      if (!$item['view']['name']) {
+        form_set_error(implode('][', _menu_views_form_parents($form)) . '][name', t('The menu item type for this @type is a view. A view name is required before this @type can be saved.', array('@type' => isset($form['#node']) ? 'node' : 'menu item')));
+      }
+      elseif (!$item['view']['display']) {
+        form_set_error(implode('][', _menu_views_form_parents($form)) . '][display', t('The menu item type for this @type is a view. A view display is required before this @type can be saved.', array('@type' => isset($form['#node']) ? 'node' : 'menu item')));
+      }
+    }
+  }
+}
+
+
+/**
+ * Submit handler for menu_edit_item form.
+ */
+function _menu_views_form_submit($form, &$form_state) {
+  $values = &$form_state['values'];
+  if (isset($form['#node'])) {
+    $values = &$form_state['values']['menu'];
+  }
+  
+  // Get view settings from menu item.
+  $item = _menu_views_get_item($form, $form_state);
+  
+  // Remove this unecessary property from the values.
+  if (isset($values['menu_views'])) {
+    unset($values['menu_views']);
+  }
+  
+  // We really only want to intercept the menu edit item submit handle if this is actually a view.
+  if ($item['type'] == 'view') {
+    // If this is a new menu item, save a quick version of the menu item and return the mlid.
+    // The menu item will get updated with the rest of the values again shortly.
+    if (!$values['mlid']) {
+      $values['hidden'] = (int) !$values['enabled'];
+      $values['options']['attributes']['title'] = $values['description'];
+      list($values['menu_name'], $values['plid']) = explode(':', $values['parent']);
+      if (!$values['mlid'] = menu_link_save($values)) {
+        drupal_set_message(t('There was an error creating the menu item.'), 'error');
+      }
+    }
+    $default = _menu_views_default_values();
+    $item = array(
+      // The mlid should remain constant, always use the information provided by the menu module and not this one.
+      'mlid' => $values['mlid'],
+      'type' => $item['type'],
+      'original_path' => $item['original_path'],
+      'view' => $item['view'],
+    );
+    // Replace the menu views values in the menu item's options.
+    $values['options']['menu_views'] = _menu_views_array_merge_recursive($default, $item);
+  }
+}
+
+
+/**
+ * Return a list of menu items that are valid possible parents for the given menu item.
+ *
+ * @param $menus
+ *   An array of menu names and titles, such as from menu_get_menus().
+ * @param $item
+ *   The menu item or the node type for which to generate a list of parents.
+ *   If $item['mlid'] == 0 then the complete tree is returned.
+ * @param $type
+ *   The node type for which to generate a list of parents.
+ *   If $item itself is a node type then $type is ignored.
+ * @return
+ *   An array of menu link titles keyed on the a string containing the menu name
+ *   and mlid. The list excludes the given item and its children.
+ *
+ * @todo This has to be turned into a #process form element callback. The
+ *   'menu_override_parent_selector' variable is entirely superfluous.
+ */
+function _menu_views_parent_options($menus, $item, $type = '') {
+  // The menu_links table can be practically any size and we need a way to
+  // allow contrib modules to provide more scalable pattern choosers.
+  // hook_form_alter is too late in itself because all the possible parents are
+  // retrieved here, unless menu_override_parent_selector is set to TRUE.
+  // @FIXME
+// // @FIXME
+// // This looks like another module's variable. You'll need to rewrite this call
+// // to ensure that it uses the correct configuration object.
+// if (variable_get('menu_override_parent_selector', FALSE)) {
+//     return array();
+//   }
+
+
+  $available_menus = array();
+  if (!is_array($item)) {
+    // If $item is not an array then it is a node type.
+    // Use it as $type and prepare a dummy menu item for _menu_get_options().
+    $type = $item;
+    $item = array('mlid' => 0);
+  }
+  if (isset($item['mlid']) && $item['mlid']) {
+    $item = menu_link_load($item['mlid']);
+  }
+  if (empty($type)) {
+    // If no node type is set, use all menus given to this function.
+    $available_menus = $menus;
+  }
+  else {
+    // If a node type is set, use all available menus for this type.
+    // @FIXME
+// // @FIXME
+// // The correct configuration object could not be determined. You'll need to
+// // rewrite this call manually.
+// $type_menus = variable_get('menu_options_' . $type, array('main-menu' => 'main-menu'));
+
+    foreach ($type_menus as $menu) {
+      $available_menus[$menu] = $menu;
+    }
+  }
+
+  return _menu_views_get_options($menus, $available_menus, $item);
+}
+
+/**
+ * Helper function to get the items of the given menu.
+ */
+function _menu_views_get_options($menus, $available_menus, $item) {
+  // If the item has children, there is an added limit to the depth of valid parents.
+  if (isset($item['parent_depth_limit'])) {
+    $limit = $item['parent_depth_limit'];
+  }
+  else {
+    $limit = _menu_parent_depth_limit($item);
+  }
+
+  $options = array();
+  foreach ($menus as $menu_name => $title) {
+    if (isset($available_menus[$menu_name])) {
+      // @FIXME
+// menu_tree_all_data() is gone in Drupal 8. To generate or work with menu trees, you'll need to
+// use the menu.link_tree service.
+// 
+// 
+// @see https://www.drupal.org/node/2226481
+// @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21MenuLinkTree.php/class/MenuLinkTree/8
+// $tree = menu_tree_all_data($menu_name, NULL);
+
+      $menu_tree = \Drupal::service('toolbar.menu_tree');
+
+      $tree = MenuLinkTreeInterface::load();
+
+      $options[$menu_name . ':0'] = '<' . $title . '>';
+      _menu_views_parents_recurse($tree, $menu_name, '--', $options, $item['mlid'], $limit);
+    }
+  }
+  return $options;
+}
+
+/**
+ * Recursive helper function for menu_parent_options().
+ */
+function _menu_views_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, $depth_limit) {
+  foreach ($tree as $data) {
+    if ($data['link']['depth'] > $depth_limit) {
+      // Don't iterate through any links on this level.
+      break;
+    }
+    if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) {
+      $item = _menu_views_get_item($data['link']);
+      _menu_views_tokenize($item);
+      if ($item['type'] == 'view' && $item['view']['name'] && $item['view']['display']) {
+        $title = t($item['view']['name']) . '-' . t($item['view']['display']);
+        $view_title = \Drupal\Component\Utility\Xss::filterAdmin($item['view']['settings']['title_override']);
+        if (empty($view_title) && ($view = views_get_view($item['view']['name']))) {
+          if ($view->access($item['view']['display']) && $view->set_display($item['view']['display'])) {
+            $view->set_arguments(explode('/', $item['view']['arguments']));
+            $view_title = \Drupal\Component\Utility\Xss::filterAdmin($view->get_title());
+          }
+          $view->destroy();
+        }
+        if (!empty($view_title)) {
+          $title = $view_title . ' (' . $title . ')';
+        }
+        $title = $indent . ' [view] ' . \Drupal\Component\Utility\Unicode::truncate($title, 30, TRUE, FALSE);
+      }
+      else {
+        $title = $indent . ' ' . \Drupal\Component\Utility\Unicode::truncate($data['link']['title'], 30, TRUE, FALSE);
+      }
+      if ($data['link']['hidden']) {
+        $title .= ' (' . t('disabled') . ')';
+      }
+      $options[$menu_name . ':' . $data['link']['mlid']] = $title;
+      if ($data['below']) {
+        _menu_views_parents_recurse($data['below'], $menu_name, $indent . '--', $options, $exclude, $depth_limit);
+      }
+    }
+  }
+}