Commit c77851c4 authored by Dries's avatar Dries

Issue #2301319 by pwolanin, effulgentsia: MenuLinkNG part5: Remove dead code and party!

parent 718a47d7
This diff is collapsed.
<?php
/**
* @file
* Hooks provided by the Menu link module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Alter a menu link after it has been translated and before it is rendered.
*
* This hook is invoked from _menu_link_translate() after a menu link has been
* translated; i.e., after the user access to the link's target page has
* been checked. It is only invoked if $menu_link['options']['alter'] has been
* set to a non-empty value (e.g. TRUE). This flag should be set using
* hook_ENTITY_TYPE_presave() for entity 'menu_link'.
*
* Implementations of this hook are able to alter any property of the menu link.
* For example, this hook may be used to add a page-specific query string to all
* menu links, or hide a certain link by setting:
* @code
* 'hidden' => 1,
* @endcode
*
* @param \Drupal\menu_link\Entity\MenuLink $menu_link
* A menu link entity.
*
* @see hook_menu_link_alter()
*/
function hook_translated_menu_link_alter(\Drupal\menu_link\Entity\MenuLink &$menu_link, $map) {
if ($menu_link->href == 'devel/cache/clear') {
$menu_link->localized_options['query'] = drupal_get_destination();
}
}
/**
* @} End of "addtogroup hooks".
*/
<?php
/**
* @file
* Install, update and uninstall functions for the menu_link module.
*/
/**
* Implements hook_schema().
*/
function menu_link_schema() {
$schema['menu_links'] = array(
'description' => 'Contains the individual links within a menu.',
'fields' => array(
'menu_name' => array(
'description' => "The menu name. All links with the same menu name (such as 'tools') are part of the same menu.",
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
),
'mlid' => array(
'description' => 'The menu link ID (mlid) is the integer primary key.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'machine_name' => array(
'description' => 'Unique machine name: Optional human-readable ID for this link.',
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
'plid' => array(
'description' => 'The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'link_path' => array(
'description' => 'The Drupal path or external path this link points to.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'langcode' => array(
'description' => 'The {language}.langcode of this link.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
),
'link_title' => array(
'description' => 'The text displayed for the link.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'options' => array(
'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.',
'type' => 'blob',
'not null' => FALSE,
'serialize' => TRUE,
),
'module' => array(
'description' => 'The name of the module that generated this link.',
'type' => 'varchar',
'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
'not null' => TRUE,
'default' => 'system',
),
'hidden' => array(
'description' => 'A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'external' => array(
'description' => 'A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'has_children' => array(
'description' => 'Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'expanded' => array(
'description' => 'Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded)',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'weight' => array(
'description' => 'Link weight among links in the same menu at the same depth.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'depth' => array(
'description' => 'The depth relative to the top level. A link with plid == 0 will have depth == 1.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'customized' => array(
'description' => 'A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'p1' => array(
'description' => 'The first mlid in the materialized path. If N = depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p2' => array(
'description' => 'The second mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p3' => array(
'description' => 'The third mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p4' => array(
'description' => 'The fourth mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p5' => array(
'description' => 'The fifth mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p6' => array(
'description' => 'The sixth mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p7' => array(
'description' => 'The seventh mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p8' => array(
'description' => 'The eighth mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'p9' => array(
'description' => 'The ninth mlid in the materialized path. See p1.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'updated' => array(
'description' => 'Flag that indicates that this link was generated during the update from Drupal 5.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'small',
),
'route_name' => array(
'description' => 'The machine name of a defined Symfony Route this menu item represents.',
'type' => 'varchar',
'length' => 255,
),
'route_parameters' => array(
'description' => 'Serialized array of route parameters of this menu link.',
'type' => 'blob',
'size' => 'big',
'not null' => FALSE,
'serialize' => TRUE,
),
),
'indexes' => array(
'path_menu' => array(array('link_path', 128), 'menu_name'),
'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded', 'has_children'),
'menu_parents' => array('menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
),
'primary key' => array('mlid'),
);
return $schema;
}
<?php
/**
* @file
* Enables users to create menu links.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\menu_link\Entity\MenuLink;
use Drupal\menu_link\MenuLinkInterface;
function menu_link_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.menu_link':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Menu Link module allows users to create menu links. It is required by the Menu UI module, which provides an interface for managing menus. See the <a href="!menu-help">Menu UI module help page</a> for more information.', array('!menu-help' => \Drupal::url('help.page', array('name' => 'menu_ui')))) . '</p>';
return $output;
}
}
/**
* Entity URI callback.
*
* @param \Drupal\menu_link\Entity\MenuLink $menu_link
* A menu link entity.
*/
function menu_link_uri(MenuLink $menu_link) {
return new Url($menu_link->route_name, $menu_link->route_parameters);
}
/**
* Loads a menu link entity.
*
* This function should never be called from within node_load() or any other
* function used as a menu object load function since an infinite recursion may
* occur.
*
* @param int $mlid
* The menu link ID.
* @param bool $reset
* (optional) Whether to reset the menu_link_load_multiple() cache.
*
* @return \Drupal\menu_link\Entity\MenuLink|null
* A menu link entity, or NULL if there is no entity with the given ID.
*
* @deprecated in Drupal 8.x, will be removed before Drupal 9.0.
* Use \Drupal\menu_link\Entity\MenuLink::load().
*/
function menu_link_load($mlid = NULL, $reset = FALSE) {
if ($reset) {
\Drupal::entityManager()->getStorage('menu_link')->resetCache(array($mlid));
}
return MenuLink::load($mlid);
}
/**
* Loads menu link entities from the database.
*
* @param array $mlids
* (optional) An array of entity IDs. If omitted, all entities are loaded.
* @param bool $reset
* (optional) Whether to reset the internal cache.
*
* @return array<\Drupal\menu_link\Entity\MenuLink>
* An array of menu link entities indexed by entity IDs.
*
* @see menu_link_load()
* @see entity_load_multiple()
*
* @deprecated in Drupal 8.x, will be removed before Drupal 9.0.
* Use \Drupal\menu_link\Entity\MenuLink::loadMultiple().
*/
function menu_link_load_multiple(array $mlids = NULL, $reset = FALSE) {
if ($reset) {
\Drupal::entityManager()->getStorage('menu_link')->resetCache($mlids);
}
return MenuLink::loadMultiple($mlids);
}
/**
* Deletes a menu link.
*
* @param int $mlid
* The menu link ID.
*
* @see menu_link_delete_multiple()
*/
function menu_link_delete($mlid) {
menu_link_delete_multiple(array($mlid));
}
/**
* Deletes multiple menu links.
*
* @param array $mlids
* An array of menu link IDs.
* @param bool $force
* (optional) Forces deletion. Internal use only, setting to TRUE is
* discouraged. Defaults to FALSE.
* @param bool $prevent_reparenting
* (optional) Disables the re-parenting logic from the deletion process.
* Defaults to FALSE.
*/
function menu_link_delete_multiple(array $mlids, $force = FALSE, $prevent_reparenting = FALSE) {
if (!$mlids) {
// If no IDs or invalid IDs were passed, do nothing.
return;
}
$controller = \Drupal::entityManager()
->getStorage('menu_link');
if (!$force) {
$entity_query = \Drupal::entityQuery('menu_link');
$group = $entity_query->orConditionGroup()
->condition('module', 'system', '<>')
->condition('updated', 0, '<>');
$entity_query->condition('mlid', $mlids, 'IN');
$entity_query->condition($group);
$result = $entity_query->execute();
$entities = $controller->loadMultiple($result);
}
else {
$entities = $controller->loadMultiple($mlids);
}
$controller->setPreventReparenting($prevent_reparenting);
$controller->delete($entities);
}
/**
* Saves a menu link.
*
* After calling this function, rebuild the menu cache using
* menu_cache_clear_all().
*
* @param \Drupal\menu_link\Entity\MenuLink $menu_link
* The menu link entity to be saved.
*
* @return int|bool
* Returns SAVED_NEW or SAVED_UPDATED if the save operation succeeded, or
* FALSE if it failed.
*/
function menu_link_save(MenuLink $menu_link) {
return $menu_link->save();
}
/**
* Inserts, updates, enables, disables, or deletes an uncustomized menu link.
*
* @param string $module
* The name of the module that owns the link.
* @param string $op
* Operation to perform: insert, update, enable, disable, or delete.
* @param string $link_path
* The path this link points to.
* @param string $link_title
* (optional) Title of the link to insert or new title to update the link to.
* Unused for delete. Defaults to NULL.
*
* @return integer|null
* The insert op returns the mlid of the new item. Others op return NULL.
*/
function menu_link_maintain($module, $op, $link_path, $link_title = NULL) {
$menu_link_controller = \Drupal::entityManager()
->getStorage('menu_link');
switch ($op) {
case 'insert':
$menu_link = entity_create('menu_link', array(
'link_title' => $link_title,
'link_path' => $link_path,
'module' => $module,)
);
return $menu_link->save();
case 'update':
$menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path, 'module' => $module, 'customized' => 0));
foreach ($menu_links as $menu_link) {
$menu_link->original = clone $menu_link;
if (isset($link_title)) {
$menu_link->link_title = $link_title;
}
$menu_link_controller->save($menu_link);
}
break;
case 'enable':
case 'disable':
$menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path, 'module' => $module, 'customized' => 0));
foreach ($menu_links as $menu_link) {
$menu_link->original = clone $menu_link;
$menu_link->hidden = ($op == 'disable' ? 1 : 0);
$menu_link->customized = 1;
if (isset($link_title)) {
$menu_link->link_title = $link_title;
}
$menu_link_controller->save($menu_link);
}
break;
case 'delete':
$result = \Drupal::entityQuery('menu_link')->condition('link_path', $link_path)->execute();
if (!empty($result)) {
menu_link_delete_multiple($result);
}
break;
}
}
/**
* Implements hook_system_breadcrumb_alter().
*/
function menu_link_system_breadcrumb_alter(array &$breadcrumb, RouteMatchInterface $route_match, array $context) {
// Custom breadcrumb behavior for editing menu links, we append a link to
// the menu in which the link is found.
if (($route_match->getRouteName() == 'menu_ui.link_edit') && $menu_link = $route_match->getParameter('menu_link')) {
if (($menu_link instanceof MenuLinkInterface) && !$menu_link->isNew()) {
// Add a link to the menu admin screen.
$menu = entity_load('menu', $menu_link->menu_name);
$breadcrumb[] = Drupal::l($menu->label(), 'menu_ui.menu_edit', array('menu' => $menu->id));
}
}
}
services:
menu_link.tree:
class: Drupal\menu_link\MenuTree
arguments: ['@database', '@cache.data', '@language_manager', '@request_stack', '@entity.manager', '@entity.query', '@state']
menu_link.static:
class: Drupal\menu_link\StaticMenuLinks
arguments: ['@module_handler']
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\menu_link\MenuLinkAccessController.
*/
namespace Drupal\menu_link;
use Drupal\Core\Entity\EntityAccessController;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines an access controller for the menu link entity.
*
* @see \Drupal\menu_link\Entity\MenuLink
*/
class MenuLinkAccessController extends EntityAccessController {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
$access = $account->hasPermission('administer menu');
if ($access) {
switch ($operation) {
case 'reset':
// Reset allowed for items defined via hook_menu() and customized.
return !empty($entity->machine_name) && $entity->customized;
case 'delete':
// Only items created by the Menu UI module can be deleted.
return $entity->module == 'menu_ui' || $entity->updated == 1;
}
}
return $access;
}
}
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\menu_link\MenuLinkInterface.
*/
namespace Drupal\menu_link;
use Drupal\Core\Entity\EntityInterface;
use Symfony\Component\Routing\Route;
/**
* Provides an interface defining a menu link entity.
*/
interface MenuLinkInterface extends EntityInterface {
/**
* Returns the Route object associated with this link, if any.
*
* @return \Symfony\Component\Routing\Route|null
* The route object for this menu link, or NULL if there isn't one.
*/
public function getRoute();
/**
* Sets the route object for this link.
*
* This should only be called by MenuLinkStorage when loading
* the link object. Calling it at other times could result in unpredictable
* behavior.
*
* @param \Symfony\Component\Routing\Route $route
*/
public function setRouteObject(Route $route);
/**
* Resets a system-defined menu link.
*
* @return \Drupal\menu_link\MenuLinkInterface
* A menu link entity.
*/
public function reset();
}
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\menu_link\MenuLinkStorageInterface.
*/
namespace Drupal\menu_link;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
/**
* Defines a common interface for menu link entity controller classes.
*/
interface MenuLinkStorageInterface extends EntityStorageInterface {
/**
* Sets an internal flag that allows us to prevent the reparenting operations
* executed during deletion.
*
* @param bool $value
* TRUE if reparenting should be allowed, FALSE if it should be prevented.
*/
public function setPreventReparenting($value = FALSE);
/**
* Gets value of internal flag that allows/prevents reparenting operations
* executed during deletion.
*
* @return bool
* TRUE if reparenting is allowed, FALSE if it is prevented.
*/
public function getPreventReparenting();
/**
* Loads system menu link as needed by system_get_module_admin_tasks().
*
* @return array
* An array of menu link entities indexed by their IDs.
*/
public function loadModuleAdminTasks();
/**
* Checks and updates the 'has_children' property for the parent of a link.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* A menu link entity.
*/
public function updateParentalStatus(EntityInterface $entity, $exclude = FALSE);
/**
* Finds the depth of an item's children relative to its depth.
*
* For example, if the item has a depth of 2 and the maximum of any child in
* the menu link tree is 5, the relative depth is 3.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* A menu link entity.
*
* @return int
* The relative depth, or zero.
*/
public function findChildrenRelativeDepth(EntityInterface $entity);
/**
* Updates the children of a menu link that is being moved.
*
* The menu name, parents (p1 - p6), and depth are updated for all children of
* the link, and the has_children status of the previous parent is updated.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* A menu link entity.
*/
public function moveChildren(EntityInterface $entity);
/**
* Returns the number of menu links from a menu.
*
* @param string $menu_name
* The unique name of a menu.
*/
public function countMenuLinks($menu_name);
/**
* Tries to derive menu link's parent from the path hierarchy.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* A menu link entity.
*
* @return \Drupal\Core\Entity\EntityInterface|false
* A menu link entity or FALSE if not valid parent was found.
*/
public function getParentFromHierarchy(EntityInterface $entity);
/**
* Builds a menu link entity from a default item.
*
* This function should only be called for link data from
* the menu_link.static service.
*
* @param array $item
* An item returned from the menu_link.static service.
*
* @return \Drupal\menu_link\MenuLinkInterface
* A menu link entity.
*/
public function createFromDefaultLink(array $item);
}
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\menu_link\MenuTreeInterface.
*/
namespace Drupal\menu_link;
/**
* Defines an interface for trees out of menu links.
*/
interface MenuTreeInterface {
/**
* Returns a rendered menu tree.
*
* The menu item's LI element is given one of the following classes:
* - expanded: The menu item is showing its submenu.
* - collapsed: The menu item has a submenu which is not shown.