diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index d205ac0..b371b7f 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -870,7 +870,7 @@ function menu_tail_load($arg, &$map, $index) {
*/
function _menu_link_translate(&$item, $translate = FALSE) {
if (!is_array($item['options'])) {
- $item['options'] = unserialize($item['options']);
+ //$item['options'] = unserialize($item['options']);
}
if ($item['external']) {
$item['access'] = 1;
@@ -1103,17 +1103,19 @@ function menu_tree_output($tree) {
$class[] = 'leaf';
}
// Set a class if the link is in the active trail.
+ $localized_options = $data['link']['localized_options']->getValue();
if ($data['link']['in_active_trail']) {
$class[] = 'active-trail';
- $data['link']['localized_options']['attributes']['class'][] = 'active-trail';
+ $localized_options['attributes']['class'][] = 'active-trail';
}
// Normally, l() compares the href of every link with the current path and
// sets the active class accordingly. But local tasks do not appear in menu
// trees, so if the current path is a local task, and this link is its
// tab root, then we have to set the class manually.
if ($data['link']['href'] == $router_item['tab_root_href'] && $data['link']['href'] != current_path()) {
- $data['link']['localized_options']['attributes']['class'][] = 'active';
+ $localized_options['attributes']['class'][] = 'active';
}
+ $data['link']['localized_options']->setValue($localized_options);
// Allow menu-specific theme overrides.
$element['#theme'] = 'menu_link__' . strtr($data['link']['menu_name'], '-', '_');
@@ -1662,7 +1664,7 @@ function theme_menu_link(array $variables) {
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
- $output = l($element['#title'], $element['#href'], $element['#localized_options']);
+ $output = l($element['#title'], $element['#href'], $element['#localized_options']->getValue());
return '
' . $output . $sub_menu . "\n";
}
@@ -1886,7 +1888,7 @@ function menu_navigation_links($menu_name, $level = 0) {
foreach ($tree as $item) {
if (!$item['link']['hidden']) {
$class = '';
- $l = $item['link']['localized_options'];
+ $l = $item['link']['localized_options']->getValue();
$l['href'] = $item['link']['href'];
$l['title'] = $item['link']['title'];
if ($item['link']['in_active_trail']) {
@@ -2654,7 +2656,7 @@ function menu_get_active_breadcrumb() {
}
foreach ($active_trail as $parent) {
- $breadcrumb[] = l($parent['title'], $parent['href'], $parent['localized_options']);
+ $breadcrumb[] = l($parent['title'], $parent['href'], is_array($parent['localized_options']) ? $parent['localized_options'] : $parent['localized_options']->getValue());
}
}
return $breadcrumb;
@@ -2865,6 +2867,8 @@ function _menu_navigation_links_rebuild($menu) {
array_multisort($sort, SORT_NUMERIC, $router_items);
foreach ($router_items as $key => $router_item) {
+ // Add the path to the item.
+ $router_item['path'] = $key;
// For performance reasons, do a straight query now and convert to a menu
// link entity later.
// @todo revisit before release.
@@ -2872,9 +2876,8 @@ function _menu_navigation_links_rebuild($menu) {
->fields('menu_links')
->condition('link_path', $router_item['path'])
->condition('module', 'system')
- ->execute()->fetchAll();
+ ->execute()->fetch();
if ($existing_item) {
- $existing_item = reset($existing_item);
$existing_item->options = unserialize($existing_item->options);
$router_item['mlid'] = $existing_item->mlid;
@@ -2900,8 +2903,8 @@ function _menu_navigation_links_rebuild($menu) {
$existing_item = NULL;
}
- if ($existing_item && $existing_item->customized) {
- $parent_candidates[$existing_item->mlid] = $existing_item;
+ if ($existing_item && $existing_item->customized->value) {
+ $parent_candidates[$existing_item->id()] = $existing_item;
}
else {
$menu_link = MenuLink::buildFromRouterItem($router_item);
@@ -2918,14 +2921,14 @@ function _menu_navigation_links_rebuild($menu) {
// Updated and customized items whose router paths are gone need new ones.
$menu_links = $menu_link_controller->loadUpdatedCustomized($paths);
foreach ($menu_links as $menu_link) {
- $router_path = _menu_find_router_path($menu_link->link_path);
- if (!empty($router_path) && ($router_path != $menu_link->router_path || $menu_link->updated)) {
+ $router_path = _menu_find_router_path($menu_link->link_path->value);
+ if (!empty($router_path) && ($router_path != $menu_link->router_path->value || $menu_link->updated->value)) {
// If the router path and the link path matches, it's surely a working
// item, so we clear the updated flag.
- $updated = $menu_link->updated && $router_path != $menu_link->link_path;
+ $updated = $menu_link->updated->value && $router_path != $menu_link->link_path->value;
- $menu_link->router_path = $router_path;
- $menu_link->updated = (int) $updated;
+ $menu_link->router_path->value = $router_path;
+ $menu_link->updated->value = (int) $updated;
$menu_link_controller->save($menu_link);
}
}
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 122cc63..314e0a2 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1725,9 +1725,9 @@ function theme_links($variables) {
// Handle title-only text items.
else {
// Merge in default array properties into $link.
- $link += array(
- 'html' => FALSE,
- );
+ if (!isset($link['html'])) {
+ $link['html'] = FALSE;
+ }
$item = ($link['html'] ? $link['title'] : check_plain($link['title']));
if (isset($link['attributes'])) {
$item = '' . $item . '';
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/MapItem.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/MapItem.php
new file mode 100644
index 0000000..073654b
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/MapItem.php
@@ -0,0 +1,115 @@
+ 'map',
+ 'label' => t('Array values'),
+ );
+ }
+ return static::$propertyDefinitions;
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Whether a offset exists
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ * @param mixed $offset
+ * An offset to check for.
+ *
+ * @return boolean true on success or false on failure.
+ *
+ *
+ * The return value will be casted to boolean if non-boolean was returned.
+ */
+ public function offsetExists($offset) {
+ return !(isset($this->values[$offset]) && isset($this->properties[$offset]));
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Offset to retrieve
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ * @param mixed $offset
+ * The offset to retrieve.
+ *
+ * @return mixed Can return all value types.
+ */
+ public function offsetGet($offset) {
+ // There is either a property object or a plain value - possibly for a
+ // not-defined property. If we have a plain value, directly return it.
+ if (isset($this->values[$offset])) {
+ return $this->values[$offset];
+ }
+ elseif (isset($this->properties[$offset])) {
+ return $this->properties[$offset]->getValue();
+ }
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Offset to set
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ * @param mixed $offset
+ * The offset to assign the value to.
+ *
+ * @param mixed $value
+ * The value to set.
+ *
+ * @return void
+ */
+ public function offsetSet($offset, $value) {
+ $this->set($offset, $value);
+ }
+
+ /**
+ * (PHP 5 >= 5.0.0)
+ * Offset to unset
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ * @param mixed $offset
+ * The offset to unset.
+ *
+ * @return void
+ */
+ public function offsetUnset($offset) {
+ $this->set($offset, NULL);
+ }
+
+
+}
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index e9e863e..bd22250 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -58,7 +58,7 @@ function book_entity_bundle_info() {
function book_menu_link_load($entities) {
foreach ($entities as $entity) {
// Change the bundle of menu links related to a book.
- if (strpos($entity->menu_name, 'book-toc-') === 0) {
+ if (strpos($entity->menu_name->value, 'book-toc-') === 0) {
$entity->bundle = 'book-toc';
}
}
diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
index 83d6098..e8e0ba6 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuFormController.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
@@ -316,7 +316,7 @@ protected function buildOverviewTreeForm($tree, $delta) {
$mlid = 'mlid:' . $item['mlid'];
$form[$mlid]['#item'] = $item;
$form[$mlid]['#attributes'] = $item['hidden'] ? array('class' => array('menu-disabled')) : array('class' => array('menu-enabled'));
- $form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']);
+ $form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']->getValue());
if ($item['hidden']) {
$form[$mlid]['title']['#markup'] .= ' (' . t('disabled') . ')';
}
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 4906043..a7a211c 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -188,7 +188,7 @@ function menu_enable() {
$system_link = reset($system_link);
$base_link = entity_create('menu_link', array(
- 'menu_name' => $system_link->menu_name,
+ 'menu_name' => $system_link->menu_name->value,
'router_path' => 'admin/structure/menu/manage/%menu',
'module' => 'menu',
));
@@ -201,8 +201,8 @@ function menu_enable() {
$link->link_path = 'admin/structure/menu/manage/' . $menu->id();
$query = Drupal::entityQuery('menu_link')
- ->condition('link_path', $link->link_path)
- ->condition('plid', $link->plid);
+ ->condition('link_path', $link->link_path->value)
+ ->condition('plid', $link->plid->value);
$result = $query->execute();
if (empty($result)) {
@@ -598,7 +598,7 @@ function menu_form_node_form_alter(&$form, $form_state) {
);
// Get number of items in menu so the weight selector is sized appropriately.
- $delta = entity_get_controller('menu_link')->countMenuLinks($link->menu_name);
+ $delta = entity_get_controller('menu_link')->countMenuLinks($link->menu_name->value);
if ($delta < 50) {
// Old hardcoded value
$delta = 50;
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
index f51b585..7f7baaa 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
@@ -7,18 +7,15 @@
namespace Drupal\menu_link\Entity;
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\Annotation\EntityType;
+use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\menu_link\MenuLinkInterface;
+use Drupal\menu_link\MenuLinkStorageControllerInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
-use Drupal\Core\Entity\Annotation\EntityType;
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Entity\EntityStorageException;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
-use Drupal\Core\Entity\ContentEntityInterface;
-use Drupal\Core\Entity\Entity;
-
/**
* Defines the menu link entity class.
*
@@ -49,14 +46,7 @@
* }
* )
*/
-class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
-
- /**
- * The link's menu name.
- *
- * @var string
- */
- public $menu_name = 'tools';
+class MenuLink extends EntityNG implements \ArrayAccess, MenuLinkInterface {
/**
* The link's bundle.
@@ -66,208 +56,42 @@ class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
public $bundle = 'tools';
/**
- * The menu link ID.
- *
- * @var int
- */
- public $mlid;
-
- /**
- * The menu link UUID.
- *
- * @var string
- */
- public $uuid;
-
- /**
- * The parent link ID.
- *
- * @var int
- */
- public $plid;
-
- /**
- * The Drupal path or external path this link points to.
+ * The route object associated with this menu link, if any.
*
- * @var string
+ * @var \Symfony\Component\Routing\Route
*/
- public $link_path;
+ protected $routeObject;
/**
- * For links corresponding to a Drupal path (external = 0), this connects the
- * link to a {menu_router}.path for joins.
+ * Crap coming from the old routing system.
*
- * @var string
- */
- public $router_path;
-
- /**
- * The entity label.
- *
- * @var string
- */
- public $link_title = '';
-
- /**
- * A serialized array of options to be passed to the url() or l() function,
- * such as a query string or HTML attributes.
+ * @todo Remove when we rip out the old routing system.
*
* @var array
*/
- public $options = array();
-
- /**
- * The name of the module that generated this link.
- *
- * @var string
- */
- public $module = 'menu';
-
- /**
- * A flag for whether the link should be rendered in menus.
- *
- * @var int
- */
- public $hidden = 0;
-
- /**
- * A flag to indicate if the link points to a full URL starting with a
- * protocol, like http:// (1 = external, 0 = internal).
- *
- * @var int
- */
- public $external;
-
- /**
- * Flag indicating whether any links have this link as a parent.
- *
- * @var int
- */
- public $has_children = 0;
+ protected $oldRouterItem = array();
/**
- * 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.
+ * Properties of the old routing system.
*
- * @var int
- */
- public $expanded = 0;
-
- /**
- * Link weight among links in the same menu at the same depth.
- *
- * @var int
- */
- public $weight = 0;
-
- /**
- * The depth relative to the top level. A link with plid == 0 will have
- * depth == 1.
- *
- * @var int
- */
- public $depth;
-
- /**
- * A flag to indicate that the user has manually created or edited the link.
+ * @todo Remove when we rip out the old routing system.
*
- * @var int
- */
- public $customized = 0;
-
- /**
- * The first entity ID in the materialized path.
- *
- * @var int
- *
- * @todo Investigate whether the p1, p2, .. pX properties can be moved to a
- * single array property.
- */
- public $p1;
-
- /**
- * The second entity ID in the materialized path.
- *
- * @var int
- */
- public $p2;
-
- /**
- * The third entity ID in the materialized path.
- *
- * @var int
- */
- public $p3;
-
- /**
- * The fourth entity ID in the materialized path.
- *
- * @var int
- */
- public $p4;
-
- /**
- * The fifth entity ID in the materialized path.
- *
- * @var int
- */
- public $p5;
-
- /**
- * The sixth entity ID in the materialized path.
- *
- * @var int
- */
- public $p6;
-
- /**
- * The seventh entity ID in the materialized path.
- *
- * @var int
- */
- public $p7;
-
- /**
- * The eighth entity ID in the materialized path.
- *
- * @var int
- */
- public $p8;
-
- /**
- * The ninth entity ID in the materialized path.
- *
- * @var int
- */
- public $p9;
-
- /**
- * The menu link modification timestamp.
- *
- * @var int
- */
- public $updated = 0;
-
- /**
- * The name of the route associated with this menu link, if any.
- *
- * @var string
- */
- public $route_name;
-
- /**
- * The route object associated with this menu link, if any.
- *
- * @var \Symfony\Component\Routing\Route
+ * @var array
*/
- protected $routeObject;
+ protected $oldRoutingProperties = array(
+ 'path', 'load_functions', 'to_arg_functions', 'access_callback',
+ 'access_arguments', 'page_callback', 'page_arguments', 'fit',
+ 'number_parts', 'context', 'tab_parent', 'tab_root', 'title',
+ 'title_callback', 'title_arguments', 'theme_callback', 'theme_arguments',
+ 'type', 'description', 'description_callback', 'description_arguments',
+ 'position', 'include_file', 'route_name',
+ );
/**
- * Overrides Entity::id().
+ * {@inheritdoc}
*/
public function id() {
- return $this->mlid;
+ return $this->get('mlid')->value;
}
/**
@@ -282,7 +106,7 @@ public function bundle() {
*/
public function createDuplicate() {
$duplicate = parent::createDuplicate();
- $duplicate->plid = NULL;
+ $duplicate->get('plid')->offsetGet(0)->set('value', NULL);
return $duplicate;
}
@@ -290,12 +114,12 @@ public function createDuplicate() {
* {@inheritdoc}
*/
public function getRoute() {
- if (!$this->route_name) {
+ if (!$this->getRouteName()) {
return NULL;
}
if (!($this->routeObject instanceof Route)) {
$route_provider = \Drupal::service('router.route_provider');
- $this->routeObject = $route_provider->getRouteByName($this->route_name);
+ $this->routeObject = $route_provider->getRouteByName($this->getRouteName());
}
return $this->routeObject;
}
@@ -317,11 +141,11 @@ public function reset() {
// not stored anywhere else. Since resetting a link happens rarely and this
// is a one-time operation, retrieving the full menu router does no harm.
$menu = menu_get_router();
- $router_item = $menu[$this->router_path];
+ $router_item = $menu[$this->getRouterPath()];
$new_link = self::buildFromRouterItem($router_item);
// Merge existing menu link's ID and 'has_children' property.
foreach (array('mlid', 'has_children') as $key) {
- $new_link->{$key} = $this->{$key};
+ $new_link->{$key}->value = $this->{$key}->value;
}
$new_link->save();
return $new_link;
@@ -352,31 +176,68 @@ public static function buildFromRouterItem(array $item) {
}
/**
- * Implements ArrayAccess::offsetExists().
+ * {@inheritdoc}
*/
public function offsetExists($offset) {
- return isset($this->{$offset});
+ if (in_array($offset, $this->oldRoutingProperties)) {
+ return isset($this->oldRouterItem[$offset]);
+ }
+ return isset($this->{$offset}->value);
}
/**
- * Implements ArrayAccess::offsetGet().
+ * {@inheritdoc}
*/
- public function &offsetGet($offset) {
- return $this->{$offset};
+ public function offsetGet($offset) {
+ if (in_array($offset, $this->oldRoutingProperties)) {
+ return $this->oldRouterItem[$offset];
+ }
+ elseif ($offset == 'localized_options' || $offset == 'options') {
+ return $this->get($offset)->offsetGet(0);
+ }
+ elseif ($this->getPropertyDefinition($offset)) {
+ return $this->get($offset)->value;
+ }
+ else {
+ return $this->$offset;
+ }
}
/**
- * Implements ArrayAccess::offsetSet().
+ * {@inheritdoc}
*/
public function offsetSet($offset, $value) {
- $this->{$offset} = $value;
+ if (in_array($offset, $this->oldRoutingProperties)) {
+ $this->oldRouterItem[$offset] = $value;
+ }
+ elseif ($this->getPropertyDefinition($offset)) {
+ $this->{$offset}->value = $value;
+ }
+ else {
+ $this->{$offset} = $value;
+ }
}
/**
- * Implements ArrayAccess::offsetUnset().
+ * {@inheritdoc}
*/
public function offsetUnset($offset) {
- unset($this->{$offset});
+ if (in_array($offset, $this->oldRoutingProperties)) {
+ unset($this->oldRouterItem[$offset]);
+ }
+ else {
+ $this->{$offset}->value = NULL;
+ }
+// unset($this->{$offset});
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
+ if (empty($values['menu_name'])) {
+ $values['menu_name'] = $values['bundle'] = 'tools';
+ }
}
/**
@@ -390,10 +251,10 @@ public static function preDelete(EntityStorageControllerInterface $storage_contr
foreach ($entities as $entity) {
// Children get re-attached to the item's parent.
- if ($entity->has_children) {
- $children = $storage_controller->loadByProperties(array('plid' => $entity->plid));
+ if ($entity->hasChildren()) {
+ $children = $storage_controller->loadByProperties(array('plid' => $entity->getParentLinkId()));
foreach ($children as $child) {
- $child->plid = $entity->plid;
+ $child->setParentLinkId($entity->getParentLinkId());
$storage_controller->save($child);
}
}
@@ -412,8 +273,8 @@ public static function postDelete(EntityStorageControllerInterface $storage_cont
}
// Store all menu names for which we need to clear the cache.
- if (!isset($affected_menus[$entity->menu_name])) {
- $affected_menus[$entity->menu_name] = $entity->menu_name;
+ if (!isset($affected_menus[$entity->getMenuName()])) {
+ $affected_menus[$entity->getMenuName()] = $entity->getMenuName();
}
}
@@ -429,63 +290,64 @@ public static function postDelete(EntityStorageControllerInterface $storage_cont
public function preSave(EntityStorageControllerInterface $storage_controller) {
// This is the easiest way to handle the unique internal path '',
// since a path marked as external does not need to match a router path.
- $this->external = (url_is_external($this->link_path) || $this->link_path == '') ? 1 : 0;
+ $this->external->value = (url_is_external($this->getLinkPath()) || $this->getLinkPath() == '') ? 1 : 0;
// Try to find a parent link. If found, assign it and derive its menu.
$parent_candidates = !empty($this->parentCandidates) ? $this->parentCandidates : array();
$parent = $this->findParent($storage_controller, $parent_candidates);
if ($parent) {
- $this->plid = $parent->id();
- $this->menu_name = $parent->menu_name;
+ $this->setParentLinkId($parent->id());
+ $this->setMenuName($parent->getMenuName());
}
// If no corresponding parent link was found, move the link to the top-level.
else {
- $this->plid = 0;
+ $this->setParentLinkId(0);
}
// Directly fill parents for top-level links.
- if ($this->plid == 0) {
- $this->p1 = $this->id();
+ if ($this->getParentLinkId() == 0) {
+ $this->p1->value = $this->id();
for ($i = 2; $i <= MENU_MAX_DEPTH; $i++) {
$parent_property = "p$i";
- $this->{$parent_property} = 0;
+ $this->{$parent_property}->value = 0;
}
- $this->depth = 1;
+ $this->depth->value = 1;
}
// Otherwise, ensure that this link's depth is not beyond the maximum depth
// and fill parents based on the parent link.
else {
- if ($this->has_children && $this->original) {
+ if ($this->hasChildren() && $this->original) {
$limit = MENU_MAX_DEPTH - $storage_controller->findChildrenRelativeDepth($this->original) - 1;
}
else {
$limit = MENU_MAX_DEPTH - 1;
}
- if ($parent->depth > $limit) {
+ if ($parent->getDepth() > $limit) {
return FALSE;
}
- $this->depth = $parent->depth + 1;
+ $this->depth->value = $parent->getDepth() + 1;
$this->setParents($parent);
}
// Need to check both plid and menu_name, since plid can be 0 in any menu.
- if (isset($this->original) && ($this->plid != $this->original->plid || $this->menu_name != $this->original->menu_name)) {
+ if (isset($this->original) && ($this->getParentLinkId() != $this->original->getParentLinkId() || $this->getMenuName() != $this->original->getMenuName())) {
$storage_controller->moveChildren($this, $this->original);
}
// Find the router_path.
- if (empty($this->router_path) || empty($this->original) || (isset($this->original) && $this->original->link_path != $this->link_path)) {
- if ($this->external) {
- $this->router_path = '';
+ if (!($this->getRouterPath()) || empty($this->original) || (isset($this->original) && $this->original->getLinkPath() != $this->getLinkPath())) {
+ if ($this->isExternal()) {
+ $this->setRouterPath('');
}
else {
// Find the router path which will serve this path.
- $this->parts = explode('/', $this->link_path, MENU_MAX_PARTS);
- $this->router_path = _menu_find_router_path($this->link_path);
+ // @todo Where do we need 'parts'?
+ $this->parts = explode('/', $this->getLinkPath(), MENU_MAX_PARTS);
+ $this->setRouterPath(_menu_find_router_path($this->getLinkPath()));
}
}
// Find the route_name.
- if (!isset($this->route_name)) {
- $this->route_name = $this::findRouteName($this->link_path);
+ if (!$this->getRouteName()) {
+ $this->setRouteName($this::findRouteName($this->getLinkPath()));
}
}
@@ -496,9 +358,9 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
// Check the has_children status of the parent.
$storage_controller->updateParentalStatus($this);
- menu_cache_clear($this->menu_name);
- if (isset($this->original) && $this->menu_name != $this->original->menu_name) {
- menu_cache_clear($this->original->menu_name);
+ menu_cache_clear($this->getMenuName());
+ if (isset($this->original) && $this->getMenuName() != $this->original->getMenuName()) {
+ menu_cache_clear($this->original->getMenuName());
}
// Now clear the cache.
@@ -527,46 +389,45 @@ public static function findRouteName($link_path) {
/**
* {@inheritdoc}
*/
- public function setParents(EntityInterface $parent) {
+ public function setParents(MenuLinkInterface $parent) {
$i = 1;
- while ($i < $this->depth) {
+ while ($i < $this->getDepth()) {
$p = 'p' . $i++;
- $this->{$p} = $parent->{$p};
+ $this->{$p}->value = $parent->getMaterializedPathEntity($p);
}
$p = 'p' . $i++;
// The parent (p1 - p9) corresponding to the depth always equals the mlid.
- $this->{$p} = $this->id();
+ $this->{$p}->value = $this->id();
while ($i <= MENU_MAX_DEPTH) {
$p = 'p' . $i++;
- $this->{$p} = 0;
+ $this->{$p}->value = 0;
}
}
/**
* {@inheritdoc}
*/
- public function findParent(EntityStorageControllerInterface $storage_controller, array $parent_candidates = array()) {
+ public function findParent(MenuLinkStorageControllerInterface $storage_controller, array $parent_candidates = array()) {
$parent = FALSE;
+ $plid = $this->getParentLinkId();
// This item is explicitely top-level, skip the rest of the parenting.
- if (isset($this->plid) && empty($this->plid)) {
+ if (!$plid === 0) {
return $parent;
}
// If we have a parent link ID, try to use that.
$candidates = array();
- if (isset($this->plid)) {
- $candidates[] = $this->plid;
+ if ($plid) {
+ $candidates = array($plid);
}
// Else, if we have a link hierarchy try to find a valid parent in there.
- if (!empty($this->depth) && $this->depth > 1) {
- for ($depth = $this->depth - 1; $depth >= 1; $depth--) {
- $parent_property = "p$depth";
- $candidates[] = $this->$parent_property;
+ if ($this->getDepth() > 1) {
+ for ($depth = $this->getDepth() - 1; $depth >= 1; $depth--) {
+ $candidates[] = $this->getMaterializedPathEntity($depth);
}
}
-
foreach ($candidates as $mlid) {
if (isset($parent_candidates[$mlid])) {
$parent = $parent_candidates[$mlid];
@@ -582,12 +443,227 @@ public function findParent(EntityStorageControllerInterface $storage_controller,
// If everything else failed, try to derive the parent from the path
// hierarchy. This only makes sense for links derived from menu router
// items (ie. from hook_menu()).
- if ($this->module == 'system') {
+ if ($this->getModule() == 'system') {
$parent = $storage_controller->getParentFromHierarchy($this);
}
return $parent;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getMenuName() {
+ return $this->get('menu_name')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMenuName($menu_name) {
+ $this->set('menu_name', $menu_name);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParentLinkId() {
+ return $this->get('plid')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParentLinkId($plid) {
+ $this->set('plid', $plid);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLinkPath() {
+ return $this->get('link_path')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLinkPath($link_path) {
+ $this->set('link_path', $link_path);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLinkTitle() {
+ return $this->get('link_title')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLinkTitle($link_title) {
+ $this->set('link_title', $link_title);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRouterPath() {
+ return $this->get('router_path')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setRouterPath($router_path) {
+ $this->set('router_path', $router_path);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOptions() {
+ return $this->get('options')->offsetGet(0)->getValue();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setOptions(array $options) {
+ $this->get('options')->offsetGet(0)->setValue($options);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getModule() {
+ return $this->get('module')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setModule($module) {
+ $this->set('module', $module);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setExpanded($expanded) {
+ $this->set('expanded', $expanded ? 1 : 0);
+ }
+
+ /**v
+ */
+ public function isExpanded() {
+ return (bool) $this->get('expanded')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isExternal() {
+ return (bool) $this->get('external')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCustomized($customized) {
+ $this->set('customized', $customized);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCustomized() {
+ return (bool) $this->get('customized')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setHidden($hidden) {
+ $this->set('hidden', $hidden ? 1 : 0);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isHidden() {
+ return (bool)$this->get('hidden')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasChildren() {
+ return (bool)$this->get('has_children')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDepth() {
+ return $this->get('depth')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getWeight() {
+ return $this->get('weight')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setWeight($weight) {
+ $this->set('weight', $weight);
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMaterializedPathEntity($depth) {
+ if ($depth < 1 || $depth > 9) {
+ return NULL;
+ }
+ return $this->get('p' . $depth)->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChangedTime() {
+ return $this->get('updated')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRouteName() {
+ return $this->get('route_name')->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setRouteName($route_name) {
+ $this->set('route_name', $route_name);
+ return $this;
+ }
}
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkAccessController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkAccessController.php
index a1c2c69..e710775 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkAccessController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkAccessController.php
@@ -27,11 +27,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
switch ($operation) {
case 'reset':
// Reset allowed for items defined via hook_menu() and customized.
- return $entity->module == 'system' && $entity->customized;
+ return $entity->module->value == 'system' && $entity->customized->value;
case 'delete':
// Only items created by the menu module can be deleted.
- return $entity->module == 'menu' || $entity->updated == 1;
+ return $entity->module->value == 'menu' || $entity->updated->value == 1;
}
}
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
index e94a0a6..e5f5673 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
@@ -7,7 +7,8 @@
namespace Drupal\menu_link;
-use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityControllerInterface;
+use Drupal\Core\Entity\EntityFormControllerNG;
use Drupal\Core\Language\Language;
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Routing\UrlGenerator;
@@ -17,7 +18,7 @@
/**
* Form controller for the node edit forms.
*/
-class MenuLinkFormController extends EntityFormController {
+class MenuLinkFormController extends EntityFormControllerNG {
/**
* The menu link storage controller.
@@ -79,37 +80,37 @@ public function form(array $form, array &$form_state) {
if (!$menu_link->isNew()) {
// Get the human-readable menu title from the given menu name.
$titles = menu_get_menus();
- $current_title = $titles[$menu_link->menu_name];
+ $current_title = $titles[$menu_link->menu_name->value];
// Get the current breadcrumb and add a link to that menu's overview page.
$breadcrumb = menu_get_active_breadcrumb();
- $breadcrumb[] = l($current_title, 'admin/structure/menu/manage/' . $menu_link->menu_name);
+ $breadcrumb[] = l($current_title, 'admin/structure/menu/manage/' . $menu_link->menu_name->value);
drupal_set_breadcrumb($breadcrumb);
}
$form['link_title'] = array(
'#type' => 'textfield',
'#title' => t('Menu link title'),
- '#default_value' => $menu_link->link_title,
+ '#default_value' => $menu_link->link_title->value,
'#description' => t('The text to be used for this link in the menu.'),
'#required' => TRUE,
);
foreach (array('link_path', 'mlid', 'module', 'has_children', 'options') as $key) {
- $form[$key] = array('#type' => 'value', '#value' => $menu_link->{$key});
+ $form[$key] = array('#type' => 'value', '#value' => $menu_link->{$key}->value);
}
// Any item created or edited via this interface is considered "customized".
$form['customized'] = array('#type' => 'value', '#value' => 1);
// We are not using url() when constructing this path because it would add
// $base_path.
- $path = $menu_link->link_path;
- if (isset($menu_link->options['query'])) {
- $path .= '?' . $this->urlGenerator->httpBuildQuery($menu_link->options['query']);
+ $path = $menu_link->link_path->value;
+ if (isset($menu_link->options->value['query'])) {
+ $path .= '?' . $this->urlGenerator->httpBuildQuery($menu_link->options->value['query']);
}
- if (isset($menu_link->options['fragment'])) {
- $path .= '#' . $menu_link->options['fragment'];
+ if (isset($menu_link->options->value['fragment'])) {
+ $path .= '#' . $menu_link->options->value['fragment'];
}
- if ($menu_link->module == 'menu') {
+ if ($menu_link->module->value == 'menu') {
$form['link_path'] = array(
'#type' => 'textfield',
'#title' => t('Path'),
@@ -123,33 +124,33 @@ public function form(array $form, array &$form_state) {
$form['_path'] = array(
'#type' => 'item',
'#title' => t('Path'),
- '#description' => l($menu_link->link_title, $menu_link->href, $menu_link->options),
+ '#description' => l($menu_link->link_title->value, $menu_link->href, $menu_link->options->get('value')->getValue()),
);
}
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
- '#default_value' => isset($menu_link->options['attributes']['title']) ? $menu_link->options['attributes']['title'] : '',
+ '#default_value' => isset($menu_link->options->value['attributes']['title']) ? $menu_link->options->value['attributes']['title'] : '',
'#rows' => 1,
'#description' => t('Shown when hovering over the menu link.'),
);
$form['enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Enabled'),
- '#default_value' => !$menu_link->hidden,
+ '#default_value' => !$menu_link->hidden->value,
'#description' => t('Menu links that are not enabled will not be listed in any menu.'),
);
$form['expanded'] = array(
'#type' => 'checkbox',
'#title' => t('Show as expanded'),
- '#default_value' => $menu_link->expanded,
+ '#default_value' => $menu_link->expanded->value,
'#description' => t('If selected and this menu link has children, the menu will always appear expanded.'),
);
// Generate a list of possible parents (not including this link or descendants).
$options = menu_parent_options(menu_get_menus(), $menu_link);
- $default = $menu_link->menu_name . ':' . $menu_link->plid;
+ $default = $menu_link->menu_name->value . ':' . $menu_link->plid->target_id;
if (!isset($options[$default])) {
$default = 'tools:0';
}
@@ -163,13 +164,13 @@ public function form(array $form, array &$form_state) {
);
// Get number of items in menu so the weight selector is sized appropriately.
- $delta = $this->menuLinkStorageController->countMenuLinks($menu_link->menu_name);
+ $delta = $this->menuLinkStorageController->countMenuLinks($menu_link->menu_name->value);
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
// Old hardcoded value.
'#delta' => max($delta, 50),
- '#default_value' => $menu_link->weight,
+ '#default_value' => $menu_link->weight->value,
'#description' => t('Optional. In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'),
);
@@ -179,13 +180,13 @@ public function form(array $form, array &$form_state) {
// be configured individually.
if ($this->moduleHandler->moduleExists('language')) {
$language_configuration = language_get_default_configuration('menu_link', $menu_link->bundle());
- $default_langcode = ($menu_link->isNew() ? $language_configuration['langcode'] : $menu_link->langcode);
+ $default_langcode = ($menu_link->isNew() ? $language_configuration['langcode'] : $menu_link->langcode->value);
$language_show = $language_configuration['language_show'];
}
// Without Language module menu links inherit the menu language and no
// language selector is shown.
else {
- $default_langcode = ($menu_link->isNew() ? entity_load('menu', $menu_link->menu_name)->langcode : $menu_link->langcode);
+ $default_langcode = ($menu_link->isNew() ? entity_load('menu', $menu_link->menu_name->value)->langcode : $menu_link->langcode->value);
$language_show = FALSE;
}
@@ -212,74 +213,64 @@ protected function actions(array $form, array &$form_state) {
}
/**
- * Overrides EntityFormController::validate().
+ * {@inheritdoc}
*/
public function validate(array $form, array &$form_state) {
$menu_link = $this->buildEntity($form, $form_state);
- $normal_path = $this->pathAliasManager->getSystemPath($menu_link->link_path);
- if ($menu_link->link_path != $normal_path) {
+ $normal_path = $this->pathAliasManager->getSystemPath($menu_link->link_path->value);
+ if ($menu_link->link_path->value != $normal_path) {
drupal_set_message(t('The menu system stores system paths only, but will use the URL alias for display. %link_path has been stored as %normal_path', array('%link_path' => $menu_link->link_path, '%normal_path' => $normal_path)));
- $menu_link->link_path = $normal_path;
$form_state['values']['link_path'] = $normal_path;
+ $menu_link->link_path->value = $normal_path;
}
- if (!url_is_external($menu_link->link_path)) {
- $parsed_link = parse_url($menu_link->link_path);
+ if (!url_is_external($menu_link->link_path->value)) {
+ $parsed_link = parse_url($menu_link->link_path->value);
if (isset($parsed_link['query'])) {
- $menu_link->options['query'] = array();
+ $menu_link->options->value['query'] = array();
parse_str($parsed_link['query'], $menu_link->options['query']);
}
else {
// Use unset() rather than setting to empty string
// to avoid redundant serialized data being stored.
- unset($menu_link->options['query']);
+ unset($menu_link->options->value['query']);
}
if (isset($parsed_link['fragment'])) {
- $menu_link->options['fragment'] = $parsed_link['fragment'];
+ $menu_link->options->value['fragment'] = $parsed_link['fragment'];
}
else {
- unset($menu_link->options['fragment']);
+ unset($menu_link->options->value['fragment']);
}
- if (isset($parsed_link['path']) && $menu_link->link_path != $parsed_link['path']) {
- $menu_link->link_path = $parsed_link['path'];
+ if (isset($parsed_link['path']) && $menu_link->link_path->value != $parsed_link['path']) {
+ $menu_link->link_path->value = $parsed_link['path'];
}
}
- if (!trim($menu_link->link_path) || !drupal_valid_path($menu_link->link_path, TRUE)) {
- form_set_error('link_path', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $menu_link->link_path)));
+ if (!trim($menu_link->link_path->value) || !drupal_valid_path($menu_link->link_path->value, TRUE)) {
+ form_set_error('link_path', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $menu_link->link_path->value)));
}
parent::validate($form, $form_state);
}
- /**
- * Overrides EntityFormController::submit().
- */
- public function submit(array $form, array &$form_state) {
- // Build the menu link object from the submitted values.
- $menu_link = parent::submit($form, $form_state);
-
+ public function buildEntity(array $form, array &$form_state) {
+ $entity = parent::buildEntity($form, $form_state);
// The value of "hidden" is the opposite of the value supplied by the
// "enabled" checkbox.
- $menu_link->hidden = (int) !$menu_link->enabled;
- unset($menu_link->enabled);
-
- $menu_link->options['attributes']['title'] = $menu_link->description;
- list($menu_link->menu_name, $menu_link->plid) = explode(':', $menu_link->parent);
-
- return $menu_link;
+ $entity->hidden->value = (int) !$form_state['values']['enabled'];
+ list($entity->menu_name->value, $entity->plid->target_id) = explode(':', $form_state['values']['parent']);
+ $attributes = $entity->options[0]['attributes'];
+ $attributes['title'] = $form_state['values']['description'];
+ $entity->options->setValue(array('attributes' => $attributes));
+ return $entity;
}
/**
* Overrides EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
- $menu_link = $this->entity;
-
- $saved = $menu_link->save();
-
- if ($saved) {
+ if ($this->entity->save()) {
drupal_set_message(t('The menu link has been saved.'));
- $form_state['redirect'] = 'admin/structure/menu/manage/' . $menu_link->menu_name;
+ $form_state['redirect'] = 'admin/structure/menu/manage/' . $this->entity->menu_name->value;
}
else {
drupal_set_message(t('There was an error saving the menu link.'), 'error');
@@ -291,7 +282,6 @@ public function save(array $form, array &$form_state) {
* Overrides EntityFormController::delete().
*/
public function delete(array $form, array &$form_state) {
- $menu_link = $this->entity;
- $form_state['redirect'] = 'admin/structure/menu/item/' . $menu_link->id() . '/delete';
+ $form_state['redirect'] = 'admin/structure/menu/item/' . $this->entity->id() . '/delete';
}
}
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
index f4c4e0e..f4da275 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
@@ -10,7 +10,6 @@
use Symfony\Component\Routing\Route;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
/**
* Provides an interface defining a menu link entity.
@@ -69,10 +68,10 @@ public static function findRouteName($link_path);
/**
* Sets the p1 through p9 properties for a menu link entity being saved.
*
- * @param \Drupal\Core\Entity\EntityInterface $parent
+ * @param \Drupal\menu_link\MenuLinkInterface $parent
* A menu link entity.
*/
- public function setParents(EntityInterface $parent);
+ public function setParents(MenuLinkInterface $parent);
/**
* Finds a possible parent for a given menu link entity.
@@ -85,7 +84,7 @@ public function setParents(EntityInterface $parent);
* - else, for system menu links (derived from hook_menu()), reparent
* based on the path hierarchy.
*
- * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
+ * @param \Drupal\menu_link\MenuLinkStorageControllerInterface $storage_controller
* Storage controller object.
* @param array $parent_candidates
* An array of menu link entities keyed by mlid.
@@ -94,5 +93,282 @@ public function setParents(EntityInterface $parent);
* A menu link entity structure of the possible parent or FALSE if no valid
* parent has been found.
*/
- public function findParent(EntityStorageControllerInterface $storage_controller, array $parent_candidates = array());
+ public function findParent(MenuLinkStorageControllerInterface $storage_controller, array $parent_candidates = array());
+
+ /**
+ * Returns the menu name of this menu link.
+ *
+ * @return string
+ * The name of the menu.
+ */
+ public function getMenuName();
+
+ /**
+ * Sets the menu name of this menu link.
+ *
+ * @param string $menu_name
+ * The name of the menu.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setMenuName($menu_name);
+
+ /**
+ * Returns the parent menu link ID of this menu link.
+ *
+ * @return int
+ * The parent link ID of the menu.
+ */
+ public function getParentLinkId();
+
+ /**
+ * Sets the parent menu link id of this menu link.
+ *
+ * @param int $plid
+ * The parent link ID of the menu.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setParentLinkId($plid);
+
+ /**
+ * Returns the Drupal path or external path this link points to.
+ *
+ * @return string
+ * The Drupal path or external path this link points to.
+ */
+ public function getLinkPath();
+
+ /**
+ * Sets the Drupal path or external path this link points to.
+ *
+ * @param string $link_path
+ * The the Drupal path or external path this link points to.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setLinkPath($link_path);
+
+ /**
+ * Returns the title of this menu link.
+ *
+ * @return string
+ * The title of this menu link.
+ */
+ public function getLinkTitle();
+
+ /**
+ * Sets the title of this menu link.
+ *
+ * @param string $link_title
+ * The title of this menu link.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setLinkTitle($link_title);
+
+ /**
+ * Returns the menu router path for this link.
+ *
+ * @return string
+ * The menu router path for this link.
+ */
+ public function getRouterPath();
+
+ /**
+ * Sets the Drupal path or external path this link points to.
+ *
+ * @param string $router_path
+ * The menu router path for this link.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setRouterPath($router_path);
+
+ /**
+ * Returns the menu link options.
+ *
+ * @return array
+ * The menu link options, to be passed to to l() or url().
+ */
+ public function getOptions();
+
+ /**
+ * Sets the menu link options.
+ *
+ * @todo: Add a method to add options?
+ *
+ * @param array $options
+ * The menu link options.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setOptions(array $options);
+
+ /**
+ * Returns the name of the module that generated this link.
+ *
+ * @return string
+ * The name of the module that generated this link.
+ */
+ public function getModule();
+
+ /**
+ * Sets the name of the module that generated this link.
+ *
+ * @param string $module
+ * The name of the module that generated this link.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setModule($module);
+
+ /**
+ * Sets whether the menu link is expanded.
+ *
+ * @param bool $expanded
+ * TRUE if the menu link is expanded, FALSE if not.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setExpanded($expanded);
+
+ /**
+ * Returns whether the menu link is expanded
+ *
+ * @return string
+ * TRUE if the menu link is expanded, FALSE if not.
+ */
+ public function isExpanded();
+
+ /**
+ * Returns whether the menu link is external.
+ *
+ * @return string
+ * TRUE if the menu link is external, FALSE if not.
+ */
+ public function isExternal();
+
+ /**
+ * Sets if the menu link is customized.
+ *
+ * @param bool $customized
+ * TRUE if the menu link is customized, FALSE if not.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setCustomized($customized);
+
+ /**
+ * Returns whether the menu link is customized.
+ *
+ * @return string
+ * TRUE if the menu link is customized, FALSE if not.
+ */
+ public function isCustomized();
+
+ /**
+ * Sets whether the menu link is hidden.
+ *
+ * @param bool $hidden
+ * TRUE if the menu link is hidden, FALSE if not.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setHidden($hidden);
+
+ /**
+ * Returns whether the menu link is hidden.
+ *
+ * @return string
+ * TRUE if the menu link is hidden, FALSE if not.
+ */
+ public function isHidden();
+
+ /**
+ * Returns whether the menu link is expanded
+ *
+ * @return string
+ * TRUE if the menu link has children, FALSE if not.
+ */
+ public function hasChildren();
+
+ /**
+ * Returns the depth relative to the top level of this link.
+ *
+ * A link with parent ID 0 will have depth of 1.
+ *
+ * @return int
+ * The menu link depth.
+ */
+ public function getDepth();
+
+ /**
+ * Returns the weight among menu links with the same depth.
+ *
+ * @return int
+ * The menu link weight.
+ */
+ public function getWeight();
+
+ /**
+ * Sets the weight among menu links with the same depth.
+ *
+ *ยท@param int $weight
+ * The menu link weight.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setWeight($weight);
+
+ /**
+ * Returns the nth depth entity ID of the materialized path.
+ *
+ * @param int $depth
+ * Indicates the depth of entity ID of the materialized path that should be
+ * returned, between 1 and 9.
+ *
+ * @return int
+ * Nth Entity ID of the materialized path.
+ */
+ public function getMaterializedPathEntity($depth);
+
+ /**
+ * Returns the menu link modification timestamp.
+ *
+ * @return int
+ * Menu link modification timestamp.
+ */
+ public function getChangedTime();
+
+ /**
+ * Returns the route name associated with this menu link, if any.
+ *
+ * @return string|null
+ * The route name of this menu link.
+ */
+ public function getRouteName();
+
+ /**
+ * Sets the route name associated with this menu link.
+ *
+ * @param string|null $route_name
+ * The route name associated with this menu link.
+ *
+ * @return \Drupal\menu_link\MenuLinkInterface
+ * The called menu link entity.
+ */
+ public function setRouteName($route_name);
+
}
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
index 43d54ce..d23a96f 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
@@ -7,7 +7,7 @@
namespace Drupal\menu_link;
-use Drupal\Core\Entity\DatabaseStorageController;
+use Drupal\Core\Entity\DatabaseStorageControllerNG;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Database\Connection;
@@ -15,12 +15,9 @@
use Symfony\Cmf\Component\Routing\RouteProviderInterface;
/**
- * Controller class for menu links.
- *
- * This extends the Drupal\entity\DatabaseStorageController class, adding
- * required special handling for menu_link entities.
+ * Defines the storage controller class for menu links.
*/
-class MenuLinkStorageController extends DatabaseStorageController implements MenuLinkStorageControllerInterface {
+class MenuLinkStorageController extends DatabaseStorageControllerNG implements MenuLinkStorageControllerInterface {
/**
* Indicates whether the delete operation should re-parent children items.
@@ -44,16 +41,7 @@ class MenuLinkStorageController extends DatabaseStorageController implements Men
protected $routeProvider;
/**
- * Overrides DatabaseStorageController::__construct().
- *
- * @param string $entity_type
- * The entity type for which the instance is created.
- * @param array $entity_info
- * An array of entity info for the entity type.
- * @param \Drupal\Core\Database\Connection $database
- * The database connection to be used.
- * @param \Symfony\Cmf\Component\Routing\RouteProviderInterface $route_provider
- * The route provider service.
+ * {@inheritdoc}
*/
public function __construct($entity_type, array $entity_info, Connection $database, RouteProviderInterface $route_provider) {
parent::__construct($entity_type, $entity_info, $database);
@@ -90,7 +78,7 @@ public static function createInstance(ContainerInterface $container, $entity_typ
}
/**
- * Overrides DatabaseStorageController::buildQuery().
+ * {@inheritdoc}
*/
protected function buildQuery($ids, $revision_id = FALSE) {
$query = parent::buildQuery($ids, $revision_id);
@@ -101,50 +89,60 @@ protected function buildQuery($ids, $revision_id = FALSE) {
}
/**
- * Overrides DatabaseStorageController::attachLoad().
- *
- * @todo Don't call parent::attachLoad() at all because we want to be able to
- * control the entity load hooks.
+ * {@inheritdoc}
*/
- protected function attachLoad(&$menu_links, $load_revision = FALSE) {
+ protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
$routes = array();
- foreach ($menu_links as &$menu_link) {
- $menu_link->options = unserialize($menu_link->options);
+ foreach ($queried_entities as &$record) {
+ $record->options = unserialize($record->options);
// Use the weight property from the menu link.
- $menu_link->router_item['weight'] = $menu_link->weight;
+ $record->router_item['weight'] = $record->weight;
// By default use the menu_name as type.
- $menu_link->bundle = $menu_link->menu_name;
+ $record->bundle = $record->menu_name;
// For all links that have an associated route, load the route object now
// and save it on the object. That way we avoid a select N+1 problem later.
- if ($menu_link->route_name) {
- $routes[$menu_link->id()] = $menu_link->route_name;
+ if ($record->route_name) {
+ $routes[$record->{$this->idKey}] = $record->route_name;
}
}
+ parent::attachLoad($queried_entities, $load_revision);
+
// Now mass-load any routes needed and associate them.
if ($routes) {
$route_objects = $this->routeProvider->getRoutesByNames($routes);
foreach ($routes as $entity_id => $route) {
// Not all stored routes will be valid on load.
if (isset($route_objects[$route])) {
- $menu_links[$entity_id]->setRouteObject($route_objects[$route]);
+ $queried_entities[$entity_id]->setRouteObject($route_objects[$route]);
}
}
}
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function mapFromStorageRecords(array $records, $load_revision = FALSE) {
+ $entities = parent::mapFromStorageRecords($records, $load_revision);
+
+ foreach ($entities as &$entity) {
+ foreach (static::$routerItemFields as $router_field) {
+ $entity->offsetSet($router_field, $records[$entity->id()]->{$router_field});
+ }
+ }
- parent::attachLoad($menu_links, $load_revision);
+ return $entities;
}
/**
* Overrides DatabaseStorageController::save().
*/
public function save(EntityInterface $entity) {
- $entity_class = $this->entityInfo['class'];
-
// We return SAVED_UPDATED by default because the logic below might not
// update the entity if its values haven't changed, so returning FALSE
// would be confusing in that situation.
@@ -152,13 +150,19 @@ public function save(EntityInterface $entity) {
$transaction = $this->database->startTransaction();
try {
+ // Ensure we are dealing with the actual entity.
+ $entity = $entity->getNGEntity();
+
+ // Sync the changes made in the fields array to the internal values array.
+ $entity->updateOriginalValues();
+
// Load the stored entity, if any.
if (!$entity->isNew() && !isset($entity->original)) {
$entity->original = entity_load_unchanged($this->entityType, $entity->id());
}
if ($entity->isNew()) {
- $entity->mlid = $this->database->insert($this->entityInfo['base_table'])->fields(array('menu_name' => 'tools'))->execute();
+ $entity->mlid->value = $this->database->insert($this->entityInfo['base_table'])->fields(array('menu_name' => 'tools'))->execute();
$entity->enforceIsNew();
}
@@ -174,19 +178,45 @@ public function save(EntityInterface $entity) {
// array_intersect_key() with the $entity as the first parameter because
// $entity may have additional keys left over from building a router entry.
// The intersect removes the extra keys, allowing a meaningful comparison.
- if ($entity->isNew() || (array_intersect_key(get_object_vars($entity), get_object_vars($entity->original)) != get_object_vars($entity->original))) {
- $return = drupal_write_record($this->entityInfo['base_table'], $entity, $this->idKey);
+ if ($entity->isNew() || (array_intersect_key($entity->getPropertyValues(), $entity->original->getPropertyValues()) != $entity->original->getPropertyValues())) {
+ // Create the storage record to be saved.
+ $record = $this->mapToStorageRecord($entity);
+ $return = drupal_write_record($this->entityInfo['base_table'], $record, $this->idKey);
if ($return) {
if (!$entity->isNew()) {
- $this->resetCache(array($entity->{$this->idKey}));
+ // @todo, should a different value be returned when saving an entity
+ // with $isDefaultRevision = FALSE?
+ if (!$entity->isDefaultRevision()) {
+ $return = FALSE;
+ }
+
+ if ($this->revisionKey) {
+ $record->{$this->revisionKey} = $this->saveRevision($entity);
+ }
+ if ($this->dataTable) {
+ $this->savePropertyData($entity);
+ }
+ $this->resetCache(array($entity->id()));
$entity->postSave($this, TRUE);
$this->invokeFieldMethod('update', $entity);
$this->invokeHook('update', $entity);
+ if ($this->dataTable) {
+ $this->invokeTranslationHooks($entity);
+ }
}
else {
$return = SAVED_NEW;
- $this->resetCache();
+ if ($this->revisionKey) {
+ $record->{$this->revisionKey} = $this->saveRevision($entity);
+ }
+ $entity->{$this->idKey}->value = $record->{$this->idKey};
+ if ($this->dataTable) {
+ $this->savePropertyData($entity);
+ }
+
+ // Reset general caches, but keep caches specific to certain entities.
+ $this->resetCache(array());
$entity->enforceIsNew(FALSE);
$entity->postSave($this, FALSE);
@@ -227,6 +257,10 @@ public function getPreventReparenting() {
* {@inheritdoc}
*/
public function loadUpdatedCustomized(array $router_paths) {
+ $menu_links = array();
+
+ // @todo This doesn't really make sense anymore with EntityNG.. and EFQ got
+ // OR condition support in the meantime, so convert this query.
$query = parent::buildQuery(NULL);
$query
->condition(db_or()
@@ -237,16 +271,12 @@ public function loadUpdatedCustomized(array $router_paths) {
->condition('customized', 1)
)
);
- $query_result = $query->execute();
- if (!empty($this->entityInfo['class'])) {
- // We provide the necessary arguments for PDO to create objects of the
- // specified entity class.
- // @see Drupal\Core\Entity\EntityInterface::__construct()
- $query_result->setFetchMode(\PDO::FETCH_CLASS, $this->entityInfo['class'], array(array(), $this->entityType));
+ if ($ids = $query->execute()->fetchCol(1)) {
+ $menu_links = $this->load($ids);
}
- return $query_result->fetchAllAssoc($this->idKey);
+ return $menu_links;
}
/**
@@ -270,13 +300,13 @@ public function loadModuleAdminTasks() {
*/
public function updateParentalStatus(EntityInterface $entity, $exclude = FALSE) {
// If plid == 0, there is nothing to update.
- if ($entity->plid) {
+ if ($entity->plid->target_id) {
// Check if at least one visible child exists in the table.
$query = \Drupal::entityQuery($this->entityType);
$query
- ->condition('menu_name', $entity->menu_name)
+ ->condition('menu_name', $entity->menu_name->value)
->condition('hidden', 0)
- ->condition('plid', $entity->plid)
+ ->condition('plid', $entity->plid->target_id)
->count();
if ($exclude) {
@@ -286,7 +316,7 @@ public function updateParentalStatus(EntityInterface $entity, $exclude = FALSE)
$parent_has_children = ((bool) $query->execute()) ? 1 : 0;
$this->database->update('menu_links')
->fields(array('has_children' => $parent_has_children))
- ->condition('mlid', $entity->plid)
+ ->condition('mlid', $entity->plid->target_id)
->execute();
}
}
@@ -299,20 +329,20 @@ public function findChildrenRelativeDepth(EntityInterface $entity) {
// make sense to convert to EFQ?
$query = $this->database->select('menu_links');
$query->addField('menu_links', 'depth');
- $query->condition('menu_name', $entity->menu_name);
+ $query->condition('menu_name', $entity->menu_name->value);
$query->orderBy('depth', 'DESC');
$query->range(0, 1);
$i = 1;
$p = 'p1';
- while ($i <= MENU_MAX_DEPTH && $entity->{$p}) {
- $query->condition($p, $entity->{$p});
+ while ($i <= MENU_MAX_DEPTH && $entity->{$p}->value) {
+ $query->condition($p, $entity->{$p}->value);
$p = 'p' . ++$i;
}
$max_depth = $query->execute()->fetchField();
- return ($max_depth > $entity->depth) ? $max_depth - $entity->depth : 0;
+ return ($max_depth > $entity->depth->value) ? $max_depth - $entity->depth->value : 0;
}
/**
@@ -321,14 +351,14 @@ public function findChildrenRelativeDepth(EntityInterface $entity) {
public function moveChildren(EntityInterface $entity) {
$query = $this->database->update($this->entityInfo['base_table']);
- $query->fields(array('menu_name' => $entity->menu_name));
+ $query->fields(array('menu_name' => $entity->menu_name->value));
$p = 'p1';
$expressions = array();
- for ($i = 1; $i <= $entity->depth; $p = 'p' . ++$i) {
- $expressions[] = array($p, ":p_$i", array(":p_$i" => $entity->{$p}));
+ for ($i = 1; $i <= $entity->depth->value; $p = 'p' . ++$i) {
+ $expressions[] = array($p, ":p_$i", array(":p_$i" => $entity->{$p}->value));
}
- $j = $entity->original->depth + 1;
+ $j = $entity->original->depth->value + 1;
while ($i <= MENU_MAX_DEPTH && $j <= MENU_MAX_DEPTH) {
$expressions[] = array('p' . $i++, 'p' . $j++, array());
}
@@ -336,7 +366,7 @@ public function moveChildren(EntityInterface $entity) {
$expressions[] = array('p' . $i++, 0, array());
}
- $shift = $entity->depth - $entity->original->depth;
+ $shift = $entity->depth->value - $entity->original->depth->value;
if ($shift > 0) {
// The order of expressions must be reversed so the new values don't
// overwrite the old ones before they can be used because "Single-table
@@ -349,10 +379,10 @@ public function moveChildren(EntityInterface $entity) {
}
$query->expression('depth', 'depth + :depth', array(':depth' => $shift));
- $query->condition('menu_name', $entity->original->menu_name);
+ $query->condition('menu_name', $entity->original->menu_name->value);
$p = 'p1';
- for ($i = 1; $i <= MENU_MAX_DEPTH && $entity->original->{$p}; $p = 'p' . ++$i) {
- $query->condition($p, $entity->original->{$p});
+ for ($i = 1; $i <= MENU_MAX_DEPTH && $entity->original->{$p}->value; $p = 'p' . ++$i) {
+ $query->condition($p, $entity->original->{$p}->value);
}
$query->execute();
@@ -376,7 +406,7 @@ public function countMenuLinks($menu_name) {
* {@inheritdoc}
*/
public function getParentFromHierarchy(EntityInterface $entity) {
- $parent_path = $entity->link_path;
+ $parent_path = $entity->link_path->value;
do {
$parent = FALSE;
$parent_path = substr($parent_path, 0, strrpos($parent_path, '/'));
@@ -387,7 +417,7 @@ public function getParentFromHierarchy(EntityInterface $entity) {
->condition('module', 'system')
// We always respect the link's 'menu_name'; inheritance for router
// items is ensured in _menu_router_build().
- ->condition('menu_name', $entity->menu_name)
+ ->condition('menu_name', $entity->menu_name->value)
->condition('link_path', $parent_path);
$result = $query->execute();
@@ -400,4 +430,203 @@ public function getParentFromHierarchy(EntityInterface $entity) {
return $parent;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function baseFieldDefinitions() {
+ $properties['menu_name'] = array(
+ 'label' => t('Menu name'),
+ 'description' => t('The menu name. All links with the same menu name (such as "tools") are part of the same menu.'),
+ 'type' => 'string_field',
+ 'settings' => array(
+ 'default_value' => 'tools',
+ ),
+ );
+ $properties['mlid'] = array(
+ 'label' => t('Menu link ID'),
+ 'description' => t('The menu link ID.'),
+ 'type' => 'integer_field',
+ 'read-only' => TRUE,
+ );
+ $properties['uuid'] = array(
+ 'label' => t('UUID'),
+ 'description' => t('The menu link UUID.'),
+ 'type' => 'uuid_field',
+ 'read-only' => TRUE,
+ );
+ $properties['plid'] = array(
+ 'label' => t('Parent ID'),
+ 'description' => t('The parent menu link ID.'),
+ 'type' => 'entity_reference_field',
+ 'settings' => array('target_type' => 'menu_link'),
+ );
+ $properties['link_path'] = array(
+ 'label' => t('Link path'),
+ 'description' => t('The Drupal path or external path this link points to.'),
+ 'type' => 'string_field',
+ );
+ $properties['router_path'] = array(
+ 'label' => t('Router path'),
+ 'description' => t('For links corresponding to a Drupal path (external = 0), this connects the link to a {menu_router}.path.'),
+ 'type' => 'string_field',
+ );
+ $properties['langcode'] = array(
+ 'label' => t('Language code'),
+ 'description' => t('The menu link language code.'),
+ 'type' => 'language_field',
+ );
+ $properties['link_title'] = array(
+ 'label' => t('Title'),
+ 'description' => t('The text displayed for the link, which may be modified by a title callback stored in {menu_router}.'),
+ 'type' => 'string_field',
+ 'settings' => array(
+ 'default_value' => '',
+ ),
+ );
+ $properties['options'] = array(
+ 'label' => t('Options'),
+ 'description' => t('A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.'),
+ 'type' => 'map_field',
+ );
+ $properties['module'] = array(
+ 'label' => t('Module'),
+ 'description' => t('The name of the module that generated this link.'),
+ 'type' => 'string_field',
+ 'settings' => array(
+ 'default_value' => 'menu',
+ ),
+ );
+ $properties['hidden'] = array(
+ 'label' => t('Hidden'),
+ 'description' => t('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' => 'boolean_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ $properties['external'] = array(
+ 'label' => t('External'),
+ 'description' => t('A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).'),
+ 'type' => 'boolean_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ $properties['has_children'] = array(
+ 'label' => t('Has children'),
+ 'description' => t('Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).'),
+ 'type' => 'boolean_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ $properties['expanded'] = array(
+ 'label' => t('Expanded'),
+ 'description' => t('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' => 'boolean_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ $properties['weight'] = array(
+ 'label' => t('Weight'),
+ 'description' => t('Link weight among links in the same menu at the same depth.'),
+ 'type' => 'integer_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ $properties['depth'] = array(
+ 'label' => t('Depth'),
+ 'description' => t('The depth relative to the top level. A link with plid == 0 will have depth == 1.'),
+ 'type' => 'integer_field',
+ );
+ $properties['customized'] = array(
+ 'label' => t('Customized'),
+ 'description' => t('A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).'),
+ 'type' => 'boolean_field',
+ 'settings' => array(
+ 'default_value' => 0,
+ ),
+ );
+ // @todo Declaring these pX properties as integer for the moment, we need to
+ // investigate if using 'entity_reference_field' cripples performance.
+ $properties['p1'] = array(
+ 'label' => t('Parent 1'),
+ 'description' => t('The first mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p2'] = array(
+ 'label' => t('Parent 2'),
+ 'description' => t('The second mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p3'] = array(
+ 'label' => t('Parent 3'),
+ 'description' => t('The third mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p4'] = array(
+ 'label' => t('Parent 4'),
+ 'description' => t('The fourth mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p5'] = array(
+ 'label' => t('Parent 5'),
+ 'description' => t('The fifth mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p6'] = array(
+ 'label' => t('Parent 6'),
+ 'description' => t('The sixth mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p7'] = array(
+ 'label' => t('Parent 7'),
+ 'description' => t('The seventh mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p8'] = array(
+ 'label' => t('Parent 8'),
+ 'description' => t('The eighth mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['p9'] = array(
+ 'label' => t('Parent 9'),
+ 'description' => t('The ninth mlid in the materialized path.'),
+ 'type' => 'integer_field',
+ );
+ $properties['updated'] = array(
+ 'label' => t('Updated'),
+ 'description' => t('Flag that indicates that this link was generated during the update from Drupal 5.'),
+ 'type' => 'boolean_field',
+ );
+ $properties['route_name'] = array(
+ 'label' => t('Route name'),
+ 'description' => t('The machine name of a defined Symfony Route this menu item represents.'),
+ 'type' => 'string_field',
+ );
+
+ // @todo Most of these should probably go away.
+ $properties['access'] = array(
+ 'label' => t('(old router) Access'),
+ 'description' => t(''),
+ 'type' => 'boolean_field',
+ 'computed' => TRUE,
+ );
+ $properties['in_active_trail'] = array(
+ 'label' => t('In active trail'),
+ 'description' => t(''),
+ 'type' => 'boolean_field',
+ 'computed' => TRUE,
+ );
+ $properties['localized_options'] = array(
+ 'label' => t('Localized options'),
+ 'description' => t(''),
+ 'type' => 'map_field',
+ 'computed' => TRUE,
+ );
+ return $properties;
+ }
+
}
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php b/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
index 29da4a8..97aafee 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
@@ -38,13 +38,13 @@ public function form(array $form, array &$form_state) {
foreach ($this->entity->links as $link) {
$mlid = $link->id();
$form['shortcuts']['links'][$mlid]['#attributes']['class'][] = 'draggable';
- $form['shortcuts']['links'][$mlid]['name']['#markup'] = l($link->link_title, $link->link_path);
- $form['shortcuts']['links'][$mlid]['#weight'] = $link->weight;
+ $form['shortcuts']['links'][$mlid]['name']['#markup'] = l($link->link_title->value, $link->link_path->value);
+ $form['shortcuts']['links'][$mlid]['#weight'] = $link->weight->value;
$form['shortcuts']['links'][$mlid]['weight'] = array(
'#type' => 'weight',
- '#title' => t('Weight for @title', array('@title' => $link->link_title)),
+ '#title' => t('Weight for @title', array('@title' => $link->link_title->value)),
'#title_display' => 'invisible',
- '#default_value' => $link->weight,
+ '#default_value' => $link->weight->value,
'#attributes' => array('class' => array('shortcut-weight')),
);
@@ -88,7 +88,7 @@ protected function actions(array $form, array &$form_state) {
*/
public function save(array $form, array &$form_state) {
foreach ($this->entity->links as $link) {
- $link->weight = $form_state['values']['shortcuts']['links'][$link->mlid]['weight'];
+ $link->weight = $form_state['values']['shortcuts']['links'][$link->id()]['weight'];
$link->save();
}
drupal_set_message(t('The shortcut set has been updated.'));
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
index 06088ef..2fcfa5b 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
@@ -129,7 +129,7 @@ function generateShortcutLink($path, $title = '') {
function getShortcutInformation($set, $key) {
$info = array();
foreach ($set->links as $uuid => $link) {
- $info[] = $link->{$key};
+ $info[] = $link->{$key}->value;
}
return $info;
}
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index a54f323..8703b98 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -56,7 +56,7 @@ function shortcut_entity_bundle_info() {
function shortcut_menu_link_load($entities) {
foreach ($entities as $entity) {
// Change the bundle of menu links related to a shortcut.
- if (strpos($entity->menu_name, 'shortcut-') === 0) {
+ if (strpos($entity->menu_name->value, 'shortcut-') === 0) {
$entity->bundle = 'shortcut';
}
}
@@ -234,9 +234,9 @@ function shortcut_link_access($menu_link) {
*/
function shortcut_menu_link_delete($menu_link) {
// If the deleted menu link was in a shortcut set, remove it.
- if (strpos($menu_link->menu_name, 'shortcut-') === 0) {
- $shortcut = entity_load('shortcut_set', str_replace('shortcut-', '', $menu_link->menu_name));
- unset($shortcut->links[$menu_link->uuid]);
+ if (strpos($menu_link->menu_name->value, 'shortcut-') === 0) {
+ $shortcut = entity_load('shortcut_set', str_replace('shortcut-', '', $menu_link->menu_name->value));
+ unset($shortcut->links[$menu_link->uuid()]);
$shortcut->save();
}
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
index 0a94658..edddcbb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
@@ -374,7 +374,7 @@ function testMenuHidden() {
$links = array();
foreach ($menu_links as $menu_link) {
- $links[$menu_link->router_path] = $menu_link;
+ $links[$menu_link->router_path->value] = $menu_link;
}
$parent = $links['menu-test/hidden/menu'];
@@ -426,7 +426,7 @@ function testMenuHidden() {
$links = array();
foreach ($menu_links as $menu_link) {
- $links[$menu_link->router_path] = $menu_link;
+ $links[$menu_link->router_path->value] = $menu_link;
}
$parent = $links['menu-test/hidden/block'];
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeAccessTest.php
index 263e2fc..6714e13 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeAccessTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeAccessTest.php
@@ -20,6 +20,13 @@
class TreeAccessTest extends DrupalUnitTestBase {
/**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = array('menu_link');
+
+ /**
* A list of menu links used for this test.
*
* @var array
@@ -93,8 +100,8 @@ public function testRouteItemMenuLinksAccess() {
// Setup the links with the route items.
$this->links = array(
- new MenuLink(array('mlid' => 1, 'route_name' => 'menu_test_1', 'depth' => 1, 'link_path' => 'menu_test/test_1'), 'menu_link'),
- new MenuLink(array('mlid' => 2, 'route_name' => 'menu_test_2', 'depth' => 1, 'link_path' => 'menu_test/test_2'), 'menu_link'),
+ entity_create('menu_link', array('mlid' => 1, 'route_name' => 'menu_test_1', 'depth' => 1, 'link_path' => 'menu_test/test_1')),
+ entity_create('menu_link', array('mlid' => 2, 'route_name' => 'menu_test_2', 'depth' => 1, 'link_path' => 'menu_test/test_2')),
);
// Build the menu tree and check access for all of the items.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeDataUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeDataUnitTest.php
index 8b6c4a1..e771e4f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeDataUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeDataUnitTest.php
@@ -8,12 +8,20 @@
namespace Drupal\system\Tests\Menu;
use Drupal\menu_link\Entity\MenuLink;
-use Drupal\simpletest\UnitTestBase;
+use Drupal\simpletest\DrupalUnitTestBase;
/**
* Menu tree data related tests.
*/
-class TreeDataUnitTest extends UnitTestBase {
+class TreeDataUnitTest extends DrupalUnitTestBase {
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = array('menu_link');
+
/**
* Dummy link structure acceptable for menu_tree_data().
*/
@@ -32,11 +40,11 @@ public static function getInfo() {
*/
public function testMenuTreeData() {
$this->links = array(
- 1 => new MenuLink(array('mlid' => 1, 'depth' => 1), 'menu_link'),
- 2 => new MenuLink(array('mlid' => 2, 'depth' => 1), 'menu_link'),
- 3 => new MenuLink(array('mlid' => 3, 'depth' => 2), 'menu_link'),
- 4 => new MenuLink(array('mlid' => 4, 'depth' => 3), 'menu_link'),
- 5 => new MenuLink(array('mlid' => 5, 'depth' => 1), 'menu_link'),
+ 1 => entity_create('menu_link', array('mlid' => 1, 'depth' => 1)),
+ 2 => entity_create('menu_link', array('mlid' => 2, 'depth' => 1)),
+ 3 => entity_create('menu_link', array('mlid' => 3, 'depth' => 2)),
+ 4 => entity_create('menu_link', array('mlid' => 4, 'depth' => 3)),
+ 5 => entity_create('menu_link', array('mlid' => 5, 'depth' => 1)),
);
$tree = menu_tree_data($this->links);
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 050cdd7..a4023ac 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -24,7 +24,7 @@ function system_admin_config_page() {
$system_link = reset($system_link);
$query = Drupal::entityQuery('menu_link')
->condition('link_path', 'admin/help', '<>')
- ->condition('menu_name', $system_link->menu_name)
+ ->condition('menu_name', $system_link->menu_name->value)
->condition('plid', $system_link->id())
->condition('hidden', 0);
$result = $query->execute();
@@ -433,7 +433,7 @@ function theme_admin_block_content($variables) {
}
$output .= '';
foreach ($content as $item) {
- $output .= '- ' . l($item['title'], $item['href'], $item['localized_options']) . '
';
+ $output .= '- ' . l($item['link_title'], $item['link_path'], is_object($item['localized_options']) ? $item['localized_options']->getValue() : $item['localized_options']) . '
';
if (!$compact && isset($item['description'])) {
$output .= '- ' . filter_xss_admin($item['description']) . '
';
}
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index bd58f93..2de78d4 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2345,7 +2345,7 @@ function system_admin_menu_block($item) {
$menu_links = entity_load_multiple_by_properties('menu_link', array('router_path' => $item['path'], 'module' => 'system'));
$menu_link = reset($menu_links);
$item['mlid'] = $menu_link->id();
- $item['menu_name'] = $menu_link->menu_name;
+ $item['menu_name'] = $menu_link->menu_name->value;
}
if (isset($cache[$item['mlid']])) {
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 62ccfd6..317f62b 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -962,13 +962,13 @@ function user_menu_link_presave(MenuLink $menu_link) {
// for authenticated users. Authenticated users should see "My account", but
// anonymous users should not see it at all. Therefore, invoke
// user_menu_link_load() to conditionally hide the link.
- if ($menu_link->link_path == 'user' && $menu_link->module == 'system') {
- $menu_link->options['alter'] = TRUE;
+ if ($menu_link->getLinkPath() == 'user' && $menu_link->getModule() == 'system') {
+ //$menu_link->options['alter'] = TRUE;
}
// Force the Logout link to appear on the top-level of 'account' menu by
// default (i.e., unless it has been customized).
- if ($menu_link->link_path == 'user/logout' && $menu_link->module == 'system' && empty($menu_link->customized)) {
+ if ($menu_link->getLinkPath() == 'user/logout' && $menu_link->getModule() == 'system' && !$menu_link->isCustomized()) {
$menu_link->plid = 0;
}
}
@@ -990,8 +990,8 @@ function user_menu_breadcrumb_alter(&$active_trail, $item) {
function user_menu_link_load($menu_links) {
// Hide the "User account" link for anonymous users.
foreach ($menu_links as $link) {
- if ($link['link_path'] == 'user' && $link['module'] == 'system' && !$GLOBALS['user']->id()) {
- $link['hidden'] = 1;
+ if ($link->getLinkPath() == 'user' && $link->getModule() == 'system' && $GLOBALS['user']->isAnonymous()) {
+ $link->hidden = 1;
}
}
}
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index 5735f29..a39fe04 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -97,7 +97,7 @@ function seven_admin_block_content($variables) {
foreach ($content as $item) {
$output .= '
';
$content = '' . filter_xss_admin($item['title']) . '';
- $options = $item['localized_options'];
+ $options = $item['localized_options']->getValue();
$options['html'] = TRUE;
if (isset($item['description']) && !system_admin_compact_mode()) {
$content .= '' . filter_xss_admin($item['description']) . '
';