diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index a988135..cd870f2 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -207,8 +207,22 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { /** * {@inheritdoc} */ - public function uri() { - return parent::uri('edit-form'); + public function urlInfo($rel = 'edit-form') { + return parent::urlInfo($rel); + } + + /** + * {@inheritdoc} + */ + public function getSystemPath($rel = 'edit-form') { + return parent::getSystemPath($rel); + } + + /** + * {@inheritdoc} + */ + public function url($rel = 'edit-form', $options = array()) { + return parent::url($rel, $options); } } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php index 979dddd..4411ba1 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListController.php @@ -32,31 +32,19 @@ public function load() { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); - - // Ensure the edit operation exists since it is access controlled. - if (isset($operations['edit'])) { - // For configuration entities edit path is the MENU_DEFAULT_LOCAL_TASK and - // therefore should be accessed by the short route. - $operations['edit']['href'] = $uri['path']; - } if ($this->entityInfo->hasKey('status')) { - if (!$entity->status()) { + if (!$entity->status() && $entity->hasLinkTemplate('enable')) { $operations['enable'] = array( 'title' => t('Enable'), - 'href' => $uri['path'] . '/enable', - 'options' => $uri['options'], 'weight' => -10, - ); + ) + $entity->urlInfo('enable'); } - else { + elseif ($entity->hasLinkTemplate('disable')) { $operations['disable'] = array( 'title' => t('Disable'), - 'href' => $uri['path'] . '/disable', - 'options' => $uri['options'], 'weight' => 40, - ); + ) + $entity->urlInfo('disable'); } } diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index 5a5532f..09a6b10 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -9,7 +9,6 @@ use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; -use Symfony\Component\Routing\Exception\RouteNotFoundException; /** * Defines a base entity class. @@ -38,18 +37,11 @@ protected $enforceIsNew; /** - * The route provider service. + * The URL generator. * - * @var \Drupal\Core\Routing\RouteProviderInterface + * @var \Drupal\Core\Routing\UrlGeneratorInterface */ - protected $routeProvider; - - /** - * Local cache for URI placeholder substitution values. - * - * @var array - */ - protected $uriPlaceholderReplacements; + protected $urlGenerator; /** * Constructs an Entity object. @@ -127,100 +119,71 @@ public function label() { } /** - * Returns the URI elements of the entity. - * - * URI templates might be set in the links array in an annotation, for - * example: - * @code - * links = { - * "canonical" = "/node/{node}", - * "edit-form" = "/node/{node}/edit", - * "version-history" = "/node/{node}/revisions" - * } - * @endcode - * or specified in a callback function set like: - * @code - * uri_callback = "contact_category_uri", - * @endcode - * If the path is not set in the links array, the uri_callback function is - * used for setting the path. If this does not exist and the link relationship - * type is canonical, the path is set using the default template: - * entity/entityType/id. - * - * @param string $rel - * The link relationship type, for example: canonical or edit-form. - * - * @return array - * An array containing the 'path' and 'options' keys used to build the URI - * of the entity, and matching the signature of url(). + * {@inheritdoc} */ - public function uri($rel = 'canonical') { - $entity_info = $this->entityInfo(); + public function urlInfo($rel = 'canonical') { + if ($this->isNew()) { + throw new EntityMalformedException(sprintf('The "%s" entity type has not been saved, and cannot have a URI.', $this->entityType())); + } // The links array might contain URI templates set in annotations. $link_templates = $this->linkTemplates(); - $template = NULL; if (isset($link_templates[$rel])) { - try { - $template = $this->routeProvider()->getRouteByName($link_templates[$rel])->getPath(); + // If there is a template for the given relationship type, generate the path. + $uri['route_name'] = $link_templates[$rel]; + $uri['route_parameters'] = $this->urlRouteParameters($rel); + } + else { + $bundle = $this->bundle(); + // A bundle-specific callback takes precedence over the generic one for + // the entity type. + $bundles = \Drupal::entityManager()->getBundleInfo($this->entityType); + if (isset($bundles[$bundle]['uri_callback'])) { + $uri_callback = $bundles[$bundle]['uri_callback']; } - catch (RouteNotFoundException $e) { - // Fall back to a non-template-based URI. + elseif ($entity_uri_callback = $this->entityInfo()->getUriCallback()) { + $uri_callback = $entity_uri_callback; } - } - if ($template) { - // If there is a template for the given relationship type, do the - // placeholder replacement and use that as the path. - $replacements = $this->uriPlaceholderReplacements(); - $uri['path'] = str_replace(array_keys($replacements), array_values($replacements), $template); - - // @todo Remove this once http://drupal.org/node/1888424 is in and we can - // move the BC handling of / vs. no-/ to the generator. - $uri['path'] = trim($uri['path'], '/'); - - // Pass the entity data to url() so that alter functions do not need to - // look up this entity again. - $uri['options']['entity_type'] = $this->entityType; - $uri['options']['entity'] = $this; - return $uri; - } - - $bundle = $this->bundle(); - // A bundle-specific callback takes precedence over the generic one for - // the entity type. - $bundles = entity_get_bundles($this->entityType); - if (isset($bundles[$bundle]['uri_callback'])) { - $uri_callback = $bundles[$bundle]['uri_callback']; - } - elseif ($entity_uri_callback = $entity_info->getUriCallback()) { - $uri_callback = $entity_uri_callback; - } - // Invoke the callback to get the URI. If there is no callback, use the - // default URI format. - // @todo Convert to is_callable() and call_user_func(). - if (isset($uri_callback) && function_exists($uri_callback)) { - $uri = $uri_callback($this); - } - // Only use these defaults for a canonical link (that is, a link to self). - // Other relationship types are not supported by this logic. - elseif ($rel == 'canonical') { - $uri = array( - 'path' => 'entity/' . $this->entityType . '/' . $this->id(), - ); - } - else { - return array(); + // Invoke the callback to get the URI. If there is no callback, use the + // default URI format. + // @todo Convert to is_callable() and call_user_func(). + if (isset($uri_callback) && function_exists($uri_callback)) { + $uri = $uri_callback($this); + } + else { + return array(); + } } // Pass the entity data to url() so that alter functions do not need to // look up this entity again. + $uri['options']['entity_type'] = $this->entityType; $uri['options']['entity'] = $this; + return $uri; } /** + * {@inheritdoc} + */ + public function getSystemPath($rel = 'canonical') { + if ($uri = $this->urlInfo($rel)) { + return $this->urlGenerator()->getPathFromRoute($uri['route_name'], $uri['route_parameters']); + } + return ''; + } + + /** + * {@inheritdoc} + */ + public function hasLinkTemplate($rel) { + $link_templates = $this->linkTemplates(); + return isset($link_templates[$rel]); + } + + /** * Returns an array link templates. * * @return array @@ -231,26 +194,38 @@ protected function linkTemplates() { } /** + * {@inheritdoc} + */ + public function url($rel = 'canonical', $options = array()) { + // While self::urlInfo() will throw an exception if the entity is new, + // the expected result for a URL is always a string. + if ($this->isNew() || !$uri = $this->urlInfo($rel)) { + return ''; + } + + $options += $uri['options']; + return $this->urlGenerator()->generateFromRoute($uri['route_name'], $uri['route_parameters'], $options); + } + + /** * Returns an array of placeholders for this entity. * * Individual entity classes may override this method to add additional * placeholders if desired. If so, they should be sure to replicate the * property caching logic. * + * @param string $rel + * The link relationship type, for example: canonical or edit-form. + * * @return array * An array of URI placeholders. */ - protected function uriPlaceholderReplacements() { - if (empty($this->uriPlaceholderReplacements)) { - $this->uriPlaceholderReplacements = array( - '{entityType}' => $this->entityType(), - '{bundle}' => $this->bundle(), - '{id}' => $this->id(), - '{uuid}' => $this->uuid(), - '{' . $this->entityType() . '}' => $this->id(), - ); + protected function urlRouteParameters($rel) { + $uri_route_parameters[$this->entityType()] = $this->id(); + if ($rel == 'admin-form' && $this->entityInfo()->getBundleEntityType() != 'bundle') { + $uri_route_parameters[$this->entityInfo()->getBundleEntityType()] = $this->bundle(); } - return $this->uriPlaceholderReplacements; + return $uri_route_parameters; } /** @@ -403,16 +378,16 @@ protected function onSaveOrDelete() { } /** - * Wraps the route provider service. + * Wraps the URL generator. * - * @return \Drupal\Core\Routing\RouteProviderInterface - * The route provider. + * @return \Drupal\Core\Routing\UrlGeneratorInterface + * The URL generator. */ - protected function routeProvider() { - if (!$this->routeProvider) { - $this->routeProvider = \Drupal::service('router.route_provider'); + protected function urlGenerator() { + if (!$this->urlGenerator) { + $this->urlGenerator = \Drupal::urlGenerator(); } - return $this->routeProvider; + return $this->urlGenerator; } } diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 2ea0fbe..8a027ed 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -309,7 +309,15 @@ public function save(array $form, array &$form_state) { * A reference to a keyed array containing the current state of the form. */ public function delete(array $form, array &$form_state) { - // @todo Perform common delete operations. + if ($this->entity->hasLinkTemplate('delete-form')) { + $form_state['redirect_route'] = $this->entity->urlInfo('delete-form'); + + $query = $this->getRequest()->query; + if ($query->has('destination')) { + $form_state['redirect_route']['options']['query']['destination'] = $query->get('destination'); + $query->remove('destination'); + } + } } /** diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php index 50e99b6..8be2f36 100644 --- a/core/lib/Drupal/Core/Entity/EntityInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityInterface.php @@ -97,11 +97,71 @@ public function label(); /** * Returns the URI elements of the entity. * + * URI templates might be set in the links array in an annotation, for + * example: + * @code + * links = { + * "canonical" = "/node/{node}", + * "edit-form" = "/node/{node}/edit", + * "version-history" = "/node/{node}/revisions" + * } + * @endcode + * or specified in a callback function set like: + * @code + * uri_callback = "contact_category_uri", + * @endcode + * If the path is not set in the links array, the uri_callback function is + * used for setting the path. If this does not exist and the link relationship + * type is canonical, the path is set using the default template: + * entity/entityType/id. + * + * @param string $rel + * The link relationship type, for example: canonical or edit-form. + * * @return * An array containing the 'path' and 'options' keys used to build the URI * of the entity, and matching the signature of url(). */ - public function uri(); + public function urlInfo($rel = 'canonical'); + + /** + * Returns the public URL for this entity. + * + * @param string $rel + * The link relationship type, for example: canonical or edit-form. + * @param array $options + * See \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute() for + * the available options. + * + * @return string + * The URL for this entity. + */ + public function url($rel = 'canonical', $options = array()); + + /** + * Returns the internal path for this entity. + * + * The self::url() method will return the full path including any prefixes, + * fragments, or query strings. This path does not include those. + * + * @param string $rel + * The link relationship type, for example: canonical or edit-form. + * + * @return string + * The internal path for this entity. + */ + public function getSystemPath($rel = 'canonical'); + + /** + * Indicates if a link template exists for a given key. + * + * @param string $key + * The link type. + * + * @return bool + * TRUE if the link template exists, FALSE otherwise. + */ + public function hasLinkTemplate($key); /** * Returns a list of URI relationships supported by this entity. diff --git a/core/lib/Drupal/Core/Entity/EntityListController.php b/core/lib/Drupal/Core/Entity/EntityListController.php index ef3ec43..16b3bf8 100644 --- a/core/lib/Drupal/Core/Entity/EntityListController.php +++ b/core/lib/Drupal/Core/Entity/EntityListController.php @@ -93,24 +93,18 @@ protected function getLabel(EntityInterface $entity) { * {@inheritdoc} */ public function getOperations(EntityInterface $entity) { - $uri = $entity->uri(); - $operations = array(); - if ($entity->access('update')) { + if ($entity->access('update') && $entity->hasLinkTemplate('edit-form')) { $operations['edit'] = array( 'title' => $this->t('Edit'), - 'href' => $uri['path'] . '/edit', - 'options' => $uri['options'], 'weight' => 10, - ); + ) + $entity->urlInfo('edit-form'); } - if ($entity->access('delete')) { + if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) { $operations['delete'] = array( 'title' => $this->t('Delete'), - 'href' => $uri['path'] . '/delete', - 'options' => $uri['options'], 'weight' => 100, - ); + ) + $entity->urlInfo('delete-form'); } return $operations; diff --git a/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php index b7581d8..775445e 100644 --- a/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityListControllerInterface.php @@ -26,7 +26,7 @@ public function getStorageController(); * This allows the controller to manipulate the list, like filtering or * sorting the loaded entities. * - * @return array + * @return \Drupal\Core\Entity\EntityInterface[] * An array of entities implementing Drupal\Core\Entity\EntityInterface. */ public function load(); diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php index 5d390be..4305c6b 100644 --- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php @@ -391,17 +391,14 @@ public function isFieldable(); * HTML page must also define an "edit-form" relationship. * * By default, the following placeholders are supported: - * - entityType: The machine name of the entity type. - * - bundle: The bundle machine name of the entity. - * - id: The unique ID of the entity. - * - uuid: The UUID of the entity. * - [entityType]: The entity type itself will also be a valid token for the * ID of the entity. For instance, a placeholder of {node} used on the Node - * class would have the same value as {id}. This is generally preferred - * over "id" for better self-documentation. + * class. + * - [bundleEntityType]: The bundle machine name itself. For instance, a + * placeholder of {node_type} used on the Node class. * * Specific entity types may also expand upon this list by overriding the - * Entity::uriPlaceholderReplacements() method. + * Entity::urlRouteParameters() method. * * @link http://www.iana.org/assignments/link-relations/link-relations.xml @endlink * @link http://tools.ietf.org/html/rfc6570 @endlink diff --git a/core/modules/action/action.module b/core/modules/action/action.module index 2923753..01d73cb 100644 --- a/core/modules/action/action.module +++ b/core/modules/action/action.module @@ -66,5 +66,6 @@ function action_entity_info(&$entity_info) { ->setFormClass('edit', 'Drupal\action\ActionEditFormController') ->setFormClass('delete', 'Drupal\action\Form\ActionDeleteForm') ->setListClass('Drupal\action\ActionListController') + ->setLinkTemplate('delete-form', 'action.delete') ->setLinkTemplate('edit-form', 'action.admin_configure'); } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php index ba7c846..61eae79 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php @@ -28,6 +28,12 @@ * "remove_items" = "Drupal\aggregator\Form\FeedItemsRemoveForm", * } * }, + * links = { + * "canonical" = "aggregator.feed_view", + * "edit-form" = "aggregator.feed_configure", + * "delete-form" = "aggregator.feed_delete", + * "edit-form" = "aggregator.feed_configure", + * }, * base_table = "aggregator_feed", * fieldable = TRUE, * entity_keys = { diff --git a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php index 6b27ec8..469b194 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php @@ -92,10 +92,7 @@ public function save(array $form, array &$form_state) { $form_state['redirect_route']['route_name'] = 'aggregator.admin_overview'; } else { - $form_state['redirect_route'] = array( - 'route_name' => 'aggregator.feed_view', - 'route_parameters' => array('aggregator_feed' => $feed->id()), - ); + $form_state['redirect_route'] = $feed->urlInfo('canonical'); } } else { @@ -104,14 +101,4 @@ public function save(array $form, array &$form_state) { } } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'aggregator.feed_delete', - 'route_parameters' => array('aggregator_feed' => $this->entity->id()), - ); - } - } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php index b3d2e61..e67b354 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php @@ -251,27 +251,6 @@ public function save(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function delete(array $form, array &$form_state) { - $destination = array(); - $query = $this->getRequest()->query; - if (!is_null($query->get('destination'))) { - $destination = drupal_get_destination(); - $query->remove('destination'); - } - $form_state['redirect_route'] = array( - 'route_name' => 'custom_block.delete', - 'route_parameters' => array( - 'custom_block' => $this->entity->id(), - ), - 'options' => array( - 'query' => $destination, - ), - ); - } - - /** - * {@inheritdoc} - */ public function validateForm(array &$form, array &$form_state) { if ($this->entity->isNew()) { $exists = $this->customBlockStorage->loadByProperties(array('info' => $form_state['values']['info'])); diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php index efa31b3..1f49a87 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php @@ -36,10 +36,7 @@ public function buildRow(EntityInterface $entity) { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - // The custom block edit path does not contain '/edit'. if (isset($operations['edit'])) { - $uri = $entity->uri(); - $operations['edit']['href'] = $uri['path']; $operations['edit']['query']['destination'] = 'admin/structure/block/custom-blocks'; } return $operations; diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php index 15cd8f8..61408ed 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php @@ -91,29 +91,18 @@ public function save(array $form, array &$form_state) { $block_type = $this->entity; $status = $block_type->save(); - $uri = $block_type->uri(); + $uri = $block_type->urlInfo(); + $edit_link = \Drupal::l($this->t('Edit'), $uri['route_name'], $uri['route_parameters'], $uri['options']); if ($status == SAVED_UPDATED) { drupal_set_message(t('Custom block type %label has been updated.', array('%label' => $block_type->label()))); - watchdog('custom_block', 'Custom block type %label has been updated.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('custom_block', 'Custom block type %label has been updated.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); } else { drupal_set_message(t('Custom block type %label has been added.', array('%label' => $block_type->label()))); - watchdog('custom_block', 'Custom block type %label has been added.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('custom_block', 'Custom block type %label has been added.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); } $form_state['redirect_route']['route_name'] = 'custom_block.type_list'; } - /** - * Overrides \Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'custom_block.type_delete', - 'route_parameters' => array( - 'custom_block_type' => $this->entity->id(), - ), - ); - } - } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php index 070171d..84a8ad9 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php @@ -41,8 +41,8 @@ public function buildHeader() { * Overrides \Drupal\Core\Entity\EntityListController::buildRow(). */ public function buildRow(EntityInterface $entity) { - $uri = $entity->uri(); - $row['type'] = l($entity->label(), $uri['path'], $uri['options']); + $uri = $entity->urlInfo(); + $row['type'] = \Drupal::l($entity->label(), $uri['route_name'], $uri['route_parameters'], $uri['options']); $row['description'] = filter_xss_admin($entity->description); return $row + parent::buildRow($entity); } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php index 643fa33..68c3b10 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php @@ -37,6 +37,7 @@ * revision_table = "custom_block_revision", * links = { * "canonical" = "custom_block.edit", + * "delete-form" = "custom_block.delete", * "edit-form" = "custom_block.edit", * "admin-form" = "custom_block.type_edit" * }, diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php index f61fa7b..0b41a4d 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php @@ -36,6 +36,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "custom_block.type_delete", * "edit-form" = "custom_block.type_edit" * } * ) diff --git a/core/modules/block/lib/Drupal/block/BlockFormController.php b/core/modules/block/lib/Drupal/block/BlockFormController.php index fba5659..8933395 100644 --- a/core/modules/block/lib/Drupal/block/BlockFormController.php +++ b/core/modules/block/lib/Drupal/block/BlockFormController.php @@ -341,24 +341,6 @@ public function submit(array $form, array &$form_state) { } /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - parent::delete($form, $form_state); - $form_state['redirect_route'] = array( - 'route_name' => 'block.admin_block_delete', - 'route_parameters' => array( - 'block' => $this->entity->id(), - ), - ); - $query = $this->getRequest()->query; - if ($query->has('destination')) { - $form_state['redirect_route']['options']['query']['destination'] = $query->get('destination'); - $query->remove('destination'); - } - } - - /** * Generates a unique machine name for a block. * * @param \Drupal\block\BlockInterface $block diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php index fe82d44..dc20929 100644 --- a/core/modules/block/lib/Drupal/block/Entity/Block.php +++ b/core/modules/block/lib/Drupal/block/Entity/Block.php @@ -37,6 +37,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "block.admin_block_delete", * "edit-form" = "block.admin_edit" * } * ) diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 0457488..c4c2fa0 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -116,7 +116,10 @@ function book_permission() { */ function book_entity_info(&$entity_info) { /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */ - $entity_info['node']->setFormClass('book_outline', 'Drupal\book\Form\BookOutlineForm'); + $entity_info['node'] + ->setFormClass('book_outline', 'Drupal\book\Form\BookOutlineForm') + ->setLinkTemplate('book-outline-form', 'book.outline') + ->setLinkTemplate('book-remove-form', 'book.remove'); } /** diff --git a/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php b/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php index 5364d93..aae3eac 100644 --- a/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php +++ b/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php @@ -119,12 +119,7 @@ public function submit(array $form, array &$form_state) { if ($this->entity->book['parent_mismatch']) { // This will usually only happen when JS is disabled. drupal_set_message($this->t('The post has been added to the selected book. You may now position it relative to other pages.')); - $form_state['redirect_route'] = array( - 'route_name' => 'book.outline', - 'route_parameters' => array( - 'node' => $this->entity->id(), - ), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('book-outline-form'); } else { drupal_set_message($this->t('The book outline has been updated.')); @@ -139,12 +134,7 @@ public function submit(array $form, array &$form_state) { * {@inheritdoc} */ public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'book.remove', - 'route_parameters' => array( - 'node' => $this->entity->id(), - ), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('book-remove-form'); } } diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 503e32a..8218762 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -126,7 +126,10 @@ function comment_entity_bundle_info() { */ function comment_uri(CommentInterface $comment) { return array( - 'path' => 'comment/' . $comment->id(), + 'route_name' => 'comment.permalink', + 'route_parameters' => array( + 'comment' => $comment->id(), + ), 'options' => array('fragment' => 'comment-' . $comment->id()), ); } @@ -428,16 +431,15 @@ function comment_entity_view(EntityInterface $entity, EntityViewDisplayInterface if ($commenting_status) { $instance = \Drupal::service('field.info')->getInstance('node', $entity->bundle(), $field_name); // Entity have commenting open or close. - $uri = $entity->uri(); if ($view_mode == 'rss') { // Add a comments RSS element which is a URL to the comments of this node. - if (!empty($uri['options'])) { - $uri['options']['fragment'] = 'comments'; - $uri['options']['absolute'] = TRUE; - } + $options = array( + 'fragment' => 'comments', + 'absolute' => TRUE, + ); $entity->rss_elements[] = array( 'key' => 'comments', - 'value' => url($uri['path'], $uri['options']) + 'value' => $entity->url('canonical', $options), ); } elseif ($view_mode == 'teaser') { @@ -448,11 +450,10 @@ function comment_entity_view(EntityInterface $entity, EntityViewDisplayInterface if (!empty($entity->get($field_name)->comment_count)) { $links['comment-comments'] = array( 'title' => format_plural($entity->get($field_name)->comment_count, '1 comment', '@count comments'), - 'href' => $uri['path'], 'attributes' => array('title' => t('Jump to the first comment of this posting.')), 'fragment' => 'comments', 'html' => TRUE, - ); + ) + $entity->urlInfo(); if (\Drupal::moduleHandler()->moduleExists('history')) { $links['comment-new-comments'] = array( 'title' => '', @@ -474,12 +475,19 @@ function comment_entity_view(EntityInterface $entity, EntityViewDisplayInterface if (user_access('post comments')) { $links['comment-add'] = array( 'title' => t('Add new comment'), - 'href' => $uri['path'], 'attributes' => array('title' => t('Add a new comment to this page.')), 'fragment' => 'comment-form', ); if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE) { - $links['comment-add']['href'] = 'comment/reply/'. $entity->entityType() . '/' . $entity->id() .'/' . $field_name; + $links['comment-add']['route_name'] = 'comment.reply'; + $links['comment-add']['route_parameters'] = array( + 'entity_type' => $entity->entityType(), + 'entity_id' => $entity->id(), + 'field_name' => $field_name, + ); + } + else { + $links['comment-add'] += $entity->urlInfo(); } } else { @@ -504,11 +512,18 @@ function comment_entity_view(EntityInterface $entity, EntityViewDisplayInterface $links['comment-add'] = array( 'title' => t('Add new comment'), 'attributes' => array('title' => t('Share your thoughts and opinions related to this posting.')), - 'href' => $uri['path'], 'fragment' => 'comment-form', ); if ($comment_form_location == COMMENT_FORM_SEPARATE_PAGE) { - $links['comment-add']['href'] = 'comment/reply/'. $entity->entityType() . '/' . $entity->id() .'/' . $field_name; + $links['comment-add']['route_name'] = 'comment.reply'; + $links['comment-add']['route_parameters'] = array( + 'entity_type' => $entity->entityType(), + 'entity_id' => $entity->id(), + 'field_name' => $field_name, + ); + } + else { + $links['comment-add'] += $entity->urlInfo(); } } } @@ -1342,6 +1357,7 @@ function comment_prepare_author(CommentInterface $comment) { * Array keys: #comment, #commented_entity. */ function template_preprocess_comment(&$variables) { + /** @var $comment \Drupal\comment\CommentInterface */ $comment = $variables['elements']['#comment']; $commented_entity = entity_load($comment->entity_type->value, $comment->entity_id->value); $variables['comment'] = $comment; @@ -1379,13 +1395,19 @@ function template_preprocess_comment(&$variables) { else { $variables['signature'] = ''; } + if (isset($comment->in_preview)) { + $variables['title'] = l($comment->subject->value, ''); + $variables['permalink'] = l(t('Permalink'), ''); + } + else { + $uri = $comment->urlInfo(); + $uri['options'] += array('attributes' => array('class' => array('permalink'), 'rel' => 'bookmark')); + $variables['title'] = \Drupal::l($comment->subject->value, $uri['route_name'], $uri['route_parameters'], $uri['options']); - $uri = $comment->uri(); - $permalink_uri = $comment->permalink(); - $uri['options'] += array('attributes' => array('class' => array('permalink'), 'rel' => 'bookmark')); + $permalink_uri = $comment->permalink(); + $variables['permalink'] = \Drupal::l(t('Permalink'), $permalink_uri['route_name'], $permalink_uri['route_parameters'], $permalink_uri['options']); + } - $variables['title'] = l($comment->subject->value, $uri['path'], $uri['options']); - $variables['permalink'] = l(t('Permalink'), $permalink_uri['path'], $permalink_uri['options']); $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['author'], '!datetime' => $variables['created'])); if ($comment->pid->target_id) { @@ -1409,8 +1431,8 @@ function template_preprocess_comment(&$variables) { } $permalink_uri_parent = $comment_parent->permalink(); $permalink_uri_parent['options'] += array('attributes' => array('class' => array('permalink'), 'rel' => 'bookmark')); - $variables['parent_title'] = l($comment_parent->subject->value, $permalink_uri_parent['path'], $permalink_uri_parent['options']); - $variables['parent_permalink'] = l(t('Parent permalink'), $permalink_uri_parent['path'], $permalink_uri_parent['options']); + $variables['parent_title'] = \Drupal::l($comment_parent->subject->value, $permalink_uri_parent['route_name'], $permalink_uri_parent['route_parameters'], $permalink_uri_parent['options']); + $variables['parent_permalink'] = \Drupal::l(t('Parent permalink'), $permalink_uri_parent['route_name'], $permalink_uri_parent['route_parameters'], $permalink_uri_parent['options']); $variables['parent'] = t('In reply to !parent_title by !parent_username', array('!parent_username' => $variables['parent_author'], '!parent_title' => $variables['parent_title'])); } diff --git a/core/modules/comment/lib/Drupal/comment/CommentBreadcrumbBuilder.php b/core/modules/comment/lib/Drupal/comment/CommentBreadcrumbBuilder.php index aa41c41..d0d39bb 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentBreadcrumbBuilder.php +++ b/core/modules/comment/lib/Drupal/comment/CommentBreadcrumbBuilder.php @@ -53,8 +53,8 @@ public function build(array $attributes) { $entity = $this->entityManager ->getStorageController($attributes['entity_type']) ->load($attributes['entity_id']); - $uri = $entity->uri(); - $breadcrumb[] = l($entity->label(), $uri['path'], $uri['options']); + $uri = $entity->urlInfo(); + $breadcrumb[] = \Drupal::l($entity->label(), $uri['route_name'], $uri['route_parameters'], $uri['options']); return $breadcrumb; } diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php index c5afeeb..1f32ee8 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php @@ -368,7 +368,7 @@ public function save(array $form, array &$form_state) { $entity = entity_load($form_state['values']['entity_type'], $form_state['values']['entity_id']); $comment = $this->entity; $field_name = $comment->field_name->value; - $uri = $entity->uri(); + $uri = $entity->urlInfo(); if ($this->currentUser->hasPermission('post comments') && ($this->currentUser->hasPermission('administer comments') || $entity->{$field_name}->status == COMMENT_OPEN)) { // Save the anonymous user information to a cookie for reuse. @@ -399,15 +399,14 @@ public function save(array $form, array &$form_state) { $query['page'] = $page; } // Redirect to the newly posted comment. - $redirect = array($uri['path'], array('query' => $query, 'fragment' => 'comment-' . $comment->id()) + $uri['options']); + $uri['options'] += array('query' => $query, 'fragment' => 'comment-' . $comment->id()); } else { watchdog('content', 'Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject->value), WATCHDOG_WARNING); drupal_set_message($this->t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject->value)), 'error'); // Redirect the user to the entity they are commenting on. - $redirect = $uri['path']; } - $form_state['redirect'] = $redirect; + $form_state['redirect_route'] = $uri; // Clear the block and page caches so that anonymous users see the comment // they have posted. Cache::invalidateTags(array('content' => TRUE)); diff --git a/core/modules/comment/lib/Drupal/comment/CommentManager.php b/core/modules/comment/lib/Drupal/comment/CommentManager.php index e1075b3..0ff5a4e 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentManager.php +++ b/core/modules/comment/lib/Drupal/comment/CommentManager.php @@ -102,7 +102,7 @@ public function getParentEntityUri(CommentInterface $comment) { return $this->entityManager ->getStorageController($comment->entity_type->value) ->load($comment->entity_id->value) - ->uri(); + ->urlInfo(); } /** @@ -273,8 +273,7 @@ public function forbiddenMessage(EntityInterface $entity, $field_name) { $destination = array('destination' => 'comment/reply/' . $entity->entityType() . '/' . $entity->id() . '/' . $field_name . '#comment-form'); } else { - $uri = $entity->uri(); - $destination = array('destination' => $uri['path'] . '#comment-form'); + $destination = array('destination' => $entity->getSystemPath() . '#comment-form'); } if ($this->userConfig->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) { diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php index 15f09a7..d11cd7d 100644 --- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php +++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php @@ -92,7 +92,7 @@ public function commentApprove(CommentInterface $comment) { drupal_set_message($this->t('Comment approved.')); $permalink_uri = $comment->permalink(); $permalink_uri['options']['absolute'] = TRUE; - $url = $this->urlGenerator()->generateFromPath($permalink_uri['path'], $permalink_uri['options']); + $url = $this->urlGenerator()->generateFromRoute($permalink_uri['route_name'], $permalink_uri['route_parameters'], $permalink_uri['options']); return new RedirectResponse($url); } @@ -129,8 +129,7 @@ public function commentPermalink(Request $request, CommentInterface $comment) { // Find the current display page for this comment. $page = comment_get_display_page($comment->id(), $instance); // @todo: Cleaner sub request handling. - $uri = $entity->uri(); - $redirect_request = Request::create($uri['path'], 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all()); + $redirect_request = Request::create($entity->getSystemPath(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all()); $redirect_request->query->set('page', $page); // @todo: Convert the pager to use the request object. $request->query->set('page', $page); @@ -155,7 +154,11 @@ public function redirectNode(EntityInterface $node) { // Legacy nodes only had a single comment field, so use the first comment // field on the entity. if (!empty($fields) && ($field_names = array_keys($fields)) && ($field_name = reset($field_names))) { - return new RedirectResponse($this->urlGenerator()->generateFromPath('comment/reply/node/' . $node->id() . '/' . $field_name, array('absolute' => TRUE))); + return $this->redirect('comment.reply', array( + 'entity_type' => 'node', + 'entity_id' => $node->id(), + 'field_name' => $field_name, + )); } throw new NotFoundHttpException(); } @@ -210,13 +213,14 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_ } $account = $this->currentUser(); - $uri = $entity->uri(); + $uri = $entity->urlInfo(); + $path = $entity->getSystemPath(); $build = array(); // Check if the user has the proper permissions. if (!$account->hasPermission('post comments')) { drupal_set_message($this->t('You are not authorized to post comments.'), 'error'); - return new RedirectResponse($this->urlGenerator()->generateFromPath($uri['path'], array('absolute' => TRUE))); + return $this->redirect($uri['route_name'], $uri['route_parameters']); } // The user is not just previewing a comment. @@ -224,7 +228,7 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_ $status = $entity->{$field_name}->status; if ($status != COMMENT_OPEN) { drupal_set_message($this->t("This discussion is closed: you can't post new comments."), 'error'); - return new RedirectResponse($this->urlGenerator()->generateFromPath($uri['path'], array('absolute' => TRUE))); + return $this->redirect($uri['route_name'], $uri['route_parameters']); } // $pid indicates that this is a reply to a comment. @@ -232,14 +236,14 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_ // Check if the user has the proper permissions. if (!$account->hasPermission('access comments')) { drupal_set_message($this->t('You are not authorized to view comments.'), 'error'); - return new RedirectResponse($this->urlGenerator()->generateFromPath($uri['path'], array('absolute' => TRUE))); + return $this->redirect($uri['route_name'], $uri['route_parameters']); } // Load the parent comment. $comment = $this->entityManager()->getStorageController('comment')->load($pid); // Check if the parent comment is published and belongs to the entity. if (($comment->status->value == CommentInterface::NOT_PUBLISHED) || ($comment->entity_id->value != $entity->id())) { drupal_set_message($this->t('The comment you are replying to does not exist.'), 'error'); - return new RedirectResponse($this->urlGenerator()->generateFromPath($uri['path'], array('absolute' => TRUE))); + return $this->redirect($uri['route_name'], $uri['route_parameters']); } // Display the parent comment. $build['comment_parent'] = $this->entityManager()->getViewBuilder('comment')->view($comment); diff --git a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php index 6bcfd95..9732c91 100644 --- a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php @@ -45,6 +45,7 @@ * }, * links = { * "canonical" = "comment.permalink", + * "delete-form" = "comment.confirm_delete", * "edit-form" = "comment.edit_page", * "admin-form" = "comment.bundle" * } @@ -342,11 +343,10 @@ public static function postDelete(EntityStorageControllerInterface $storage_cont */ public function permalink() { $entity = entity_load($this->get('entity_type')->value, $this->get('entity_id')->value); - $uri = $entity->uri(); - $url['path'] = $uri['path']; - $url['options'] = array('fragment' => 'comment-' . $this->id()); + $uri = $entity->urlInfo(); + $uri['options'] = array('fragment' => 'comment-' . $this->id()); - return $url; + return $uri; } /** diff --git a/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php b/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php index 07c6d54..ebd2623 100644 --- a/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php +++ b/core/modules/comment/lib/Drupal/comment/Form/CommentAdminOverview.php @@ -172,6 +172,7 @@ public function buildForm(array $form, array &$form_state, $type = 'new') { ->pager(50) ->execute(); + /** @var $comments \Drupal\comment\CommentInterface[] */ $comments = $this->commentStorage->loadMultiple($cids); // Build a table listing the appropriate comments. @@ -190,8 +191,9 @@ public function buildForm(array $form, array &$form_state, $type = 'new') { } foreach ($comments as $comment) { + /** @var $commented_entity \Drupal\comment\CommentInterface */ $commented_entity = $commented_entities[$comment->entity_type->value][$comment->entity_id->value]; - $commented_entity_uri = $commented_entity->uri(); + $commented_entity_uri = $commented_entity->urlInfo(); $username = array( '#theme' => 'username', '#account' => comment_prepare_author($comment), @@ -207,7 +209,8 @@ public function buildForm(array $form, array &$form_state, $type = 'new') { 'data' => array( '#type' => 'link', '#title' => $comment->subject->value, - '#href' => $comment_permalink['path'], + '#route_name' => $comment_permalink['route_name'], + '#route_parameters' => $comment_permalink['route_parameters'], '#options' => $comment_permalink['options'] + array( 'attributes' => array( 'title' => Unicode::truncate($body, 128), @@ -220,14 +223,15 @@ public function buildForm(array $form, array &$form_state, $type = 'new') { 'data' => array( '#type' => 'link', '#title' => $commented_entity->label(), - '#href' => $commented_entity_uri['path'], + '#route_name' => $commented_entity_uri['route_name'], + '#route_parameters' => $commented_entity_uri['route_parameters'], '#options' => $commented_entity_uri['options'], '#access' => $commented_entity->access('view'), ), ), 'changed' => $this->date->format($comment->changed->value, 'short'), ); - $comment_uri = $comment->uri(); + $comment_uri = $comment->urlInfo(); $links = array(); $links['edit'] = array( 'title' => $this->t('edit'), diff --git a/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php b/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php index 60b2036..f226305 100644 --- a/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php +++ b/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php @@ -63,7 +63,8 @@ protected function actions(array $form, array &$form_state) { // @todo Convert to getCancelRoute() after http://drupal.org/node/1987778. $uri = $this->commentManager->getParentEntityUri($this->entity); - $actions['cancel']['#href'] = $uri['path']; + $actions['cancel']['#route_name'] = $uri['route_name']; + $actions['cancel']['#route_parameters'] = $uri['route_parameters']; return $actions; } @@ -99,8 +100,7 @@ public function submit(array $form, array &$form_state) { // Clear the cache so an anonymous user sees that his comment was deleted. Cache::invalidateTags(array('content' => TRUE)); - $uri = $this->commentManager->getParentEntityUri($this->entity); - $form_state['redirect'] = $uri['path']; + $form_state['redirect_route'] = $this->commentManager->getParentEntityUri($this->entity); } } diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php index b74600c..8f429f2 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php @@ -93,8 +93,7 @@ protected function renderLink($data, ResultRow $values) { $entity_id = $this->getValue($values, 'entity_id'); $entity_type = $this->getValue($values, 'entity_type'); $entity = entity_load($entity_type, $entity_id); - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $entity->getSystemPath(); } } diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Link.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Link.php index 502566f..adba10b 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Link.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Link.php @@ -117,8 +117,7 @@ protected function renderLink($data, ResultRow $values) { $entity_id = $comment->entity_id; $entity_type = $comment->entity_type; $entity = $this->entityManager->getStorageController($entity_type)->load($entity_id); - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $entity->getSystemPath(); } return $text; diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkDelete.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkDelete.php index c225580..504b7ad 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkDelete.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkDelete.php @@ -43,7 +43,7 @@ protected function renderLink($data, ResultRow $values) { $comment = $this->getEntity($values); $this->options['alter']['make_link'] = TRUE; - $this->options['alter']['path'] = "comment/" . $comment->id(). "/delete"; + $this->options['alter']['path'] = $comment->getSystemPath('delete-form'); $this->options['alter']['query'] = drupal_get_destination(); return $text; diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/row/Rss.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/row/Rss.php index 4911373..4fbfc76 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/row/Rss.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/row/Rss.php @@ -98,6 +98,7 @@ public function render($row) { } // Load the specified comment and its associated node: + /** @var $comment \Drupal\comment\CommentInterface */ $comment = $this->comments[$cid]; if (empty($comment)) { return; @@ -105,8 +106,7 @@ public function render($row) { $item_text = ''; - $uri = $comment->uri(); - $comment->link = url($uri['path'], $uri['options'] + array('absolute' => TRUE)); + $comment->link = $comment->url('canonical', array('absolute' => TRUE)); $comment->rss_namespaces = array(); $comment->rss_elements = array( array( diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php index e9fd575..0e8c282 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php @@ -134,11 +134,11 @@ protected function assertPublishedStatus() { $languages = language_list(); // Check that simple users cannot see unpublished field translations. - $uri = $entity->uri(); + $path = $entity->getSystemPath(); foreach ($this->langcodes as $index => $langcode) { $translation = $this->getTranslation($entity, $langcode); $value = $this->getValue($translation, 'comment_body', $langcode); - $this->drupalGet($uri['path'], array('language' => $languages[$langcode])); + $this->drupalGet($path, array('language' => $languages[$langcode])); if ($index > 0) { $this->assertNoRaw($value, 'Unpublished field translation is not shown.'); } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php index 12fda9c..682aeef 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityListTest.php @@ -35,8 +35,7 @@ public static function getInfo() { * Tests entity list controller methods. */ function testList() { - $controller = $this->container->get('entity.manager') - ->getListController('config_test'); + $controller = \Drupal::entityManager()->getListController('config_test'); // Test getStorageController() method. $this->assertTrue($controller->getStorageController() instanceof EntityStorageControllerInterface, 'EntityStorageController instance in storage.'); @@ -51,26 +50,19 @@ function testList() { $this->assertTrue($entity instanceof ConfigTest, '"Default" ConfigTest entity is an instance of ConfigTest.'); // Test getOperations() method. - $uri = $entity->uri(); $expected_operations = array( 'edit' => array ( 'title' => t('Edit'), - 'href' => $uri['path'], - 'options' => $uri['options'], 'weight' => 10, - ), + ) + $entity->urlInfo(), 'disable' => array( 'title' => t('Disable'), - 'href' => $uri['path'] . '/disable', - 'options' => $uri['options'], 'weight' => 40, - ), + ) + $entity->urlInfo('disable'), 'delete' => array ( 'title' => t('Delete'), - 'href' => $uri['path'] . '/delete', - 'options' => $uri['options'], 'weight' => 100, - ), + ) + $entity->urlInfo('delete-form'), ); $actual_operations = $controller->getOperations($entity); @@ -130,20 +122,15 @@ function testList() { $entity = $list['default']; // Test getOperations() method. - $uri = $entity->uri(); $expected_operations = array( 'edit' => array( 'title' => t('Edit'), - 'href' => $uri['path'], - 'options' => $uri['options'], 'weight' => 10, - ), + ) + $entity->urlInfo(), 'delete' => array( 'title' => t('Delete'), - 'href' => $uri['path'] . '/delete', - 'options' => $uri['options'], 'weight' => 100, - ), + ) + $entity->urlInfo('delete-form'), ); $actual_operations = $controller->getOperations($entity); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityStatusUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityStatusUITest.php index da36cab..89f5b00 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityStatusUITest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityStatusUITest.php @@ -41,17 +41,17 @@ function testCRUD() { ); $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save'); - $uri = entity_load('config_test', $id)->uri(); + $entity = entity_load('config_test', $id); // Disable an entity. - $disable_path = "{$uri['path']}/disable"; + $disable_path = $entity->getSystemPath('disable'); $this->assertLinkByHref($disable_path); $this->drupalGet($disable_path); $this->assertResponse(200); $this->assertNoLinkByHref($disable_path); // Enable an entity. - $enable_path = "{$uri['path']}/enable"; + $enable_path = $entity->getSystemPath('enable'); $this->assertLinkByHref($enable_path); $this->drupalGet($enable_path); $this->assertResponse(200); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php index 2832c93..5dd699a 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php @@ -61,8 +61,14 @@ function testCRUD() { // Verify Entity properties/methods on the newly created empty entity. $this->assertIdentical($empty->entityType(), 'config_test'); - $uri = $empty->uri(); - $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage'); + // The URI can only be checked after saving. + try { + $empty->urlInfo(); + $this->fail('EntityMalformedException was thrown.'); + } + catch (EntityMalformedException $e) { + $this->pass('EntityMalformedException was thrown.'); + } // Verify that an empty entity cannot be saved. try { @@ -107,9 +113,6 @@ function testCRUD() { $expected['uuid'] = $config_test->uuid(); $this->assertIdentical($config_test->label(), $expected['label']); - $uri = $config_test->uri(); - $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage/' . $expected['id']); - // Verify that the entity can be saved. try { $status = $config_test->save(); @@ -119,6 +122,9 @@ function testCRUD() { $this->fail('EntityMalformedException was not thrown.'); } + // The entity path can only be checked after saving. + $this->assertIdentical($config_test->getSystemPath(), 'admin/structure/config_test/manage/' . $expected['id']); + // Verify that the correct status is returned and properties did not change. $this->assertIdentical($status, SAVED_NEW); $this->assertIdentical($config_test->id(), $expected['id']); diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module index 0c3b782..4fb13e3 100644 --- a/core/modules/config/tests/config_test/config_test.module +++ b/core/modules/config/tests/config_test/config_test.module @@ -76,6 +76,8 @@ function config_test_entity_info_alter(&$entity_info) { // Create a clone of config_test that does not have a status. $entity_info['config_test_no_status'] = clone $entity_info['config_test']; $config_test_no_status = &$entity_info['config_test_no_status']; + $config_test_no_status->setLinkTemplate('edit-form', 'config_test.entity_config_test_no_status'); + $config_test_no_status->setLinkTemplate('delete-form', 'config_test.entity_delete_config_test_no_status'); $keys = $config_test_no_status->getKeys(); unset($keys['status']); diff --git a/core/modules/config/tests/config_test/config_test.routing.yml b/core/modules/config/tests/config_test/config_test.routing.yml index 7af61cd..2775b2b 100644 --- a/core/modules/config/tests/config_test/config_test.routing.yml +++ b/core/modules/config/tests/config_test/config_test.routing.yml @@ -20,6 +20,14 @@ config_test.entity: requirements: _access: 'TRUE' +config_test.entity_config_test_no_status: + path: '/admin/structure/config_test/manage/{config_test_no_status}' + defaults: + _content: '\Drupal\config_test\ConfigTestController::edit' + entity_type: 'config_test_no_status' + requirements: + _access: 'TRUE' + config_test.entity_enable: path: '/admin/structure/config_test/manage/{config_test}/enable' defaults: @@ -40,6 +48,12 @@ config_test.entity_delete: path: '/admin/structure/config_test/manage/{config_test}/delete' defaults: _entity_form: 'config_test.delete' - entity_type: 'config_test' + requirements: + _access: 'TRUE' + +config_test.entity_delete_config_test_no_status: + path: '/admin/structure/config_test/manage/{config_test_no_status}/delete' + defaults: + _entity_form: 'config_test_no_status.delete' requirements: _access: 'TRUE' diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php index 514311b..3417a12 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/ConfigTestFormController.php @@ -82,16 +82,4 @@ public function save(array $form, array &$form_state) { $form_state['redirect_route']['route_name'] = 'config_test.list_page'; } - /** - * Overrides Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'config_test.entity_delete', - 'route_parameters' => array( - 'config_test' => $this->entity->id(), - ), - ); - } - } diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php index 34217a9..623fa14 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php @@ -33,7 +33,10 @@ * "status" = "status" * }, * links = { - * "edit-form" = "config_test.entity" + * "edit-form" = "config_test.entity", + * "delete-form" = "config_test.entity_delete", + * "enable" = "config_test.entity_enable", + * "disable" = "config_test.entity_disable" * } * ) */ diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module index 8e91d30..cb2b0e4 100644 --- a/core/modules/config_translation/config_translation.module +++ b/core/modules/config_translation/config_translation.module @@ -154,10 +154,10 @@ function config_translation_config_translation_info(&$info) { */ function config_translation_entity_operation_alter(array &$operations, EntityInterface $entity) { if (\Drupal::currentUser()->hasPermission('translate configuration')) { - $uri = $entity->uri(); + $uri = $entity->urlInfo(); $operations['translate'] = array( 'title' => t('Translate'), - 'href' => $uri['path'] . '/translate', + 'href' => $entity->getSystemPath() . '/translate', 'options' => $uri['options'], 'weight' => 50, ); diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index 9b06fd9..5ba6877 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -80,6 +80,14 @@ function contact_menu() { } /** + * Implements hook_entity_info_alter(). + */ +function contact_entity_info_alter(&$entity_info) { + /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */ + $entity_info['user']->setLinkTemplate('contact-form', 'contact.personal_page'); +} + +/** * Implements hook_entity_bundle_info(). */ function contact_entity_bundle_info() { @@ -163,6 +171,7 @@ function contact_category_load($id) { */ function contact_mail($key, &$message, $params) { $contact_message = $params['contact_message']; + /** @var $sender \Drupal\user\UserInterface */ $sender = $params['sender']; $language = language_load($message['langcode']); @@ -174,8 +183,7 @@ function contact_mail($key, &$message, $params) { '!sender-name' => user_format_name($sender), ); if ($sender->isAuthenticated()) { - $sender_uri = $sender->uri(); - $variables['!sender-url'] = url($sender_uri['path'], array('absolute' => TRUE, 'language' => $language) + $sender_uri['options']); + $variables['!sender-url'] = $sender->url('canonical', array('absolute' => TRUE, 'language' => $language)); } else { $variables['!sender-url'] = $params['sender']->getEmail(); diff --git a/core/modules/contact/lib/Drupal/contact/CategoryFormController.php b/core/modules/contact/lib/Drupal/contact/CategoryFormController.php index 15c7c5d..50b5203 100644 --- a/core/modules/contact/lib/Drupal/contact/CategoryFormController.php +++ b/core/modules/contact/lib/Drupal/contact/CategoryFormController.php @@ -97,14 +97,16 @@ public function save(array $form, array &$form_state) { $category = $this->entity; $status = $category->save(); - $uri = $category->uri(); + $uri = $category->urlInfo(); + $edit_link = \Drupal::l($this->t('Edit'), $uri['route_name'], $uri['route_parameters'], $uri['options']); + if ($status == SAVED_UPDATED) { drupal_set_message(t('Category %label has been updated.', array('%label' => $category->label()))); - watchdog('contact', 'Category %label has been updated.', array('%label' => $category->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('contact', 'Category %label has been updated.', array('%label' => $category->label()), WATCHDOG_NOTICE, $edit_link); } else { drupal_set_message(t('Category %label has been added.', array('%label' => $category->label()))); - watchdog('contact', 'Category %label has been added.', array('%label' => $category->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('contact', 'Category %label has been added.', array('%label' => $category->label()), WATCHDOG_NOTICE, $edit_link); } // Update the default category. @@ -124,14 +126,4 @@ public function save(array $form, array &$form_state) { $form_state['redirect_route']['route_name'] = 'contact.category_list'; } - /** - * Overrides Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'contact.category_delete', - 'route_parameters' => array('contact_category' => $this->entity->id()), - ); - } - } diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Category.php b/core/modules/contact/lib/Drupal/contact/Entity/Category.php index 86fa0f1..a3d3187 100644 --- a/core/modules/contact/lib/Drupal/contact/Entity/Category.php +++ b/core/modules/contact/lib/Drupal/contact/Entity/Category.php @@ -36,6 +36,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "contact.category_delete", * "edit-form" = "contact.category_edit" * } * ) diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php index ca4a607..e7012b6 100644 --- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php +++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php @@ -17,6 +17,13 @@ class MessageFormController extends ContentEntityFormController { /** + * The message being used by this form. + * + * @var \Drupal\contact\MessageInterface + */ + protected $entity; + + /** * Overrides Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { @@ -208,8 +215,7 @@ public function save(array $form, array &$form_state) { // To avoid false error messages caused by flood control, redirect away from // the contact form; either to the contacted user account or the front page. if ($message->isPersonal() && user_access('access user profiles')) { - $uri = $message->getPersonalRecipient()->uri(); - $form_state['redirect'] = array($uri['path'], $uri['options']); + $form_state['redirect_route'] = $message->getPersonalRecipient()->urlInfo(); } else { $form_state['redirect_route']['route_name'] = ''; diff --git a/core/modules/contact/lib/Drupal/contact/Tests/Views/ContactLinkTest.php b/core/modules/contact/lib/Drupal/contact/Tests/Views/ContactLinkTest.php index 064ac2d..1bae3d4 100644 --- a/core/modules/contact/lib/Drupal/contact/Tests/Views/ContactLinkTest.php +++ b/core/modules/contact/lib/Drupal/contact/Tests/Views/ContactLinkTest.php @@ -108,9 +108,7 @@ public function assertContactLinks(array $accounts, array $names) { foreach ($names as $name) { $account = $accounts[$name]; - $uri = $account->uri(); - $contact_uri = $uri['path'] . '/contact'; - $result = $this->xpath('//div[contains(@class, "views-field-contact")]//a[contains(@href, :uri)]', array(':uri' => $contact_uri)); + $result = $this->xpath('//div[contains(@class, "views-field-contact")]//a[contains(@href, :url)]', array(':url' => $account->url('contact-form'))); $this->assertTrue(count($result)); } } diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index a6f7987..ceba2d3 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -175,12 +175,9 @@ function content_translation_entity_field_info_alter(&$info, $entity_type) { function content_translation_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) { // @todo Use an access permission. if ($entity instanceof NodeInterface && $entity->isTranslatable()) { - $uri = $entity->uri(); $operations['translate'] = array( 'title' => t('Translate'), - 'href' => $uri['path'] . '/translations', - 'options' => $uri['options'], - ); + ) + $entity->urlInfo('drupal:content-translation-overview'); } } diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc index aa1b1f3..447ef5f 100644 --- a/core/modules/content_translation/content_translation.pages.inc +++ b/core/modules/content_translation/content_translation.pages.inc @@ -19,7 +19,6 @@ */ function content_translation_overview(EntityInterface $entity) { $controller = content_translation_controller($entity->entityType()); - $entity_manager = \Drupal::entityManager(); $languages = language_list(); $original = $entity->getUntranslated()->language()->id; $translations = $entity->getTranslationLanguages(); @@ -27,18 +26,13 @@ function content_translation_overview(EntityInterface $entity) { $rel = array(); foreach (array('canonical', 'edit-form', 'drupal:content-translation-overview') as $name) { - $rel[$name] = $entity->uri($name); + $rel[$name] = $entity->getSystemPath($name); } $header = array(t('Language'), t('Translation'), t('Source language'), t('Status'), t('Operations')); $rows = array(); if (\Drupal::languageManager()->isMultilingual()) { - // If we have a view path defined for the current entity get the switch - // links based on it. - if (!empty($rel['canonical'])) { - $links = _content_translation_get_switch_links($rel['canonical']['path']); - } // Determine whether the current entity is translatable. $translatable = FALSE; @@ -53,13 +47,13 @@ function content_translation_overview(EntityInterface $entity) { $language_name = $language->name; $langcode = $language->id; - $add_path = $rel['drupal:content-translation-overview']['path'] . '/add/' . $original . '/' . $langcode; - $translate_path = $rel['drupal:content-translation-overview']['path'] . '/edit/' . $langcode; + $add_path = $rel['drupal:content-translation-overview'] . '/add/' . $original . '/' . $langcode; + $translate_path = $rel['drupal:content-translation-overview'] . '/edit/' . $langcode; $add_links = _content_translation_get_switch_links($add_path); - $edit_links = _content_translation_get_switch_links($rel['edit-form']['path']); + $edit_links = _content_translation_get_switch_links($rel['edit-form']); $translate_links = _content_translation_get_switch_links($translate_path); - $delete_links = _content_translation_get_switch_links($rel['drupal:content-translation-overview']['path'] . '/delete/' . $langcode); + $delete_links = _content_translation_get_switch_links($rel['drupal:content-translation-overview'] . '/delete/' . $langcode); $operations = array( 'data' => array( @@ -74,7 +68,7 @@ function content_translation_overview(EntityInterface $entity) { $source = isset($entity->translation[$langcode]['source']) ? $entity->translation[$langcode]['source'] : ''; $is_original = $langcode == $original; $label = $entity->getTranslation($langcode)->label(); - $link = isset($links->links[$langcode]['href']) ? $links->links[$langcode] : array('href' => $rel['canonical']['path'], 'language' => $language); + $link = isset($links->links[$langcode]['href']) ? $links->links[$langcode] : array('href' => $rel['canonical'], 'language' => $language); $row_title = l($label, $link['href'], $link); if (empty($link['href'])) { @@ -85,7 +79,7 @@ function content_translation_overview(EntityInterface $entity) { // the entity form, otherwise if we are not dealing with the original // language we point the link to the translation form. if ($entity->access('update')) { - $links['edit'] = isset($edit_links->links[$langcode]['href']) ? $edit_links->links[$langcode] : array('href' => $rel['edit-form']['path'], 'language' => $language); + $links['edit'] = isset($edit_links->links[$langcode]['href']) ? $edit_links->links[$langcode] : array('href' => $rel['edit-form'], 'language' => $language); } elseif (!$is_original && $controller->getTranslationAccess($entity, 'update')) { $links['edit'] = isset($translate_links->links[$langcode]['href']) ? $translate_links->links[$langcode] : array('href' => $translate_path, 'language' => $language); diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php index e99c9b0..e63aa0a 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php @@ -431,9 +431,8 @@ public function entityFormSourceChange($form, &$form_state) { $entity = $form_controller->getEntity(); $source = $form_state['values']['source_langcode']['source']; - $uri = $entity->uri('drupal:content-translation-overview'); - $path = $uri['path'] . '/add/' . $source . '/' . $form_controller->getFormLangcode($form_state); - $form_state['redirect'] = $path; + $path = $entity->getSystemPath('drupal:content-translation-overview'); + $form_state['redirect'] = $path . '/add/' . $source . '/' . $form_controller->getFormLangcode($form_state); $languages = language_list(); drupal_set_message(t('Source language set to: %language', array('%language' => $languages[$source]->name))); } @@ -459,9 +458,9 @@ function entityFormDelete($form, &$form_state) { function entityFormDeleteTranslation($form, &$form_state) { $form_controller = content_translation_form_controller($form_state); $entity = $form_controller->getEntity(); - $uri = $entity->uri('drupal:content-translation-overview'); + $path = $entity->getSystemPath('drupal:content-translation-overview'); $form_langcode = $form_controller->getFormLangcode($form_state); - $form_state['redirect'] = $uri['path'] . '/delete/' . $form_langcode; + $form_state['redirect'] = $path . '/delete/' . $form_langcode; } /** diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php index 5d33cdf..b7a0ced 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationDeleteForm.php @@ -40,7 +40,6 @@ public function getFormId() { */ public function buildForm(array $form, array &$form_state, $_entity_type = NULL, $language = NULL) { $this->entity = $this->getRequest()->attributes->get($_entity_type); - $uri = $this->entity->uri('drupal:content-translation-overview'); $this->language = language_load($language); return parent::buildForm($form, $form_state); } @@ -82,8 +81,8 @@ public function submitForm(array &$form, array &$form_state) { // Remove any existing path alias for the removed translation. // @todo This should be taken care of by the Path module. if (\Drupal::moduleHandler()->moduleExists('path')) { - $uri = $this->entity->uri(); - $conditions = array('source' => $uri['path'], 'langcode' => $this->language->id); + $path = $this->entity->getSystemPath(); + $conditions = array('source' => $path, 'langcode' => $this->language->id); \Drupal::service('path.crud')->delete($conditions); } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Plugin/views/field/TranslationLink.php b/core/modules/content_translation/lib/Drupal/content_translation/Plugin/views/field/TranslationLink.php index 2bf910e..176d3f6 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Plugin/views/field/TranslationLink.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Plugin/views/field/TranslationLink.php @@ -64,8 +64,7 @@ protected function renderLink(EntityInterface $entity, ResultRow $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('translate'); $this->options['alter']['make_link'] = TRUE; - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path'] . '/translations'; + $this->options['alter']['path'] = $entity->getSystemPath() . '/translations'; return $text; } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php index 8a1b198..49c40e7 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php @@ -52,8 +52,7 @@ protected function doTestBasicTranslation() { $this->entityId = $this->createEntity($values[$default_langcode], $default_langcode); $entity = entity_load($this->entityType, $this->entityId, TRUE); $this->assertTrue($entity, 'Entity found in the database.'); - $uri = $entity->uri(); - $this->drupalGet($uri['path']); + $this->drupalGet($entity->getSystemPath()); $this->assertResponse(200, 'Entity URL is valid.'); $translation = $this->getTranslation($entity, $default_langcode); @@ -68,8 +67,8 @@ protected function doTestBasicTranslation() { $langcode = 'it'; $values[$langcode] = $this->getNewEntityValues($langcode); - $uri = $entity->uri('drupal:content-translation-overview'); - $path = $langcode . '/' . $uri['path'] . '/add/' . $default_langcode . '/' . $langcode; + $content_translation_path = $entity->getSystemPath('drupal:content-translation-overview'); + $path = $langcode . '/' . $content_translation_path . '/add/' . $default_langcode . '/' . $langcode; $this->drupalPostForm($path, $this->getEditValues($values, $langcode), $this->getFormSubmitAction($entity)); if ($this->testLanguageSelector) { $this->assertNoFieldByXPath('//select[@id="edit-langcode"]', NULL, 'Language selector correclty disabled on translations.'); @@ -80,7 +79,7 @@ protected function doTestBasicTranslation() { $langcode = 'fr'; $source_langcode = 'it'; $edit = array('source_langcode[source]' => $source_langcode); - $path = $langcode . '/' . $uri['path'] . '/add/' . $default_langcode . '/' . $langcode; + $path = $langcode . '/' . $content_translation_path . '/add/' . $default_langcode . '/' . $langcode; $this->drupalPostForm($path, $edit, t('Change')); $this->assertFieldByXPath("//input[@name=\"{$this->fieldName}[0][value]\"]", $values[$source_langcode][$this->fieldName][0]['value'], 'Source language correctly switched.'); @@ -107,8 +106,7 @@ protected function doTestBasicTranslation() { */ protected function doTestTranslationOverview() { $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('drupal:content-translation-overview'); - $this->drupalGet($uri['path']); + $this->drupalGet($entity->getSystemPath('drupal:content-translation-overview')); foreach ($this->langcodes as $langcode) { if ($entity->hasTranslation($langcode)) { @@ -127,14 +125,14 @@ protected function doTestOutdatedStatus() { // Mark translations as outdated. $edit = array('content_translation[retranslate]' => TRUE); - $uri = $entity->uri('edit-form'); - $this->drupalPostForm($langcode . '/' . $uri['path'], $edit, $this->getFormSubmitAction($entity)); + $edit_path = $entity->getSystemPath('edit-form'); + $this->drupalPostForm($langcode . '/' . $edit_path, $edit, $this->getFormSubmitAction($entity)); $entity = entity_load($this->entityType, $this->entityId, TRUE); // Check that every translation has the correct "outdated" status. foreach ($this->langcodes as $enabled_langcode) { $prefix = $enabled_langcode != $default_langcode ? $enabled_langcode . '/' : ''; - $path = $prefix . $uri['path']; + $path = $prefix . $edit_path; $this->drupalGet($path); if ($enabled_langcode == $langcode) { $this->assertFieldByXPath('//input[@name="content_translation[retranslate]"]', FALSE, 'The retranslate flag is not checked by default.'); @@ -156,8 +154,7 @@ protected function doTestOutdatedStatus() { */ protected function doTestPublishedStatus() { $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('edit-form'); - $path = $uri['path']; + $path = $entity->getSystemPath('edit-form'); // Unpublish translations. foreach ($this->langcodes as $index => $langcode) { @@ -179,8 +176,7 @@ protected function doTestPublishedStatus() { */ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('edit-form'); - $path = $uri['path']; + $path = $entity->getSystemPath('edit-form'); $values = array(); // Post different authoring information for each translation. @@ -224,8 +220,8 @@ protected function doTestTranslationDeletion() { // Confirm and delete a translation. $langcode = 'fr'; $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('edit-form'); - $this->drupalPostForm($langcode . '/' . $uri['path'], array(), t('Delete translation')); + $path = $entity->getSystemPath('edit-form'); + $this->drupalPostForm($langcode . '/' . $path, array(), t('Delete translation')); $this->drupalPostForm(NULL, array(), t('Delete')); $entity = entity_load($this->entityType, $this->entityId, TRUE); if ($this->assertTrue(is_object($entity), 'Entity found')) { diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationWorkflowsTest.php index 0b3da77..d5ac203 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationWorkflowsTest.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationWorkflowsTest.php @@ -67,8 +67,8 @@ protected function setupEntity() { // Create a translation. $this->drupalLogin($this->translator); - $uri = $this->entity->uri('drupal:content-translation-overview'); - $add_translation_path = $uri['path'] . "/add/$default_langcode/{$this->langcodes[2]}"; + $path = $this->entity->getSystemPath('drupal:content-translation-overview'); + $add_translation_path = $path . "/add/$default_langcode/{$this->langcodes[2]}"; $this->drupalPostForm($add_translation_path, array(), t('Save')); $this->rebuildContainer(); } @@ -91,8 +91,7 @@ function testWorkflows() { // Check that translation permissions governate the associated operations. $ops = array('create' => t('Add'), 'update' => t('Edit'), 'delete' => t('Delete')); - $uri = $this->entity->uri('drupal:content-translation-overview'); - $translations_path = $uri['path']; + $translations_path = $this->entity->getSystemPath('drupal:content-translation-overview'); foreach ($ops as $current_op => $label) { $user = $this->drupalCreateUser(array($this->getTranslatePermission(), "$current_op content translations")); $this->drupalLogin($user); @@ -125,16 +124,14 @@ protected function assertWorkflows(UserInterface $user, $expected_status) { $this->drupalLogin($user); // Check whether the user is allowed to access the entity form in edit mode. - $uri = $this->entity->uri('edit-form'); - $edit_path = $uri['path']; + $edit_path = $this->entity->getSystemPath('edit-form'); $options = array('language' => $languages[$default_langcode]); $this->drupalGet($edit_path, $options); $this->assertResponse($expected_status['edit'], format_string('The @user_label has the expected edit access.', $args)); // Check whether the user is allowed to access the translation overview. $langcode = $this->langcodes[1]; - $uri = $this->entity->uri('drupal:content-translation-overview'); - $translations_path = $uri['path']; + $translations_path = $this->entity->getSystemPath('drupal:content-translation-overview'); $options = array('language' => $languages[$langcode]); $this->drupalGet($translations_path, $options); $this->assertResponse($expected_status['overview'], format_string('The @user_label has the expected translation overview access.', $args)); diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php index 6275fe5..43bdad1 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormMode.php @@ -47,6 +47,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "entity.form_mode_delete", * "edit-form" = "entity.form_mode_edit" * } * ) diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php index 1b569a8..9a31767 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewMode.php @@ -48,6 +48,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "entity.view_mode_delete", * "edit-form" = "entity.view_mode_edit" * } * ) diff --git a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeEditForm.php b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeEditForm.php index 48c2b96..47662ba 100644 --- a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeEditForm.php +++ b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeEditForm.php @@ -12,17 +12,4 @@ */ class EntityDisplayModeEditForm extends EntityDisplayModeFormBase { - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $entity_type = $this->entity->entityType(); - $form_state['redirect_route'] = array( - 'route_name' => 'entity.' . $entity_type . '_delete', - 'route_parameters' => array( - $entity_type => $this->entity->id(), - ), - ); - } - } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php index 008ffe7..ea13e17 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php @@ -59,15 +59,17 @@ public function viewElements(FieldItemListInterface $items) { // User doesn't have access to the referenced entity. continue; } + /** @var $referenced_entity \Drupal\Core\Entity\EntityInterface */ if ($referenced_entity = $item->entity) { $label = $referenced_entity->label(); // If the link is to be displayed and the entity has a uri, // display a link. - if ($this->getSetting('link') && $uri = $referenced_entity->uri()) { + if ($this->getSetting('link') && $uri = $referenced_entity->urlInfo()) { $elements[$delta] = array( '#type' => 'link', '#title' => $label, - '#href' => $uri['path'], + '#route_name' => $uri['route_name'], + '#route_parameters' => $uri['route_parameters'], '#options' => $uri['options'], ); } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php index 5f98b85..df4731b 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstance.php @@ -518,14 +518,11 @@ protected function linkTemplates() { /** * {@inheritdoc} */ - protected function uriPlaceholderReplacements() { - if (empty($this->uriPlaceholderReplacements)) { - parent::uriPlaceholderReplacements(); - $entity_info = \Drupal::entityManager()->getDefinition($this->entity_type); - $key = '{' . $entity_info->getBundleEntityType() . '}'; - $this->uriPlaceholderReplacements[$key] = $this->bundle; - } - return $this->uriPlaceholderReplacements; + protected function urlRouteParameters($rel) { + $parameters = parent::urlRouteParameters($rel); + $entity_info = \Drupal::entityManager()->getDefinition($this->entity_type); + $parameters[$entity_info->getBundleEntityType()] = $this->bundle; + return $parameters; } /** diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 9461296..5b2460a 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -122,6 +122,15 @@ function field_ui_entity_info(&$entity_info) { /** @var $entity_info \Drupal\Core\Entity\EntityTypeInterface[] */ $entity_info['field_instance']->setFormClass('delete', 'Drupal\field_ui\Form\FieldDeleteForm'); $entity_info['field_entity']->setListClass('Drupal\field_ui\FieldListController'); + + foreach ($entity_info as $info) { + if ($bundle = $info->getBundleOf()) { + $info + ->setLinkTemplate('field_ui-fields', "field_ui.overview_$bundle") + ->setLinkTemplate('field_ui-form-display', "field_ui.form_display_overview_$bundle") + ->setLinkTemplate('field_ui-display', "field_ui.display_overview_$bundle"); + } + } } /** @@ -170,30 +179,23 @@ function field_ui_entity_operation_alter(array &$operations, EntityInterface $en // Add manage fields and display links if this entity type is the bundle // of another. if ($bundle_of = $info->getBundleOf()) { - $uri = $entity->uri(); if (user_access('administer '. $bundle_of . ' fields')) { $operations['manage-fields'] = array( 'title' => t('Manage fields'), - 'href' => $uri['path'] . '/fields', - 'options' => $uri['options'], 'weight' => 15, - ); + ) + $entity->urlInfo('field_ui-fields'); } if (user_access('administer '. $bundle_of . ' form display')) { $operations['manage-form-display'] = array( 'title' => t('Manage form display'), - 'href' => $uri['path'] . '/form-display', - 'options' => $uri['options'], 'weight' => 20, - ); + ) + $entity->urlInfo('field_ui-form-display'); } if (user_access('administer '. $bundle_of . ' display')) { $operations['manage-display'] = array( 'title' => t('Manage display'), - 'href' => $uri['path'] . '/display', - 'options' => $uri['options'], 'weight' => 25, - ); + ) + $entity->urlInfo('field_ui-display'); } } } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index b1fb656..4a25ca6 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -273,7 +273,7 @@ function testSingleViewMode() { $this->assertNoText('Use custom display settings for the following view modes', 'Custom display settings fieldset found.'); // This may not trigger a notice when 'view_modes_custom' isn't available. - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary . '/display', array(), t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary . '/overview/display', array(), t('Save')); } /** diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php index a8e6508..6b466d8 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php @@ -507,7 +507,7 @@ function testDuplicateFieldName() { */ function testDeleteTaxonomyField() { // Create a new field. - $bundle_path = 'admin/structure/taxonomy/manage/tags'; + $bundle_path = 'admin/structure/taxonomy/manage/tags/overview'; $edit1 = array( 'fields[_add_new_field][label]' => $this->field_label, 'fields[_add_new_field][field_name]' => $this->field_name_input, diff --git a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php index 0bb5dec..edab6c5 100644 --- a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php +++ b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php @@ -39,7 +39,8 @@ * "status" = "status" * }, * links = { - * "edit-form" = "filter.format_edit" + * "edit-form" = "filter.format_edit", + * "disable" = "filter.admin_disable" * } * ) */ diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 538d6b3..9b8ee70 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -196,7 +196,9 @@ function forum_entity_info(&$entity_info) { // Register forum specific form controllers. $entity_info['taxonomy_term'] ->setFormClass('forum', 'Drupal\forum\Form\ForumFormController') - ->setFormClass('container', 'Drupal\forum\Form\ContainerFormController'); + ->setFormClass('container', 'Drupal\forum\Form\ContainerFormController') + ->setLinkTemplate('forum-delete-form', 'forum.delete') + ->setLinkTemplate('forum-edit-form', 'forum.edit_forum'); } /** @@ -216,7 +218,10 @@ function forum_entity_bundle_info_alter(&$bundles) { */ function forum_uri($forum) { return array( - 'path' => 'forum/' . $forum->id(), + 'route_name' => 'forum.page', + 'route_parameters' => array( + 'taxonomy_term' => $forum->id(), + ), ); } diff --git a/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php b/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php index 0605c0a..125a35d 100644 --- a/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php +++ b/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php @@ -102,21 +102,12 @@ public function save(array $form, array &$form_state) { * {@inheritdoc} */ public function delete(array $form, array &$form_state) { - $destination = array(); - $request = $this->getRequest(); - if ($request->query->has('destination')) { - $destination = drupal_get_destination(); - $request->query->remove('destination'); + $form_state['redirect_route'] = $this->entity->urlInfo('forum-delete-form'); + + $query = $this->getRequest()->query; + if ($query->has('destination')) { + $form_state['redirect_route']['options']['query']['destination'] = $query->get('destination'); } - $form_state['redirect_route'] = array( - 'route_name' => 'forum.delete', - 'route_parameters' => array( - 'taxonomy_term' => $this->entity->id(), - ), - 'options' => array( - 'query' => $destination, - ), - ); } /** diff --git a/core/modules/forum/lib/Drupal/forum/Form/Overview.php b/core/modules/forum/lib/Drupal/forum/Form/Overview.php index 560d535..4505264 100644 --- a/core/modules/forum/lib/Drupal/forum/Form/Overview.php +++ b/core/modules/forum/lib/Drupal/forum/Form/Overview.php @@ -77,14 +77,14 @@ public function buildForm(array $form, array &$form_state) { unset($form['terms'][$key]['operations']['#links']['delete']); if (!empty($term->forum_container->value)) { $form['terms'][$key]['operations']['#links']['edit']['title'] = $this->t('edit container'); - $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/container/' . $term->id(); + $form['terms'][$key]['operations']['#links']['edit']['route_name'] = 'forum.edit_container'; // We don't want the redirect from the link so we can redirect the // delete action. unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']); } else { $form['terms'][$key]['operations']['#links']['edit']['title'] = $this->t('edit forum'); - $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/forum/' . $term->id(); + $form['terms'][$key]['operations']['#links']['edit']['route_name'] = 'forum.edit_forum'; // We don't want the redirect from the link so we can redirect the // delete action. unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php index 86017f7..a706f74 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php @@ -284,7 +284,7 @@ private function doAdminTests($user) { $this->root_forum = $this->createForum('forum'); // Test vocabulary form alterations. - $this->drupalGet('admin/structure/taxonomy/manage/forums/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/forums'); $this->assertFieldByName('op', t('Save'), 'Save button found.'); $this->assertNoFieldByName('op', t('Delete'), 'Delete button not found.'); @@ -305,7 +305,7 @@ private function doAdminTests($user) { )); $vocabulary->save(); // Test tags vocabulary form is not affected. - $this->drupalGet('admin/structure/taxonomy/manage/tags/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/tags'); $this->assertFieldByName('op', t('Save'), 'Save button found.'); $this->assertFieldByName('op', t('Delete'), 'Delete button found.'); // Test tags vocabulary term form is not affected. @@ -331,7 +331,7 @@ function editForumVocabulary() { ); // Edit the vocabulary. - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $original_vocabulary->id() . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $original_vocabulary->id(), $edit, t('Save')); $this->assertResponse(200); $this->assertRaw(t('Updated vocabulary %name.', array('%name' => $edit['name'])), 'Vocabulary was edited'); diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php index a3aa448..83f044b 100644 --- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php +++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php @@ -32,7 +32,7 @@ public function normalize($entity, $format = NULL, array $context = array()) { $normalized = array( '_links' => array( 'self' => array( - 'href' => $this->getEntityUri($entity), + 'href' => !$entity->isNew() ? $this->getEntityUri($entity) : '', ), 'type' => array( 'href' => $this->linkManager->getTypeUri($entity->entityType(), $entity->bundle()), @@ -160,8 +160,7 @@ public function denormalize($data, $class, $format = NULL, array $context = arra * The entity URI. */ protected function getEntityUri($entity) { - $uri_info = $entity->uri(); - return url($uri_info['path'], array('absolute' => TRUE)); + return $entity->url('canonical', array('absolute' => TRUE)); } /** diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizeTest.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizeTest.php index eb577e5..396f40a 100644 --- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizeTest.php +++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizeTest.php @@ -21,6 +21,15 @@ public static function getInfo() { } /** + * {@inheritdoc} + */ + function setUp() { + parent::setUp(); + + \Drupal::service('router.builder')->rebuild(); + } + + /** * Tests the normalize function. */ public function testNormalize() { @@ -172,8 +181,7 @@ public function testNormalize() { * The entity URI. */ protected function getEntityUri($entity) { - $entity_uri_info = $entity->uri(); - return url($entity_uri_info['path'], array('absolute' => TRUE)); + return $entity->url('canonical', array('absolute' => TRUE)); } } diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc index 79134ab..4407563 100644 --- a/core/modules/image/image.field.inc +++ b/core/modules/image/image.field.inc @@ -93,6 +93,7 @@ function theme_image_formatter($variables) { // The link path and link options are both optional, but for the options to be // processed, the link path must at least be an empty string. + // @todo Add support for route names. if (isset($variables['path']['path'])) { $path = $variables['path']['path']; $options = isset($variables['path']['options']) ? $variables['path']['options'] : array(); diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php index 57869d4..506f660 100644 --- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php +++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php @@ -40,6 +40,7 @@ * "uuid" = "uuid" * }, * links = { + * "flush-form" = "image.style_flush", * "edit-form" = "image.style_edit" * } * ) diff --git a/core/modules/image/lib/Drupal/image/Form/ImageEffectDeleteForm.php b/core/modules/image/lib/Drupal/image/Form/ImageEffectDeleteForm.php index edc71af..a9ffdde 100644 --- a/core/modules/image/lib/Drupal/image/Form/ImageEffectDeleteForm.php +++ b/core/modules/image/lib/Drupal/image/Form/ImageEffectDeleteForm.php @@ -47,12 +47,7 @@ public function getConfirmText() { * {@inheritdoc} */ public function getCancelRoute() { - return array( - 'route_name' => 'image.style_edit', - 'route_parameters' => array( - 'image_style' => $this->imageStyle->id(), - ), - ); + return $this->imageStyle->urlInfo('edit-form'); } /** @@ -78,12 +73,7 @@ public function buildForm(array $form, array &$form_state, ImageStyleInterface $ public function submitForm(array &$form, array &$form_state) { $this->imageStyle->deleteImageEffect($this->imageEffect); drupal_set_message($this->t('The image effect %name has been deleted.', array('%name' => $this->imageEffect->label()))); - $form_state['redirect_route'] = array( - 'route_name' => 'image.style_edit', - 'route_parameters' => array( - 'image_style' => $this->imageStyle->id(), - ), - ); + $form_state['redirect_route'] = $this->imageStyle->urlInfo('edit-form'); } } diff --git a/core/modules/image/lib/Drupal/image/Form/ImageEffectFormBase.php b/core/modules/image/lib/Drupal/image/Form/ImageEffectFormBase.php index 8ddc426..5323592 100644 --- a/core/modules/image/lib/Drupal/image/Form/ImageEffectFormBase.php +++ b/core/modules/image/lib/Drupal/image/Form/ImageEffectFormBase.php @@ -107,12 +107,7 @@ public function submitForm(array &$form, array &$form_state) { $this->imageStyle->saveImageEffect($form_state['values']); drupal_set_message($this->t('The image effect was successfully applied.')); - $form_state['redirect_route'] = array( - 'route_name' => 'image.style_edit', - 'route_parameters' => array( - 'image_style' => $this->imageStyle->id(), - ), - ); + $form_state['redirect_route'] = $this->imageStyle->urlInfo('edit-form'); } /** diff --git a/core/modules/image/lib/Drupal/image/Form/ImageStyleFormBase.php b/core/modules/image/lib/Drupal/image/Form/ImageStyleFormBase.php index 3ec0b2d..430b802 100644 --- a/core/modules/image/lib/Drupal/image/Form/ImageStyleFormBase.php +++ b/core/modules/image/lib/Drupal/image/Form/ImageStyleFormBase.php @@ -69,13 +69,8 @@ public function form(array $form, array &$form_state) { * {@inheritdoc} */ public function save(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'image.style_edit', - 'route_parameters' => array( - 'image_style' => $this->entity->id(), - ), - ); - return $this->entity->save(); + $this->entity->save(); + $form_state['redirect_route'] = $this->entity->urlInfo('edit-form'); } } diff --git a/core/modules/image/lib/Drupal/image/ImageStyleListController.php b/core/modules/image/lib/Drupal/image/ImageStyleListController.php index cce8dcf..568b5be 100644 --- a/core/modules/image/lib/Drupal/image/ImageStyleListController.php +++ b/core/modules/image/lib/Drupal/image/ImageStyleListController.php @@ -75,13 +75,10 @@ public function buildRow(EntityInterface $entity) { * {@inheritdoc} */ public function getOperations(EntityInterface $entity) { - $uri = $entity->uri('edit-form'); $flush = array( 'title' => t('Flush'), - 'href' => $uri['path'] . '/flush', - 'options' => $uri['options'], 'weight' => 200, - ); + ) + $entity->urlInfo('flush-form'); return parent::getOperations($entity) + array('flush' => $flush); } diff --git a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php index 6252842..9dd9d12 100644 --- a/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php +++ b/core/modules/image/lib/Drupal/image/Plugin/Field/FieldFormatter/ImageFormatter.php @@ -95,7 +95,7 @@ public function viewElements(FieldItemListInterface $items) { $image_link_setting = $this->getSetting('image_link'); // Check if the formatter involves a link. if ($image_link_setting == 'content') { - $uri = $items->getEntity()->uri(); + $uri['path'] = $items->getEntity()->getSystemPath(); } elseif ($image_link_setting == 'file') { $link_file = TRUE; diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php index fc7280e..b0b020f 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php @@ -123,8 +123,7 @@ function testStyle() { // Load the saved image style. $style = entity_load('image_style', $style_name); // Ensure that the image style URI matches our expected path. - $style_uri = $style->uri(); - $style_uri_path = url($style_uri['path'], $style_uri['options']); + $style_uri_path = $style->url(); $this->assertTrue(strpos($style_uri_path, $style_path) !== FALSE, 'The image style URI is correct.'); // Confirm that all effects on the image style have settings on the effect diff --git a/core/modules/language/lib/Drupal/language/Entity/Language.php b/core/modules/language/lib/Drupal/language/Entity/Language.php index d9d6c3f..63e8542 100644 --- a/core/modules/language/lib/Drupal/language/Entity/Language.php +++ b/core/modules/language/lib/Drupal/language/Entity/Language.php @@ -37,6 +37,7 @@ * "uuid" = "uuid" * }, * links = { + * "delete-form" = "language.delete", * "edit-form" = "language.edit" * } * ) diff --git a/core/modules/language/lib/Drupal/language/LanguageListController.php b/core/modules/language/lib/Drupal/language/LanguageListController.php index 601d059..4d047e0 100644 --- a/core/modules/language/lib/Drupal/language/LanguageListController.php +++ b/core/modules/language/lib/Drupal/language/LanguageListController.php @@ -45,16 +45,6 @@ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); $default = language_default(); - // Edit and delete path for Languages entities have a different pattern - // than other config entities. - $path = 'admin/config/regional/language'; - if (isset($operations['edit'])) { - $operations['edit']['href'] = $path . '/edit/' . $entity->id(); - } - if (isset($operations['delete'])) { - $operations['delete']['href'] = $path . '/delete/' . $entity->id(); - } - // Deleting the site default language is not allowed. if ($entity->id() == $default->id) { unset($operations['delete']); diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php index 5e369d5..9a7d93b 100644 --- a/core/modules/menu/lib/Drupal/menu/MenuFormController.php +++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php @@ -205,34 +205,18 @@ public function save(array $form, array &$form_state) { $status = $menu->save(); - $uri = $menu->uri(); + $uri = $menu->urlInfo(); + $edit_link = \Drupal::l($this->t('Edit'), $uri['route_name'], $uri['route_parameters'], $uri['options']); if ($status == SAVED_UPDATED) { drupal_set_message(t('Menu %label has been updated.', array('%label' => $menu->label()))); - watchdog('menu', 'Menu %label has been updated.', array('%label' => $menu->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('menu', 'Menu %label has been updated.', array('%label' => $menu->label()), WATCHDOG_NOTICE, $edit_link); } else { drupal_set_message(t('Menu %label has been added.', array('%label' => $menu->label()))); - watchdog('menu', 'Menu %label has been added.', array('%label' => $menu->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('menu', 'Menu %label has been added.', array('%label' => $menu->label()), WATCHDOG_NOTICE, $edit_link); } - $form_state['redirect_route'] = array( - 'route_name' => 'menu.menu_edit', - 'route_parameters' => array( - 'menu' => $this->entity->id(), - ), - ); - } - - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'menu.delete_menu', - 'route_parameters' => array( - 'menu' => $this->entity->id(), - ), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('edit-form'); } /** diff --git a/core/modules/menu/lib/Drupal/menu/MenuListController.php b/core/modules/menu/lib/Drupal/menu/MenuListController.php index 4c5a408..18a3732 100644 --- a/core/modules/menu/lib/Drupal/menu/MenuListController.php +++ b/core/modules/menu/lib/Drupal/menu/MenuListController.php @@ -43,16 +43,13 @@ public function buildRow(EntityInterface $entity) { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); if (isset($operations['edit'])) { $operations['edit']['title'] = t('Edit menu'); $operations['add'] = array( 'title' => t('Add link'), - 'href' => $uri['path'] . '/add', - 'options' => $uri['options'], 'weight' => 20, - ); + ) + $entity->urlInfo('add-form'); } if (isset($operations['delete'])) { $operations['delete']['title'] = t('Delete menu'); diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index 1ffddee..7887189 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -102,11 +102,14 @@ function menu_entity_info(&$entity_info) { ->setFormClass('edit', 'Drupal\menu\MenuFormController') ->setFormClass('delete', 'Drupal\menu\Form\MenuDeleteForm') ->setListClass('Drupal\menu\MenuListController') + ->setLinkTemplate('add-form', 'menu.link_add') + ->setLinkTemplate('delete-form', 'menu.delete_menu') ->setLinkTemplate('edit-form', 'menu.menu_edit'); $entity_info['menu_link'] ->setFormClass('delete', 'Drupal\menu\Form\MenuLinkDeleteForm') - ->setFormClass('reset', 'Drupal\menu\Form\MenuLinkResetForm'); + ->setFormClass('reset', 'Drupal\menu\Form\MenuLinkResetForm') + ->setLinkTemplate('delete-form', 'menu.link_delete'); } /** 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 bc2c71d..ffe3d37 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php @@ -310,16 +310,4 @@ 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_route'] = array( - 'route_name' => 'menu.link_delete', - 'route_parameters' => array( - 'menu' => $menu_link->id(), - ), - ); - } } diff --git a/core/modules/menu_link/menu_link.module b/core/modules/menu_link/menu_link.module index 6757a4e..dc86f4c 100644 --- a/core/modules/menu_link/menu_link.module +++ b/core/modules/menu_link/menu_link.module @@ -27,7 +27,8 @@ function menu_link_help($path, $arg) { */ function menu_link_uri(MenuLink $menu_link) { return array( - 'path' => $menu_link->link_path, + 'route_name' => $menu_link->route_name, + 'route_parameters' => $menu_link->route_parameters, ); } diff --git a/core/modules/node/lib/Drupal/node/Controller/NodeController.php b/core/modules/node/lib/Drupal/node/Controller/NodeController.php index 126332f..4d62d12 100644 --- a/core/modules/node/lib/Drupal/node/Controller/NodeController.php +++ b/core/modules/node/lib/Drupal/node/Controller/NodeController.php @@ -129,12 +129,12 @@ public function page(NodeInterface $node) { $build = $this->buildPage($node); foreach ($node->uriRelationships() as $rel) { - $uri = $node->uri($rel); + $uri = $node->urlInfo($rel); // Set the node path as the canonical URL to prevent duplicate content. $build['#attached']['drupal_add_html_head_link'][] = array( array( 'rel' => $rel, - 'href' => $this->urlGenerator()->generateFromPath($uri['path'], $uri['options']), + 'href' => $node->url($rel), ) , TRUE); @@ -143,7 +143,7 @@ public function page(NodeInterface $node) { $build['#attached']['drupal_add_html_head_link'][] = array( array( 'rel' => 'shortlink', - 'href' => $this->urlGenerator()->generateFromPath($uri['path'], array_merge($uri['options'], array('alias' => TRUE))), + 'href' => $node->url($rel, array('alias' => TRUE)), ) , TRUE); } diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 0d4683e..f25a99f 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -52,6 +52,7 @@ * permission_granularity = "bundle", * links = { * "canonical" = "node.view", + * "delete-form" = "node.delete_confirm", * "edit-form" = "node.page_edit", * "version-history" = "node.revision_overview", * "admin-form" = "node.type_edit" diff --git a/core/modules/node/lib/Drupal/node/Entity/NodeType.php b/core/modules/node/lib/Drupal/node/Entity/NodeType.php index 99c5267..2b36eb5 100644 --- a/core/modules/node/lib/Drupal/node/Entity/NodeType.php +++ b/core/modules/node/lib/Drupal/node/Entity/NodeType.php @@ -38,7 +38,9 @@ * "uuid" = "uuid" * }, * links = { - * "edit-form" = "node.type_edit" + * "add-form" = "node.add", + * "edit-form" = "node.type_edit", + * "delete-form" = "node.type_delete_confirm" * } * ) */ diff --git a/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php index 644b069..93148d4 100644 --- a/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php +++ b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php @@ -62,8 +62,9 @@ protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); // @todo Convert to getCancelRoute() after http://drupal.org/node/1987778. - $uri = $this->entity->uri(); - $actions['cancel']['#href'] = $this->urlGenerator->generateFromPath($uri['path'], $uri['options']); + $uri = $this->entity->urlInfo(); + $actions['cancel']['#route_name'] = $uri['route_name']; + $actions['cancel']['#route_parameters'] = $uri['route_parameters']; return $actions; } diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php index 1cc58a7..d283f46 100644 --- a/core/modules/node/lib/Drupal/node/NodeFormController.php +++ b/core/modules/node/lib/Drupal/node/NodeFormController.php @@ -483,25 +483,4 @@ public function save(array $form, array &$form_state) { cache_invalidate_tags(array('content' => TRUE)); } - /** - * Overrides Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $destination = array(); - $query = \Drupal::request()->query; - if ($query->has('destination')) { - $destination = drupal_get_destination(); - $query->remove('destination'); - } - $form_state['redirect_route'] = array( - 'route_name' => 'node.delete_confirm', - 'route_parameters' => array( - 'node' => $this->entity->id(), - ), - 'options' => array( - 'query' => $destination, - ), - ); - } - } diff --git a/core/modules/node/lib/Drupal/node/NodeListController.php b/core/modules/node/lib/Drupal/node/NodeListController.php index 122b97f..c4d01ce 100644 --- a/core/modules/node/lib/Drupal/node/NodeListController.php +++ b/core/modules/node/lib/Drupal/node/NodeListController.php @@ -95,11 +95,12 @@ public function buildRow(EntityInterface $entity) { '#mark_type' => node_mark($entity->id(), $entity->getChangedTime()), ); $langcode = $entity->language()->id; - $uri = $entity->uri(); + $uri = $entity->urlInfo(); $row['title']['data'] = array( '#type' => 'link', '#title' => $entity->label(), - '#href' => $uri['path'], + '#route_name' => $uri['route_name'], + '#route_parameters' => $uri['route_parameters'], '#options' => $uri['options'] + ($langcode != Language::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? array('language' => $languages[$langcode]) : array()), '#suffix' => ' ' . drupal_render($mark), ); diff --git a/core/modules/node/lib/Drupal/node/NodeTypeFormController.php b/core/modules/node/lib/Drupal/node/NodeTypeFormController.php index 1c31b3f..cc86095 100644 --- a/core/modules/node/lib/Drupal/node/NodeTypeFormController.php +++ b/core/modules/node/lib/Drupal/node/NodeTypeFormController.php @@ -208,16 +208,4 @@ public function save(array $form, array &$form_state) { $form_state['redirect_route']['route_name'] = 'node.overview_types'; } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'node.type_delete_confirm', - 'route_parameters' => array( - 'node_type' => $this->entity->id(), - ), - ); - } - } diff --git a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php index c3acc23..8a7e30a 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php @@ -243,13 +243,12 @@ public function execute() { $extra = $this->moduleHandler->invokeAll('node_search_result', array($node, $item->langcode)); $language = language_load($item->langcode); - $uri = $node->uri(); $username = array( '#theme' => 'username', '#account' => $node->getAuthor(), ); $results[] = array( - 'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))), + 'link' => $node->url('canonical', array('absolute' => TRUE, 'language' => $language)), 'type' => check_plain($this->entityManager->getStorageController('node_type')->load($node->bundle())->label()), 'title' => $node->label(), 'user' => drupal_render($username), diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkDelete.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkDelete.php index 36dde02..1710a72 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkDelete.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/LinkDelete.php @@ -37,7 +37,7 @@ protected function renderLink($node, ResultRow $values) { } $this->options['alter']['make_link'] = TRUE; - $this->options['alter']['path'] = 'node/' . $node->id() . '/delete'; + $this->options['alter']['path'] = $node->getSystemPath('delete-form'); $this->options['alter']['query'] = drupal_get_destination(); $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php index 979d222..1164125 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php @@ -109,8 +109,7 @@ public function render($row) { $item_text = ''; - $uri = $node->uri(); - $node->link = url($uri['path'], $uri['options'] + array('absolute' => TRUE)); + $node->link = $node->url('canonical', array('absolute' => TRUE)); $node->rss_namespaces = array(); $node->rss_elements = array( array( diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php index c8d554c..5b7389a 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php @@ -111,7 +111,7 @@ protected function getFormSubmitAction(EntityInterface $entity) { */ protected function doTestPublishedStatus() { $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('edit-form'); + $path = $entity->getSystemPath('edit-form'); $languages = language_list(); $actions = array( @@ -126,7 +126,7 @@ protected function doTestPublishedStatus() { if (!empty($status_actions)) { $action = array_shift($status_actions); } - $this->drupalPostForm($uri['path'], array(), $action, array('language' => $languages[$langcode])); + $this->drupalPostForm($path, array(), $action, array('language' => $languages[$langcode])); } $entity = entity_load($this->entityType, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { @@ -143,7 +143,7 @@ protected function doTestPublishedStatus() { */ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityType, $this->entityId, TRUE); - $uri = $entity->uri('edit-form'); + $path = $entity->getSystemPath('edit-form'); $languages = language_list(); $values = array(); @@ -159,7 +159,7 @@ protected function doTestAuthoringInfo() { 'date[date]' => format_date($values[$langcode]['created'], 'custom', 'Y-m-d'), 'date[time]' => format_date($values[$langcode]['created'], 'custom', 'H:i:s'), ); - $this->drupalPostForm($uri['path'], $edit, $this->getFormSubmitAction($entity), array('language' => $languages[$langcode])); + $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity), array('language' => $languages[$langcode])); } $entity = entity_load($this->entityType, $this->entityId, TRUE); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeViewTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeViewTest.php index 550ba44..5f04e45 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeViewTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeViewTest.php @@ -28,8 +28,7 @@ public static function getInfo() { public function testHtmlHeadLinks() { $node = $this->drupalCreateNode(); - $uri = $node->uri(); - $this->drupalGet($uri['path']); + $this->drupalGet($node->getSystemPath()); $result = $this->xpath('//link[@rel = "version-history"]'); $this->assertEqual($result[0]['href'], url("node/{$node->id()}/revisions")); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 28ca4f1..fbc0ba4 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -225,7 +225,10 @@ function node_entity_form_display_alter(EntityFormDisplayInterface $form_display */ function node_uri(EntityInterface $node) { return array( - 'path' => 'node/' . $node->id(), + 'route_name' => 'node.view', + 'route_parameters' => array( + 'node' => $node->id(), + ), ); } @@ -647,8 +650,7 @@ function template_preprocess_node(&$variables) { ); $variables['name'] = drupal_render($username); - $uri = $node->uri(); - $variables['node_url'] = url($uri['path'], $uri['options']); + $variables['node_url'] = empty($node->in_preview) ? $node->url() : ''; $variables['label'] = $variables['elements']['title']; unset($variables['elements']['title']); $variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node); diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php index 6607332..552ef62 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsDynamicValuesTest.php @@ -61,12 +61,11 @@ function setUp() { ); $this->entity = entity_create('entity_test_rev', $values); $this->entity->save(); - $uri = $this->entity->uri(); $this->test = array( 'label' => $this->entity->label(), 'uuid' => $this->entity->uuid(), 'bundle' => $this->entity->bundle(), - 'uri' => $uri['path'], + 'uri' => $this->entity->url(), ); } } diff --git a/core/modules/options/tests/options_test.module b/core/modules/options/tests/options_test.module index 9ff237d..08b533e 100644 --- a/core/modules/options/tests/options_test.module +++ b/core/modules/options/tests/options_test.module @@ -31,10 +31,9 @@ function options_test_allowed_values_callback(FieldDefinitionInterface $field_de function options_test_dynamic_values_callback(FieldDefinitionInterface $field_definition, EntityInterface $entity, &$cacheable) { $cacheable = FALSE; // We need the values of the entity as keys. - $uri = $entity->uri(); return drupal_map_assoc(array( $entity->label(), - $uri['path'], + $entity->url(), $entity->uuid(), $entity->bundle(), )); diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 8e96610..7639a02 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -227,9 +227,8 @@ function path_entity_insert(EntityInterface $entity) { // Only save a non-empty alias. if (!empty($entity->path->alias)) { // Ensure fields for programmatic executions. - $uri = $entity->uri(); $langcode = $entity->language()->id; - \Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode); + \Drupal::service('path.crud')->save($entity->getSystemPath(), $entity->path->alias, $langcode); } } } @@ -248,9 +247,8 @@ function path_entity_update(EntityInterface $entity) { if ($entity->path->alias) { $pid = $entity->path->pid; // Ensure fields for programmatic executions. - $uri = $entity->uri(); $langcode = $entity->language()->id; - \Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode, $pid); + \Drupal::service('path.crud')->save($entity->getSystemPath(), $entity->path->alias, $langcode, $pid); } } } @@ -261,8 +259,7 @@ function path_entity_update(EntityInterface $entity) { function path_entity_predelete(EntityInterface $entity) { if ($entity instanceof ContentEntityInterface && $entity->hasField('path')) { // Delete all aliases associated with this term. - $uri = $entity->uri(); - \Drupal::service('path.crud')->delete(array('source' => $uri['path'])); + \Drupal::service('path.crud')->delete(array('source' => $entity->getSystemPath())); } } diff --git a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php index 26a73ac..05ff927 100644 --- a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php +++ b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php @@ -35,7 +35,8 @@ * "uuid" = "uuid" * }, * links = { - * "edit-form" = "picture.mapping_page_edit" + * "edit-form" = "picture.mapping_page_edit", + * "duplicate-form" = "picture.mapping_page_duplicate" * } * ) */ diff --git a/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php b/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php index ffe4c0c..e391676 100644 --- a/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php +++ b/core/modules/picture/lib/Drupal/picture/PictureMappingListController.php @@ -38,13 +38,10 @@ public function buildRow(EntityInterface $entity) { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); $operations['duplicate'] = array( 'title' => t('Duplicate'), - 'href' => $uri['path'] . '/duplicate', - 'options' => $uri['options'], 'weight' => 15, - ); + ) + $entity->urlInfo('duplicate-form'); return $operations; } diff --git a/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php b/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php index 09f189d..1a4c429 100644 --- a/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php +++ b/core/modules/picture/lib/Drupal/picture/Plugin/Field/FieldFormatter/PictureFormatter.php @@ -116,7 +116,7 @@ public function viewElements(FieldItemListInterface $items) { $elements = array(); // Check if the formatter involves a link. if ($this->getSetting('image_link') == 'content') { - $uri = $items->getEntity()->uri(); + $uri = $items->getEntity()->urlInfo(); } elseif ($this->getSetting('image_link') == 'file') { $link_file = TRUE; diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php index b8a3bfb..e4ebe19 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php @@ -227,8 +227,7 @@ public function testCommentReplyOfRdfaMarkup() { * An array containing information about an anonymous user. */ function _testBasicCommentRdfaMarkup($graph, $comment, $account = array()) { - $uri = $comment->uri(); - $comment_uri = url($uri['path'], $uri['options'] + array('absolute' => TRUE)); + $comment_uri = $comment->url('canonical', array('absolute' => TRUE)); // Comment type. $expected_value = array( diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php index 29d4084..56e2aa5 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php @@ -52,6 +52,7 @@ public function setUp() { parent::setUp(); $this->installSchema('system', array('router')); + \Drupal::service('router.builder')->rebuild(); } /** @@ -109,8 +110,7 @@ protected function createTestField() { * The absolute URI. */ protected function getAbsoluteUri($entity) { - $uri_info = $entity->uri(); - return url($uri_info['path'], array('absolute' => TRUE)); + return $entity->url('canonical', array('absolute' => TRUE)); } } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/StandardProfileTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/StandardProfileTest.php index 0ec0df8..2d4ed43 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/StandardProfileTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/StandardProfileTest.php @@ -171,22 +171,17 @@ public function setUp() { $image_file = $this->article->get('field_image')->entity; $this->imageUri = entity_load('image_style', 'large')->buildUrl($image_file->getFileUri()); // Term. - $term_uri_info = $this->term->uri(); - $this->termUri = url($term_uri_info['path'], array('absolute' => TRUE)); + $this->termUri = $this->term->url('canonical', array('absolute' => TRUE)); // Article. - $article_uri_info = $this->article->uri(); - $this->articleUri = url($article_uri_info['path'], array('absolute' => TRUE)); + $this->articleUri = $this->article->url('canonical', array('absolute' => TRUE)); // Page. - $page_uri_info = $this->page->uri(); - $this->pageUri = url($page_uri_info['path'], array('absolute' => TRUE)); + $this->pageUri = $this->page->url('canonical', array('absolute' => TRUE)); // Author. - $this->authorUri = url('user/' . $this->adminUser->id(), array('absolute' => TRUE)); + $this->authorUri = $this->adminUser->url('canonical', array('absolute' => TRUE)); // Comment. - $article_comment_uri_info = $this->articleComment->uri(); - $this->articleCommentUri = url($article_comment_uri_info['path'], array('absolute' => TRUE)); + $this->articleCommentUri = $this->articleComment->url('canonical', array('absolute' => TRUE)); // Commenter. - $commenter_uri_info = $this->webUser->uri(); - $this->commenterUri = url($commenter_uri_info['path'], array('absolute' => TRUE)); + $this->commenterUri = $this->webUser->url('canonical', array('absolute' => TRUE)); $this->drupalLogout(); } @@ -251,9 +246,7 @@ protected function doFrontPageRdfaTests() { */ protected function doArticleRdfaTests() { // Feed the HTML into the parser. - $uri_info = $this->article->uri(); - $path = $uri_info['path']; - $graph = $this->getRdfGraph($path); + $graph = $this->getRdfGraph($this->article->getSystemPath()); // Type. $this->assertEqual($graph->type($this->articleUri), 'schema:Article', 'Article type was found (schema:Article).'); @@ -290,9 +283,7 @@ protected function doPageRdfaTests() { $node_type->save(); // Feed the HTML into the parser. - $uri_info = $this->page->uri(); - $path = $uri_info['path']; - $graph = $this->getRdfGraph($path); + $graph = $this->getRdfGraph($this->page->getSystemPath()); // Type. $this->assertEqual($graph->type($this->pageUri), 'schema:WebPage', 'Page type was found (schema:WebPage).'); @@ -308,9 +299,7 @@ protected function doUserRdfaTests() { $this->drupalLogin($this->root_user); // Feed the HTML into the parser. - $uri_info = $this->adminUser->uri(); - $path = $uri_info['path']; - $graph = $this->getRdfGraph($path); + $graph = $this->getRdfGraph($this->adminUser->getSystemPath()); // User type. $this->assertEqual($graph->type($this->authorUri), 'schema:Person', "User type was found (schema:Person) on user page."); @@ -330,9 +319,7 @@ protected function doUserRdfaTests() { */ protected function doTermRdfaTests() { // Feed the HTML into the parser. - $uri_info = $this->term->uri(); - $path = $uri_info['path']; - $graph = $this->getRdfGraph($path); + $graph = $this->getRdfGraph($this->term->getSystemPath()); // Term type. $this->assertEqual($graph->type($this->termUri), 'schema:Thing', "Term type was found (schema:Thing) on term page."); @@ -360,8 +347,7 @@ protected function doTermRdfaTests() { * The word to use in the test assertion message. */ protected function assertRdfaCommonNodeProperties($graph, NodeInterface $node, $message_prefix) { - $uri_info = $node->uri(); - $uri = url($uri_info['path'], array('absolute' => TRUE)); + $uri = $node->url('canonical', array('absolute' => TRUE)); // Title. $expected_value = array( diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index c48e683..057af3e 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -7,6 +7,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Template\Attribute; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; /** * Implements hook_help(). @@ -229,8 +230,7 @@ function rdf_comment_load($comments) { ->getPreparedFieldMapping('created'); $comment->rdf_data['date'] = rdf_rdfa_attributes($created_mapping, $comment->created->value); $entity = entity_load($comment->entity_type->value, $comment->entity_id->value); - $uri = $entity->uri(); - $comment->rdf_data['entity_uri'] = url($uri['path']); + $comment->rdf_data['entity_uri'] = $entity->url(); if ($comment->pid->target_id) { $comment->rdf_data['pid_uri'] = url('comment/' . $comment->pid->target_id); } @@ -333,8 +333,9 @@ function rdf_preprocess_node(&$variables) { * Implements hook_preprocess_HOOK() for user templates. */ function rdf_preprocess_user(&$variables) { + /** @var $account \Drupal\user\UserInterface */ $account = $variables['elements']['#user']; - $uri = $account->uri(); + $uri = $account->urlInfo(); $mapping = rdf_get_mapping('user', 'user'); $bundle_mapping = $mapping->getPreparedBundleMapping(); @@ -342,11 +343,11 @@ function rdf_preprocess_user(&$variables) { // will automatically describe the user. if (!empty($bundle_mapping['types'])) { $variables['attributes']['typeof'] = $bundle_mapping['types']; - $variables['attributes']['about'] = url($uri['path'], $uri['options']); + $variables['attributes']['about'] = $account->url(); } // If we are on the user account page, add the relationship between the // sioc:UserAccount and the foaf:Person who holds the account. - if (current_path() == $uri['path']) { + if (\Drupal::request()->attributes->get(RouteObjectInterface::ROUTE_NAME) == $uri['route_name']) { // Adds the markup for username as language neutral literal, see // rdf_preprocess_username(). $name_mapping = $mapping->getPreparedFieldMapping('name'); @@ -354,7 +355,7 @@ function rdf_preprocess_user(&$variables) { $username_meta = array( '#tag' => 'meta', '#attributes' => array( - 'about' => url($uri['path'], $uri['options']), + 'about' => $account->url(), 'property' => $name_mapping['properties'], 'content' => $account->getUsername(), 'lang' => '', @@ -431,13 +432,12 @@ function rdf_preprocess_comment(&$variables) { $mapping = rdf_get_mapping('comment', $comment->bundle()); $bundle_mapping = $mapping->getPreparedBundleMapping(); - if (!empty($bundle_mapping['types'])) { + if (!empty($bundle_mapping['types']) && !isset($comment->in_preview)) { // Adds RDFa markup to the comment container. The about attribute specifies // the URI of the resource described within the HTML element, while the // typeof attribute indicates its RDF type (e.g., sioc:Post, foaf:Document, // and so on.) - $uri = $comment->uri(); - $variables['attributes']['about'] = url($uri['path'], $uri['options']); + $variables['attributes']['about'] = $comment->url(); $variables['attributes']['typeof'] = $bundle_mapping['types']; } diff --git a/core/modules/rest/lib/Drupal/rest/Routing/ResourceRoutes.php b/core/modules/rest/lib/Drupal/rest/Routing/ResourceRoutes.php index ef1b93f..a902bc4 100644 --- a/core/modules/rest/lib/Drupal/rest/Routing/ResourceRoutes.php +++ b/core/modules/rest/lib/Drupal/rest/Routing/ResourceRoutes.php @@ -62,7 +62,7 @@ public static function create(ContainerInterface $container) { */ public function routes() { $routes = array(); - $enabled_resources = $this->config->get('rest.settings')->load()->get('resources'); + $enabled_resources = $this->config->get('rest.settings')->load()->get('resources') ?: array(); // Iterate over all enabled resource plugins. foreach ($enabled_resources as $id => $enabled_methods) { diff --git a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php index 11359b4..9f8d413 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php @@ -57,6 +57,7 @@ public function testPatchUpdate() { $patch_entity = entity_create($entity_type, $patch_values); // We don't want to overwrite the UUID. unset($patch_entity->uuid); + $patch_entity->save(); $serialized = $serializer->serialize($patch_entity, $this->defaultFormat); // Update the entity over the REST API. diff --git a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php index d0419d4..d7bbb18 100644 --- a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php +++ b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php @@ -33,7 +33,11 @@ * }, * admin_permission = "administer search", * links = { - * "edit-form" = "search.edit" + * "edit-form" = "search.edit", + * "delete-form" = "search.delete", + * "enable" = "search.enable", + * "disable" = "search.disable", + * "set-default" = "search.set_default" * }, * config_prefix = "search.page", * entity_keys = { diff --git a/core/modules/search/lib/Drupal/search/Form/SearchPageFormBase.php b/core/modules/search/lib/Drupal/search/Form/SearchPageFormBase.php index 1e574c3..0001554 100644 --- a/core/modules/search/lib/Drupal/search/Form/SearchPageFormBase.php +++ b/core/modules/search/lib/Drupal/search/Form/SearchPageFormBase.php @@ -184,18 +184,6 @@ public function save(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'search.delete', - 'route_parameters' => array( - 'search_page' => $this->entity->id(), - ), - ); - } - - /** - * {@inheritdoc} - */ protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); if ($this->entity->isDefaultSearch()) { diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php index 59f8287..7b2017b 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php @@ -40,7 +40,8 @@ * "label" = "title" * }, * links = { - * "edit-form" = "/admin/config/user-interface/shortcut/link/{shortcut}" + * "delete-form" = "shortcut.link_delete", + * "edit-form" = "shortcut.link_edit" * } * ) */ diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php index ef2c480..c9dee35 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php @@ -37,7 +37,9 @@ * "uuid" = "uuid" * }, * links = { - * "edit-form" = "shortcut.set_customize" + * "customize-form" = "shortcut.set_customize", + * "delete-form" = "shortcut.set_delete", + * "edit-form" = "shortcut.set_edit" * } * ) */ diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php index 7179886..5f72679 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php @@ -167,14 +167,4 @@ public function save(array $form, array &$form_state) { ); } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'shortcut.link_delete', - 'route_parameters' => array('shortcut' => $this->entity->id()), - ); - } - } diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetFormController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetFormController.php index 404dd1d..5360b5f 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetFormController.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetFormController.php @@ -83,24 +83,7 @@ public function save(array $form, array &$form_state) { else { drupal_set_message(t('Updated set name to %set-name.', array('%set-name' => $entity->label()))); } - $form_state['redirect_route'] = array( - 'route_name' => 'shortcut.set_customize', - 'route_parameters' => array( - 'shortcut_set' => $this->entity->id(), - ), - ); - } - - /** - * Overrides \Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'shortcut.set_delete', - 'route_parameters' => array( - 'shortcut_set' => $this->entity->id(), - ), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('customize-form'); } } diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php index 179992c..6741ed2 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutSetListController.php @@ -28,17 +28,14 @@ public function buildHeader() { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); if (isset($operations['edit'])) { $operations['edit']['title'] = t('Edit shortcut set'); - $operations['edit']['href'] = $uri['path'] . '/edit'; } $operations['list'] = array( 'title' => t('List links'), - 'href' => $uri['path'], - ); + ) + $entity->urlInfo('customize-form'); return $operations; } diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutSetsTest.php b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutSetsTest.php index 06493ec..9d39537 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutSetsTest.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutSetsTest.php @@ -108,7 +108,7 @@ function testShortcutSetRename() { function testShortcutSetRenameAlreadyExists() { $set = $this->generateShortcutSet($this->randomName()); $existing_label = $this->set->label(); - $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/edit', array('label' => $existing_label), t('Save')); + $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id(), array('label' => $existing_label), t('Save')); $this->assertRaw(t('The shortcut set %name already exists. Choose another name.', array('%name' => $existing_label))); $set = shortcut_set_load($set->id()); $this->assertNotEqual($set->label(), $existing_label, format_string('The shortcut set %title cannot be renamed to %new-title because a shortcut set with that title already exists.', array('%title' => $set->label(), '%new-title' => $existing_label))); diff --git a/core/modules/shortcut/shortcut.routing.yml b/core/modules/shortcut/shortcut.routing.yml index a702470..9ec8d64 100644 --- a/core/modules/shortcut/shortcut.routing.yml +++ b/core/modules/shortcut/shortcut.routing.yml @@ -23,7 +23,7 @@ shortcut.set_add: _entity_create_access: 'shortcut_set' shortcut.set_edit: - path: '/admin/config/user-interface/shortcut/manage/{shortcut_set}/edit' + path: '/admin/config/user-interface/shortcut/manage/{shortcut_set}' defaults: _entity_form: 'shortcut_set.edit' _title: 'Edit shortcut set' @@ -39,7 +39,7 @@ shortcut.link_add_inline: _csrf_token: 'TRUE' shortcut.set_customize: - path: '/admin/config/user-interface/shortcut/manage/{shortcut_set}' + path: '/admin/config/user-interface/shortcut/manage/{shortcut_set}/customize' defaults: _entity_form: 'shortcut_set.customize' _title: 'List links' diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php index 451de06..6bf2310 100644 --- a/core/modules/system/entity.api.php +++ b/core/modules/system/entity.api.php @@ -699,10 +699,9 @@ function hook_entity_field_info_alter(&$info, $entity_type) { * The entity on which the linked operations will be performed. */ function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) { - $uri = $entity->uri(); $operations['translate'] = array( 'title' => t('Translate'), - 'href' => $uri['path'] . '/translate', + 'href' => $entity->getSystemPath() . '/translate', 'weight' => 50, ); } diff --git a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php index 35ad4ab..8dbdf5b 100644 --- a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php +++ b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php @@ -36,6 +36,7 @@ * }, * admin_permission = "administer site configuration", * links = { + * "delete-form" = "system.date_format_delete", * "edit-form" = "system.date_format_edit" * } * ) diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityOperationsTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityOperationsTest.php index 776021d..fa75e9f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityOperationsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityOperationsTest.php @@ -49,8 +49,7 @@ public function testEntityOperationAlter() { $this->drupalGet('admin/people/roles'); $roles = user_roles(); foreach ($roles as $role) { - $uri = $role->uri(); - $this->assertLinkByHref($uri['path'] . '/test_operation'); + $this->assertLinkByHref($role->url() . '/test_operation'); $this->assertLink(format_string('Test Operation: @label', array('@label' => $role->label()))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php deleted file mode 100644 index 381d8b0..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php +++ /dev/null @@ -1,40 +0,0 @@ - 'Entity URI', - 'description' => 'Tests default URI functionality.', - 'group' => 'Entity API', - ); - } - - public function setUp() { - parent::setUp(); - $this->installSchema('system', array('variable', 'url_alias')); - } - - /** - * Tests that an entity without a URI callback uses the default URI. - */ - function testDefaultUri() { - // Create a test entity. - $entity = entity_create('entity_test_no_label', array('name' => 'test', 'user_id' => 1)); - $entity->save(); - $uri = $entity->uri(); - $expected_path = 'entity/entity_test_no_label/' . $entity->id(); - $this->assertEqual(url($uri['path'], $uri['options']), url($expected_path), 'Entity without URI callback returns expected URI.'); - } - -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php index 9ab9103..b891b73 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php @@ -74,7 +74,7 @@ function testBreadCrumbs() { $trail += array( 'admin/structure/taxonomy/manage/tags' => t('Tags'), ); - $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/edit', $trail); + $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/overview', $trail); $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/fields', $trail); $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/add', $trail); diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index ee69cbb..91504fb 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -454,10 +454,9 @@ function entity_test_entity_predelete(EntityInterface $entity) { * Implements hook_entity_operation_alter(). */ function entity_test_entity_operation_alter(array &$operations, EntityInterface $entity) { - $uri = $entity->uri(); $operations['test_operation'] = array( 'title' => format_string('Test Operation: @label', array('@label' => $entity->label())), - 'href' => $uri['path'] . '/test_operation', + 'href' => $entity->url() . '/test_operation', 'weight' => 50, ); } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php index b28a6d9..32e0e9c 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php @@ -44,6 +44,7 @@ * bundle_entity_type = "taxonomy_vocabulary", * links = { * "canonical" = "taxonomy.term_page", + * "delete-form" = "taxonomy.term_delete", * "edit-form" = "taxonomy.term_edit", * "admin-form" = "taxonomy.overview_terms" * }, diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php index 12facd4..7857c07 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php @@ -36,7 +36,11 @@ * "uuid" = "uuid" * }, * links = { - * "edit-form" = "taxonomy.overview_terms" + * "add-form" = "taxonomy.term_add", + * "delete-form" = "taxonomy.vocabulary_delete", + * "reset" = "taxonomy.vocabulary_reset", + * "overview-form" = "taxonomy.overview_terms", + * "edit-form" = "taxonomy.vocabulary_edit" * } * ) */ diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/OverviewTerms.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/OverviewTerms.php index b680223..8e5bcce 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/OverviewTerms.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/OverviewTerms.php @@ -199,8 +199,8 @@ public function buildForm(array $form, array &$form_state, VocabularyInterface $ ), ); foreach ($current_page as $key => $term) { - $uri = $term->uri(); - $edit_uri = $term->uri('edit-form'); + /** @var $term \Drupal\Core\Entity\EntityInterface */ + $uri = $term->urlInfo(); $form['terms'][$key]['#term'] = $term; $indentation = array(); if (isset($term->depth) && $term->depth > 0) { @@ -213,7 +213,8 @@ public function buildForm(array $form, array &$form_state, VocabularyInterface $ '#prefix' => !empty($indentation) ? drupal_render($indentation) : '', '#type' => 'link', '#title' => $term->label(), - '#href' => $uri['path'], + '#route_name' => $uri['route_name'], + '#route_parameters' => $uri['route_parameters'], ); if ($taxonomy_vocabulary->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE && count($tree) > 1) { $parent_fields = TRUE; @@ -256,21 +257,18 @@ public function buildForm(array $form, array &$form_state, VocabularyInterface $ $operations = array( 'edit' => array( 'title' => $this->t('edit'), - 'href' => $edit_uri['path'], 'query' => $destination, - ), + ) + $term->urlInfo('edit-form'), 'delete' => array( 'title' => $this->t('delete'), - 'href' => $uri['path'] . '/delete', 'query' => $destination, - ), + ) + $term->urlInfo('delete-form'), ); if ($this->moduleHandler->moduleExists('content_translation') && content_translation_translate_access($term)) { $operations['translate'] = array( 'title' => $this->t('translate'), - 'href' => $uri['path'] . '/translations', 'query' => $destination, - ); + ) + $term->urlInfo('drupal:content-translation-overview'); } $form['terms'][$key]['operations'] = array( '#type' => 'operations', @@ -454,10 +452,9 @@ public function submitForm(array &$form, array &$form_state) { * Redirects to confirmation form for the reset action. */ public function submitReset(array &$form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'taxonomy.vocabulary_reset', - 'route_parameters' => array('taxonomy_vocabulary' => $form_state['taxonomy']['vocabulary']->id()), - ); + /** @var $vocabulary \Drupal\taxonomy\VocabularyInterface */ + $vocabulary = $form_state['taxonomy']['vocabulary']; + $form_state['redirect_route'] = $vocabulary->urlInfo('reset'); } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php index 9f9e255..e18adaa 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php @@ -60,12 +60,7 @@ public function getQuestion() { * {@inheritdoc} */ public function getCancelRoute() { - return array( - 'route_name' => 'taxonomy.overview_terms', - 'route_parameters' => array( - 'taxonomy_vocabulary' => $this->entity->id(), - ), - ); + return $this->entity->urlInfo('overview-form'); } /** @@ -89,10 +84,7 @@ public function save(array $form, array &$form_state) { $this->termStorage->resetWeights($this->entity->id()); drupal_set_message($this->t('Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label()))); watchdog('taxonomy', 'Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label()), WATCHDOG_NOTICE); - $form_state['redirect_route'] = array( - 'route_name' => 'taxonomy.vocabulary_edit', - 'route_parameters' => array('taxonomy_vocabulary' => $this->entity->id()), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('edit-form'); } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php index f931321..f7d0325 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -37,12 +37,14 @@ public function viewElements(FieldItemListInterface $items) { ); } else { + /** @var $term \Drupal\taxonomy\TermInterface */ $term = $item->entity; - $uri = $term->uri(); + $uri = $term->urlInfo(); $elements[$delta] = array( '#type' => 'link', '#title' => $term->label(), - '#href' => $uri['path'], + '#route_name' => $uri['route_name'], + '#route_parameters' => $uri['route_parameters'], '#options' => $uri['options'], ); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php index 7044964..927370d 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php @@ -34,9 +34,7 @@ public function viewElements(FieldItemListInterface $items) { if ($item->target_id) { $value = $item->entity->label(); - $uri = $item->entity->uri(); - $uri['options']['absolute'] = TRUE; - $domain = url($uri['path'], $uri['options']); + $domain = $item->entity->url('canonical', array('absolute' => TRUE)); } else { $value = $item->entity->label(); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/Taxonomy.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/Taxonomy.php index 1c5b79c..905cdcf 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/Taxonomy.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/Taxonomy.php @@ -83,8 +83,7 @@ protected function renderLink($data, ResultRow $values) { 'vid' => $this->getValue($values, 'vid'), )); $this->options['alter']['make_link'] = TRUE; - $uri = $term->uri(); - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $term->getSystemPath(); } if (!empty($this->options['convert_spaces'])) { diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php index 925d83c..07db84e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php @@ -229,19 +229,4 @@ public function save(array $form, array &$form_state) { $form_state['tid'] = $term->id(); } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $destination = array(); - if ($this->getRequest()->query->has('destination')) { - $destination = drupal_get_destination(); - } - $form_state['redirect_route'] = array( - 'route_name' => 'taxonomy.term_delete', - 'route_parameters' => array('taxonomy_term' => $this->entity->id()), - 'options' => array('query' => $destination), - ); - } - } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php index ba951a1..172eecb 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php @@ -36,8 +36,7 @@ function entityFormSave(array $form, array &$form_state) { // We need a redirect here, otherwise we would get an access denied page, // since the current URL would be preserved and we would try to add a // translation for a language that already has a translation. - $uri = $entity->uri('edit-form'); - $form_state['redirect'] = $uri['path']; + $form_state['redirect_route'] = $entity->urlInfo('edit-form'); } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermIndentationTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermIndentationTest.php index 94abb71..5020cc2 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermIndentationTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermIndentationTest.php @@ -52,7 +52,7 @@ function testTermIndentation() { ); // Submit the edited form and check for HTML indentation element presence. - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid'), $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid') . '/overview', $edit, t('Save')); $this->assertPattern('|
 
|'); // Check explicitly that term 2's parent is term 1. @@ -67,7 +67,7 @@ function testTermIndentation() { 'terms[tid:' . $term2->id() . ':0][weight]' => 1, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid'), $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid' ) . '/overview', $edit, t('Save')); // All terms back at the root level, no identation should be present. $this->assertNoPattern('|
 
|'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php index 9201129..c74efbe 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php @@ -49,7 +49,7 @@ function testTermLanguage() { $edit = array( 'default_language[language_show]' => TRUE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); // Add a term. $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); @@ -85,7 +85,7 @@ function testDefaultTermLanguage() { 'default_language[langcode]' => 'bb', 'default_language[language_show]' => TRUE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); $this->assertOptionSelected('edit-langcode', 'bb', 'The expected langcode was selected.'); @@ -94,7 +94,7 @@ function testDefaultTermLanguage() { 'default_language[langcode]' => 'current_interface', 'default_language[language_show]' => TRUE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); $this->drupalGet('aa/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); $this->assertOptionSelected('edit-langcode', 'aa', "The expected langcode, 'aa', was selected."); $this->drupalGet('bb/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); @@ -112,7 +112,7 @@ function testDefaultTermLanguage() { 'default_language[langcode]' => 'site_default', 'default_language[language_show]' => TRUE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); $this->assertOptionSelected('edit-langcode', 'cc', "The expected langcode, 'cc', was selected."); } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php index 410ff5a..83c42c6 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php @@ -311,7 +311,7 @@ function testTermInterface() { $this->assertNotNull($term, 'Term found in database.'); // Submitting a term takes us to the add page; we need the List page. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id()); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); // Test edit link as accessed from Taxonomy administration pages. // Because Simpletest creates its own database when running tests, we know @@ -330,7 +330,7 @@ function testTermInterface() { $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save')); // Check that the term is still present at admin UI after edit. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id()); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); $this->assertText($edit['name'], 'The randomly generated term name is present.'); $this->assertLink(t('edit')); @@ -383,7 +383,7 @@ function testTermReorder() { drupal_static_reset('taxonomy_get_treeterms'); list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->id(), 0, NULL, TRUE); - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id()); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); // Each term has four hidden fields, "tid:1:0[tid]", "tid:1:0[parent]", // "tid:1:0[depth]", and "tid:1:0[weight]". Change the order to term2, @@ -413,7 +413,7 @@ function testTermReorder() { $this->assertEqual($terms[1]->parents, array($term2->id()), 'Term 3 was made a child of term 2.'); $this->assertEqual($terms[2]->tid, $term1->id(), 'Term 1 was moved below term 2.'); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), array(), t('Reset to alphabetical')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array(), t('Reset to alphabetical')); // Submit confirmation form. $this->drupalPostForm(NULL, array(), t('Reset to alphabetical')); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php index 238df1e..b0a2865 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php @@ -117,12 +117,12 @@ function testTranslateLinkVocabularyAdminPage() { $untranslatable_tid = $this->createEntity(array(), $this->langcodes[0], $untranslatable_vocabulary->id()); // Verify translation links. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id()); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); $this->assertResponse(200, 'The translatable vocabulary page was found.'); $this->assertLinkByHref('term/' . $translatable_tid . '/translations', 0, 'The translations link exists for a translatable vocabulary.'); $this->assertLinkByHref('term/' . $translatable_tid . '/edit', 0, 'The edit link exists for a translatable vocabulary.'); - $this->drupalGet('admin/structure/taxonomy/manage/' . $untranslatable_vocabulary->id()); + $this->drupalGet('admin/structure/taxonomy/manage/' . $untranslatable_vocabulary->id() . '/overview'); $this->assertResponse(200); $this->assertLinkByHref('term/' . $untranslatable_tid . '/edit'); $this->assertNoLinkByHref('term/' . $untranslatable_tid . '/translations'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php index fb24bf3..5503589 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php @@ -63,7 +63,7 @@ function testVocabularyLanguage() { $this->drupalPostForm(NULL, $edit, t('Save')); // Check the language on the edit page. - $this->drupalGet('admin/structure/taxonomy/manage/' . $vid . '/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/' . $vid); $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The vocabulary language was correctly selected.'); // Change the language and save again. @@ -72,7 +72,7 @@ function testVocabularyLanguage() { $this->drupalPostForm(NULL, $edit, t('Save')); // Check again the language on the edit page. - $this->drupalGet('admin/structure/taxonomy/manage/' . $vid . '/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/' . $vid); $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The vocabulary language was correctly selected.'); } @@ -92,7 +92,7 @@ function testVocabularyDefaultLanguageForTerms() { $this->drupalPostForm('admin/structure/taxonomy/add', $edit, t('Save')); // Check that the vocabulary was actually created. - $this->drupalGet('admin/structure/taxonomy/manage/' . $edit['vid'] . '/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/' . $edit['vid']); $this->assertResponse(200, 'The vocabulary has been created.'); // Check that the language settings were saved. @@ -109,14 +109,14 @@ function testVocabularyDefaultLanguageForTerms() { 'default_language[langcode]' => 'aa', 'default_language[language_show]' => FALSE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid, $edit, t('Save')); // And check again the settings and also the interface. $language_settings = language_get_default_configuration('taxonomy_term', $vid); $this->assertEqual($language_settings['langcode'], 'aa', 'The langcode was saved.'); $this->assertFalse($language_settings['language_show'], 'The visibility setting was saved.'); - $this->drupalGet('admin/structure/taxonomy/manage/' . $vid . '/edit'); + $this->drupalGet('admin/structure/taxonomy/manage/' . $vid); $this->assertOptionSelected('edit-default-language-langcode', 'aa', 'The correct default language for the terms of this vocabulary is selected.'); $this->assertNoFieldChecked('edit-default-language-language-show', 'Show language selection option is not checked.'); @@ -126,7 +126,7 @@ function testVocabularyDefaultLanguageForTerms() { 'default_language[langcode]' => 'authors_default', 'default_language[language_show]' => FALSE, ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid . '/edit', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid, $edit, t('Save')); // Check that we have the new settings. $new_settings = language_get_default_configuration('taxonomy_term', $vid); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php index cf9042d..a3d4fbe 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php @@ -142,7 +142,7 @@ function testTaxonomyAdminDeletingVocabulary() { // Delete the vocabulary. $edit = array(); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/edit', $edit, t('Delete')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id(), $edit, t('Delete')); $this->assertRaw(t('Are you sure you want to delete the vocabulary %name?', array('%name' => $vocabulary->name)), '[confirm deletion] Asks for confirmation.'); $this->assertText(t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'), '[confirm deletion] Inform that all terms will be deleted.'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php index 05ffbf4..6a02f1e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php @@ -20,6 +20,7 @@ class VocabularyFormController extends EntityFormController { */ public function form(array $form, array &$form_state) { $vocabulary = $this->entity; + $form['#title'] = $this->t('Edit vocabulary'); $form['name'] = array( '#type' => 'textfield', @@ -128,19 +129,19 @@ public function save(array $form, array &$form_state) { // Prevent leading and trailing spaces in vocabulary names. $vocabulary->name = trim($vocabulary->name); - switch ($vocabulary->save()) { + $status = $vocabulary->save(); + $uri = $vocabulary->urlInfo(); + $edit_link = \Drupal::l($this->t('edit'), $uri['route_name'], $uri['route_parameters'], $uri['options']); + switch ($status) { case SAVED_NEW: drupal_set_message($this->t('Created new vocabulary %name.', array('%name' => $vocabulary->name))); - watchdog('taxonomy', 'Created new vocabulary %name.', array('%name' => $vocabulary->name), WATCHDOG_NOTICE, l($this->t('edit'), 'admin/structure/taxonomy/manage/' . $vocabulary->id() . '/edit')); - $form_state['redirect_route'] = array( - 'route_name' => 'taxonomy.overview_terms', - 'route_parameters' => array('taxonomy_vocabulary' => $vocabulary->id()), - ); + watchdog('taxonomy', 'Created new vocabulary %name.', array('%name' => $vocabulary->name), WATCHDOG_NOTICE, $edit_link); + $form_state['redirect_route'] = $vocabulary->urlInfo('overview-form'); break; case SAVED_UPDATED: drupal_set_message($this->t('Updated vocabulary %name.', array('%name' => $vocabulary->name))); - watchdog('taxonomy', 'Updated vocabulary %name.', array('%name' => $vocabulary->name), WATCHDOG_NOTICE, l($this->t('edit'), 'admin/structure/taxonomy/manage/' . $vocabulary->id() . '/edit')); + watchdog('taxonomy', 'Updated vocabulary %name.', array('%name' => $vocabulary->name), WATCHDOG_NOTICE, $edit_link); $form_state['redirect_route']['route_name'] = 'taxonomy.vocabulary_list'; break; } @@ -149,15 +150,4 @@ public function save(array $form, array &$form_state) { $form_state['vid'] = $vocabulary->id(); } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $vocabulary = $this->getEntity($form_state); - $form_state['redirect_route'] = array( - 'route_name' => 'taxonomy.vocabulary_delete', - 'route_parameters' => array('taxonomy_vocabulary' => $vocabulary->id()), - ); - } - } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php index ff93ede..104b360 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyListController.php @@ -32,25 +32,19 @@ public function getFormId() { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); if (isset($operations['edit'])) { $operations['edit']['title'] = t('edit vocabulary'); - $operations['edit']['href'] = $uri['path'] . '/edit'; } $operations['list'] = array( 'title' => t('list terms'), - 'href' => $uri['path'], - 'options' => $uri['options'], 'weight' => 0, - ); + ) + $entity->urlInfo('overview-form'); $operations['add'] = array( 'title' => t('add terms'), - 'href' => $uri['path'] . '/add', - 'options' => $uri['options'], 'weight' => 10, - ); + ) + $entity->urlInfo('add-form'); unset($operations['delete']); return $operations; diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index fd08344..3ffef31 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -125,7 +125,10 @@ function taxonomy_entity_bundle_info() { */ function taxonomy_term_uri($term) { return array( - 'path' => 'taxonomy/term/' . $term->id(), + 'route_name' => 'taxonomy.term_page', + 'route_parameters' => array( + 'taxonomy_term' => $term->id(), + ), ); } @@ -382,8 +385,7 @@ function template_preprocess_taxonomy_term(&$variables) { $variables['term'] = $variables['elements']['#term']; $term = $variables['term']; - $uri = $term->uri(); - $variables['url'] = url($uri['path'], $uri['options']); + $variables['url'] = $term->url(); // We use name here because that is what appears in the UI. $variables['name'] = check_plain($term->label()); $variables['page'] = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term); diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc index 79d4472..d177e1c 100644 --- a/core/modules/taxonomy/taxonomy.pages.inc +++ b/core/modules/taxonomy/taxonomy.pages.inc @@ -19,12 +19,11 @@ function taxonomy_term_page(Term $term) { $build['#attached']['drupal_add_feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->label()); foreach ($term->uriRelationships() as $rel) { - $uri = $term->uri($rel); // Set the term path as the canonical URL to prevent duplicate content. $build['#attached']['drupal_add_html_head_link'][] = array( array( 'rel' => $rel, - 'href' => url($uri['path'], $uri['options']), + 'href' => $term->url($rel), ), TRUE, ); @@ -34,7 +33,7 @@ function taxonomy_term_page(Term $term) { $build['#attached']['drupal_add_html_head_link'][] = array( array( 'rel' => 'shortlink', - 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE))), + 'href' => $term->url($rel, array('alias' => TRUE)), ), TRUE, ); diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index b5f3c2e..63b374d 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -39,10 +39,10 @@ taxonomy.vocabulary_add: _entity_create_access: 'taxonomy_vocabulary' taxonomy.vocabulary_edit: - path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/edit' + path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}' defaults: _entity_form: 'taxonomy_vocabulary.default' - _title: 'Edit vocabulary' + _title_callback: '\Drupal\taxonomy\Controller\TaxonomyController::vocabularyTitle' requirements: _entity_access: 'taxonomy_vocabulary.update' @@ -76,7 +76,7 @@ taxonomy.autocomplete_vid: _permission: 'access content' taxonomy.overview_terms: - path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}' + path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/overview' defaults: _form: 'Drupal\taxonomy\Form\OverviewTerms' _title_callback: 'Drupal\taxonomy\Controller\TaxonomyController::vocabularyTitle' diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc index ce77a7c..eec9d73 100644 --- a/core/modules/taxonomy/taxonomy.tokens.inc +++ b/core/modules/taxonomy/taxonomy.tokens.inc @@ -112,8 +112,7 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options = break; case 'url': - $uri = $term->uri(); - $replacements[$original] = url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE))); + $replacements[$original] = $term->url('canonical', array('absolute' => TRUE)); break; case 'node-count': diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc index d114050..bc041a0 100644 --- a/core/modules/taxonomy/taxonomy.views.inc +++ b/core/modules/taxonomy/taxonomy.views.inc @@ -464,33 +464,6 @@ function taxonomy_field_views_data_views_data_alter(array &$data, FieldInterface } /** - * Helper function to set a breadcrumb for taxonomy. - */ -function views_taxonomy_set_breadcrumb(&$breadcrumb, &$argument) { - if (empty($argument->options['set_breadcrumb'])) { - return; - } - - $args = $argument->view->args; - $parents = taxonomy_get_parents_all($argument->argument); - foreach (array_reverse($parents) as $parent) { - // Unfortunately parents includes the current argument. Skip. - if ($parent->id() == $argument->argument) { - continue; - } - if (!empty($argument->options['use_taxonomy_term_path'])) { - $path = $parent->uri(); - $path = $path['path']; - } - else { - $args[$argument->position] = $parent->id(); - $path = $argument->view->getUrl($args); - } - $breadcrumb[$path] = check_plain($parent->label()); - } -} - -/** * Implements hook_views_plugins_argument_validator_alter(). * * Extend the generic entity argument validator. diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php index 320d7f0..e4b5f04 100644 --- a/core/modules/user/lib/Drupal/user/Entity/Role.php +++ b/core/modules/user/lib/Drupal/user/Entity/Role.php @@ -36,7 +36,9 @@ * "label" = "label" * }, * links = { - * "edit-form" = "user.role_edit" + * "delete-form" = "user.role_delete", + * "edit-form" = "user.role_edit", + * "edit-permissions-form" = "user.admin_permission" * } * ) */ diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php index 2954df5..f9db482 100644 --- a/core/modules/user/lib/Drupal/user/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Entity/User.php @@ -44,7 +44,8 @@ * links = { * "canonical" = "user.view", * "edit-form" = "user.edit", - * "admin-form" = "user.account_settings" + * "admin-form" = "user.account_settings", + * "cancel-form" = "user.cancel" * } * ) */ diff --git a/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php b/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php index e1a3c6a..5d14e09 100644 --- a/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php +++ b/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php @@ -144,8 +144,9 @@ public function buildForm(array $form, array &$form_state) { $form = parent::buildForm($form, $form_state); // @todo Convert to getCancelRoute() after https://drupal.org/node/1987896. - $uri = $this->entity->uri(); - $form['actions']['cancel']['#href'] = $uri['path']; + $uri = $this->entity->urlInfo(); + $form['actions']['cancel']['#route_name'] = $uri['route_name']; + $form['actions']['cancel']['#route_parameters'] = $uri['route_parameters']; return $form; } diff --git a/core/modules/user/lib/Drupal/user/Form/UserPermissionsRoleSpecificForm.php b/core/modules/user/lib/Drupal/user/Form/UserPermissionsRoleSpecificForm.php index 19d5dce..6345a06 100644 --- a/core/modules/user/lib/Drupal/user/Form/UserPermissionsRoleSpecificForm.php +++ b/core/modules/user/lib/Drupal/user/Form/UserPermissionsRoleSpecificForm.php @@ -7,6 +7,8 @@ namespace Drupal\user\Form; +use Drupal\user\RoleInterface; + /** * Provides the user permissions administration form for a specific role. */ @@ -15,15 +17,15 @@ class UserPermissionsRoleSpecificForm extends UserPermissionsForm { /** * The specific role for this form. * - * @var string + * @var \Drupal\user\RoleInterface */ - protected $roleId; + protected $userRole; /** * {@inheritdoc} */ protected function getRoles() { - return array($this->roleId => $this->roleStorage->load($this->roleId)); + return array($this->userRole->id() => $this->userRole); } /** @@ -32,8 +34,8 @@ protected function getRoles() { * @param string $role_id * The user role ID used for this form. */ - public function buildForm(array $form, array &$form_state, $role_id = NULL) { - $this->roleId = $role_id; + public function buildForm(array $form, array &$form_state, RoleInterface $user_role = NULL) { + $this->userRole = $user_role; return parent::buildForm($form, $form_state); } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php index 5c75d85..a84b640 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php @@ -89,8 +89,7 @@ protected function renderLink(EntityInterface $entity, ResultRow $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('View'); $this->options['alter']['make_link'] = TRUE; - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $entity->getSystemPath(); return $text; } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php index 5d21ccf..eae22a0 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php @@ -28,8 +28,7 @@ protected function renderLink(EntityInterface $entity, ResultRow $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('Cancel account'); - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path'] . '/cancel'; + $this->options['alter']['path'] = $entity->getSystemPath('cancel-form'); $this->options['alter']['query'] = drupal_get_destination(); return $text; diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php index 6442691..6afa9ff 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php @@ -28,8 +28,7 @@ protected function renderLink(EntityInterface $entity, ResultRow $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('Edit'); - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path'] . '/edit'; + $this->options['alter']['path'] = $entity->getSystemPath('edit-form'); $this->options['alter']['query'] = drupal_get_destination(); return $text; diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/User.php index c40f204..a362979 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/User.php @@ -65,8 +65,7 @@ public function buildOptionsForm(&$form, &$form_state) { protected function renderLink($data, ResultRow $values) { if (!empty($this->options['link_to_user']) && $this->view->getUser()->hasPermission('access user profiles') && ($entity = $this->getEntity($values)) && $data !== NULL && $data !== '') { $this->options['alter']['make_link'] = TRUE; - $uri = $entity->uri(); - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $entity->getSystemPath(); } return $data; } diff --git a/core/modules/user/lib/Drupal/user/ProfileTranslationController.php b/core/modules/user/lib/Drupal/user/ProfileTranslationController.php index 9667170..fdcf151 100644 --- a/core/modules/user/lib/Drupal/user/ProfileTranslationController.php +++ b/core/modules/user/lib/Drupal/user/ProfileTranslationController.php @@ -36,8 +36,7 @@ function entityFormSave(array $form, array &$form_state) { // We need a redirect here, otherwise we would get an access denied page // since the current URL would be preserved and we would try to add a // translation for a language that already has a translation. - $uri = $entity->uri(); - $form_state['redirect'] = $uri['path']; + $form_state['redirect_route'] = $entity->urlInfo(); } } } diff --git a/core/modules/user/lib/Drupal/user/RegisterFormController.php b/core/modules/user/lib/Drupal/user/RegisterFormController.php index d1e7e71..ba95171 100644 --- a/core/modules/user/lib/Drupal/user/RegisterFormController.php +++ b/core/modules/user/lib/Drupal/user/RegisterFormController.php @@ -115,9 +115,8 @@ public function save(array $form, array &$form_state) { $account->password = $pass; // New administrative account without notification. - $uri = $account->uri(); if ($admin && !$notify) { - drupal_set_message($this->t('Created a new user account for %name. No e-mail has been sent.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->getUsername()))); + drupal_set_message($this->t('Created a new user account for %name. No e-mail has been sent.', array('@url' => $account->url(), '%name' => $account->getUsername()))); } // No e-mail verification required; log in user immediately. elseif (!$admin && !\Drupal::config('user.settings')->get('verify_mail') && $account->isActive()) { @@ -129,13 +128,13 @@ public function save(array $form, array &$form_state) { // No administrator approval required. elseif ($account->isActive() || $notify) { if (!$account->getEmail() && $notify) { - drupal_set_message($this->t('The new user %name was created without an email address, so no welcome message was sent.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->getUsername()))); + drupal_set_message($this->t('The new user %name was created without an email address, so no welcome message was sent.', array('@url' => $account->url(), '%name' => $account->getUsername()))); } else { $op = $notify ? 'register_admin_created' : 'register_no_approval_required'; if (_user_mail_notify($op, $account)) { if ($notify) { - drupal_set_message($this->t('A welcome message with further instructions has been e-mailed to the new user %name.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->getUsername()))); + drupal_set_message($this->t('A welcome message with further instructions has been e-mailed to the new user %name.', array('@url' => $account->url(), '%name' => $account->getUsername()))); } else { drupal_set_message($this->t('A welcome message with further instructions has been sent to your e-mail address.')); diff --git a/core/modules/user/lib/Drupal/user/RoleFormController.php b/core/modules/user/lib/Drupal/user/RoleFormController.php index 01076dd..0cf8cd4 100644 --- a/core/modules/user/lib/Drupal/user/RoleFormController.php +++ b/core/modules/user/lib/Drupal/user/RoleFormController.php @@ -66,26 +66,19 @@ public function save(array $form, array &$form_state) { // Prevent leading and trailing spaces in role names. $entity->set('label', trim($entity->label())); - $uri = $entity->uri(); - if ($entity->save() == SAVED_UPDATED) { + $status = $entity->save(); + + $uri = $entity->urlInfo(); + $edit_link = \Drupal::l($this->t('Edit'), $uri['route_name'], $uri['route_parameters'], $uri['options']); + if ($status == SAVED_UPDATED) { drupal_set_message($this->t('Role %label has been updated.', array('%label' => $entity->label()))); - watchdog('user', 'Role %label has been updated.', array('%label' => $entity->label()), WATCHDOG_NOTICE, l($this->t('Edit'), $uri['path'])); + watchdog('user', 'Role %label has been updated.', array('%label' => $entity->label()), WATCHDOG_NOTICE, $edit_link); } else { drupal_set_message($this->t('Role %label has been added.', array('%label' => $entity->label()))); - watchdog('user', 'Role %label has been added.', array('%label' => $entity->label()), WATCHDOG_NOTICE, l($this->t('Edit'), $uri['path'])); + watchdog('user', 'Role %label has been added.', array('%label' => $entity->label()), WATCHDOG_NOTICE, $edit_link); } $form_state['redirect_route']['route_name'] = 'user.role_list'; } - /** - * {@inheritdoc} - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'user.role_delete', - 'route_parameters' => array('user_role' => $this->entity->id()), - ); - } - } diff --git a/core/modules/user/lib/Drupal/user/RoleListController.php b/core/modules/user/lib/Drupal/user/RoleListController.php index 4aa4f52..c2cd9b9 100644 --- a/core/modules/user/lib/Drupal/user/RoleListController.php +++ b/core/modules/user/lib/Drupal/user/RoleListController.php @@ -44,14 +44,11 @@ public function buildRow(EntityInterface $entity) { public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $operations['permissions'] = array( - 'title' => t('Edit permissions'), - 'href' => 'admin/people/permissions/' . $entity->id(), - 'weight' => 20, - ); - // Built-in roles could not be deleted or disabled. - if (in_array($entity->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { - unset($operations['delete']); + if ($entity->hasLinkTemplate('edit-permissions-form')) { + $operations['permissions'] = array( + 'title' => t('Edit permissions'), + 'weight' => 20, + ) + $entity->urlInfo('edit-permissions-form'); } return $operations; } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php b/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php index 76bf0e9..70ef130 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserEntityCallbacksTest.php @@ -21,6 +21,11 @@ class UserEntityCallbacksTest extends WebTestBase { */ public static $modules = array('user'); + /** + * @var \Drupal\Core\Entity\EntityInterface + */ + protected $account; + public static function getInfo() { return array( 'name' => 'User entity callback tests', @@ -52,7 +57,6 @@ function testLabelCallback() { * Test URI callback. */ function testUriCallback() { - $uri = $this->account->uri(); - $this->assertEqual('user/' . $this->account->id(), $uri['path'], 'Correct user URI.'); + $this->assertEqual('user/' . $this->account->id(), $this->account->getSystemPath(), 'Correct user URI.'); } } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 235d8fd..6bf593f 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -151,7 +151,10 @@ function user_entity_bundle_info() { */ function user_uri($user) { return array( - 'path' => 'user/' . $user->id(), + 'route_name' => 'user.view', + 'route_parameters' => array( + 'user' => $user->id(), + ), ); } diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index bbc2053..f59aabc 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -68,12 +68,12 @@ user.admin_permissions: _permission: 'administer permissions' user.admin_permission: - path: '/admin/people/permissions/{role_id}' + path: '/admin/people/permissions/{user_role}' defaults: _form: '\Drupal\user\Form\UserPermissionsRoleSpecificForm' _title: 'Edit role' requirements: - _permission: 'administer permissions' + _entity_access: 'user_role.update' user.multiple_cancel_confirm: path: '/admin/people/cancel' diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php index 7ac209b..bc47c37 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/EntityLabel.php @@ -106,12 +106,12 @@ public function render(ResultRow $values) { return; } + /** @var $entity \Drupal\Core\Entity\EntityInterface */ $entity = $this->loadedReferencers[$type][$value]; if (!empty($this->options['link_to_entity'])) { - $uri = $entity->uri(); $this->options['alter']['make_link'] = TRUE; - $this->options['alter']['path'] = $uri['path']; + $this->options['alter']['path'] = $entity->getSystemPath(); } return $this->sanitizeValue($entity->label()); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php index d812284..4357d2e 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php @@ -50,7 +50,7 @@ public function validateView(array $form, array &$form_state); * @param array $form_state * The current state of the wizard form. * - * @return \Drupal\views\ViewExecutable + * @return \Drupal\views\ViewStorageInterface * The created view object. * * @throws \Drupal\views\Plugin\views\wizard\WizardException diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php index d71c283..934944f 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php @@ -54,6 +54,7 @@ protected function setUp() { $this->installSchema('system', array('menu_router', 'router')); $this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy')); $this->installConfig(array('taxonomy')); + \Drupal::service('router.builder')->rebuild(); } /** diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Analyze.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Analyze.php index cc798fe..41a7d94 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Analyze.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Analyze.php @@ -58,10 +58,9 @@ public function buildForm(array $form, array &$form_state) { * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array('view' => $form_state['view']->id()), - ); + /** @var $view \Drupal\views_ui\ViewUI */ + $view = $form_state['view']; + $form_state['redirect_route'] = $view->urlInfo('edit-form'); } } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php index 82d796c..82be91c 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php @@ -32,6 +32,7 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, array &$form_state) { + /** @var $view \Drupal\views\ViewStorageInterface */ $view = $form_state['view']; $display_id = $form_state['display_id']; @@ -148,6 +149,7 @@ public function buildForm(array $form, array &$form_state) { * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { + /** @var $view \Drupal\views_ui\ViewUI */ $view = $form_state['view']; $order = array(); @@ -190,11 +192,8 @@ public function submitForm(array &$form, array &$form_state) { // Store in cache. $view->cacheSet(); - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.operation', - 'route_parameters' => array('view' => $view->id(), 'operation' => 'edit'), - 'options' => array('fragment' => 'views-tab-default'), - ); + $form_state['redirect_route'] = $view->urlInfo('edit-form'); + $form_state['redirect_route']['options']['fragment'] = 'views-tab-default'; } } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/BreakLockForm.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/BreakLockForm.php index 8d0b48d..2af481f 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/Form/BreakLockForm.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/BreakLockForm.php @@ -85,12 +85,7 @@ public function getDescription() { * {@inheritdoc} */ public function getCancelRoute() { - return array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array( - 'view' => $this->entity->id(), - ), - ); + return $this->entity->urlInfo('edit-form'); } /** @@ -116,10 +111,7 @@ public function buildForm(array $form, array &$form_state) { */ public function submit(array $form, array &$form_state) { $this->tempStore->delete($this->entity->id()); - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array('view' => $this->entity->id()), - ); + $form_state['redirect_route'] = $this->entity->urlInfo('edit-form'); drupal_set_message($this->t('The lock has been broken and you may now edit this view.')); } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php index f02e145..7477184 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php @@ -181,7 +181,9 @@ public function validate(array $form, array &$form_state) { */ public function submit(array $form, array &$form_state) { try { - $view = $form_state['wizard_instance']->createView($form, $form_state); + /** @var $wizard \Drupal\views\Plugin\views\wizard\WizardInterface */ + $wizard = $form_state['wizard_instance']; + $view = $wizard->createView($form, $form_state); } // @todo Figure out whether it really makes sense to throw and catch exceptions on the wizard. catch (WizardException $e) { @@ -191,10 +193,7 @@ public function submit(array $form, array &$form_state) { } $view->save(); - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array('view' => $view->id()), - ); + $form_state['redirect_route'] = $view->urlInfo('edit-form'); } /** diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php index 4071738..6d9e85b 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php @@ -72,8 +72,7 @@ public function submit(array $form, array &$form_state) { $this->entity->save(); // Redirect the user to the view admin form. - $uri = $this->entity->uri(); - $form_state['redirect'] = $uri['path']; + $form_state['redirect_route'] = $this->entity->urlInfo('edit-form'); return $this->entity; } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php index 05c11cc..622af72 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php @@ -122,7 +122,7 @@ public function form(array $form, array &$form_state) { $lock_message_substitutions = array( '!user' => drupal_render($username), '!age' => format_interval(REQUEST_TIME - $view->lock->updated), - '!break' => url('admin/structure/views/view/' . $view->id() . '/break-lock'), + '!break' => $view->url('break-lock'), ); $form['locked'] = array( '#type' => 'container', @@ -626,10 +626,7 @@ public function submitDisplayDelete($form, &$form_state) { // Redirect to the top-level edit page. The first remaining display will // become the active display. - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array('view' => $view->id()), - ); + $form_state['redirect_route'] = $view->urlInfo('edit-form'); } /** @@ -687,8 +684,7 @@ public function renderDisplayTop(ViewUI $view) { ), 'clone' => array( 'title' => $this->t('Clone view'), - 'href' => "admin/structure/views/view/{$view->id()}/clone", - ), + ) + $view->urlInfo('clone'), 'reorder' => array( 'title' => $this->t('Reorder displays'), 'href' => "admin/structure/views/nojs/reorder-displays/{$view->id()}/$display_id", @@ -700,8 +696,7 @@ public function renderDisplayTop(ViewUI $view) { if ($view->access('delete')) { $element['extra_actions']['#links']['delete'] = array( 'title' => $this->t('Delete view'), - 'href' => "admin/structure/views/view/{$view->id()}/delete", - ); + ) + $view->urlInfo('delete-form'); } // Let other modules add additional links here. diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewFormControllerBase.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewFormControllerBase.php index 2151a89..38e8150 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewFormControllerBase.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewFormControllerBase.php @@ -120,10 +120,10 @@ public function getDisplayTabs(ViewUI $view) { '#weight' => $display['position'], '#link' => array( 'title' => $this->getDisplayLabel($view, $id), - 'href' => 'admin/structure/views/view/' . $view->id() . '/edit/' . $id, 'localized_options' => array(), - ), + ) + $view->urlInfo('edit-display-form'), ); + $tabs[$id]['#link']['route_parameters']['display_id'] = $id; if (!empty($display['deleted'])) { $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-deleted-link'; } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php index 363a285..62ffce8 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewListController.php @@ -136,22 +136,19 @@ public function buildHeader() { */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); - $uri = $entity->uri(); - $operations['clone'] = array( - 'title' => $this->t('Clone'), - 'href' => $uri['path'] . '/clone', - 'options' => $uri['options'], - 'weight' => 15, - ); + if ($entity->hasLinkTemplate('clone')) { + $operations['clone'] = array( + 'title' => $this->t('Clone'), + 'weight' => 15, + ) + $entity->urlInfo('clone'); + } // Add AJAX functionality to enable/disable operations. foreach (array('enable', 'disable') as $op) { if (isset($operations[$op])) { - $operations[$op]['route_name'] = 'views_ui.operation'; - $operations[$op]['route_parameters'] = array('view' => $entity->id(), 'op' => $op); - // @todo Remove this when entity links use route_names. - unset($operations[$op]['href']); + $operations[$op]['route_name'] = "views_ui.$op"; + $operations[$op]['route_parameters'] = array('view' => $entity->id()); // Enable and disable operations should use AJAX. $operations[$op]['attributes']['class'][] = 'use-ajax'; diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php index 4533f76..ae9f4da 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php @@ -90,7 +90,9 @@ public function form(array $form, array &$form_state) { '#markup' => $view->renderPreview($this->displayID, $args), ); } - $form['#action'] = url('admin/structure/views/view/' . $view->id() .'/preview/' . $this->displayID); + $uri = $view->urlInfo('preview-form'); + $uri['route_parameters']['display_id'] = $this->displayID; + $form['#action'] = \Drupal::url($uri['route_name'], $uri['route_parameters'], $uri['options']); return $form; } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php index 1f5766d..90c68de 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php @@ -101,7 +101,7 @@ class ViewUI implements ViewStorageInterface { /** * The View storage object. * - * @var \Drupal\views\Entity\View + * @var \Drupal\views\ViewStorageInterface */ protected $storage; @@ -278,10 +278,7 @@ public function standardCancel($form, &$form_state) { $this->cacheSet(); } - $form_state['redirect_route'] = array( - 'route_name' => 'views_ui.edit', - 'route_parameters' => array('view' => $this->id()), - ); + $form_state['redirect_route'] = $this->urlInfo('edit-form'); } /** @@ -886,8 +883,15 @@ public function save() { /** * Implements \Drupal\Core\Entity\EntityInterface::uri(). */ - public function uri() { - return $this->storage->uri(); + public function urlInfo($rel = 'edit-form') { + return $this->storage->urlInfo($rel); + } + + /** + * {@inheritdoc} + */ + public function getSystemPath($rel = 'edit-form') { + return $this->storage->getSystemPath($rel); } /** @@ -1160,4 +1164,18 @@ public function referencedEntities() { return $this->storage->referencedEntities(); } + /** + * {@inheritdoc} + */ + public function url($rel = 'edit-form', $options = array()) { + return $this->storage->url($rel, $options); + } + + /** + * {@inheritdoc} + */ + public function hasLinkTemplate($key) { + return $this->storage->hasLinkTemplate($key); + } + } diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module index f90508c..5d7ffdf 100644 --- a/core/modules/views_ui/views_ui.module +++ b/core/modules/views_ui/views_ui.module @@ -73,7 +73,14 @@ function views_ui_entity_info(&$entity_info) { ->setFormClass('delete', 'Drupal\views_ui\ViewDeleteFormController') ->setFormClass('break_lock', 'Drupal\views_ui\Form\BreakLockForm') ->setListClass('Drupal\views_ui\ViewListController') - ->setLinkTemplate('edit-form', 'views_ui.edit'); + ->setLinkTemplate('edit-form', 'views_ui.edit') + ->setLinkTemplate('edit-display-form', 'views_ui.edit_display') + ->setLinkTemplate('preview-form', 'views_ui.preview') + ->setLinkTemplate('clone', 'views_ui.clone') + ->setLinkTemplate('delete-form', 'views_ui.delete') + ->setLinkTemplate('enable', 'views_ui.enable') + ->setLinkTemplate('disable', 'views_ui.disable') + ->setLinkTemplate('break-lock', 'views_ui.break_lock'); } /** diff --git a/core/modules/views_ui/views_ui.routing.yml b/core/modules/views_ui/views_ui.routing.yml index 03c6b95..ee6ad6c 100644 --- a/core/modules/views_ui/views_ui.routing.yml +++ b/core/modules/views_ui/views_ui.routing.yml @@ -46,14 +46,23 @@ views_ui.reports_plugins: requirements: _permission: 'administer views' -views_ui.operation: - path: '/admin/structure/views/view/{view}/{op}' +views_ui.enable: + path: '/admin/structure/views/view/{view}/enable' defaults: _controller: '\Drupal\views_ui\Controller\ViewsUIController::ajaxOperation' + op: enable + requirements: + _permission: 'administer views' + _csrf_token: 'TRUE' + +views_ui.disable: + path: '/admin/structure/views/view/{view}/disable' + defaults: + _controller: '\Drupal\views_ui\Controller\ViewsUIController::ajaxOperation' + op: disable requirements: _permission: 'administer views' _csrf_token: 'TRUE' - op: 'enable|disable' views_ui.clone: path: '/admin/structure/views/view/{view}/clone' diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityUrlTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityUrlTest.php new file mode 100644 index 0000000..96f482d --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Entity/EntityUrlTest.php @@ -0,0 +1,340 @@ + 'EntityInterface URL test', + 'description' => 'Unit test the EntityInterface URL methods.', + 'group' => 'Entity', + ); + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); + + $container = new ContainerBuilder(); + $container->set('entity.manager', $this->entityManager); + \Drupal::setContainer($container); + } + + /** + * Tests the urlInfo() method. + * + * @covers ::urlInfo() + * + * @dataProvider providerTestUrlInfo + */ + public function testUrlInfo($entity_class, $link_template, $expected) { + /** @var $entity \Drupal\Core\Entity\EntityInterface */ + $entity = new $entity_class(array('id' => 'test_entity_id'), 'test_entity_type'); + + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->once()) + ->method('getLinkTemplates') + ->will($this->returnValue(array( + 'edit-form' => 'test_entity_type.edit', + ))); + + $this->entityManager + ->expects($this->any()) + ->method('getDefinition') + ->with('test_entity_type') + ->will($this->returnValue($entity_type)); + + // If no link template is given, call without a value to test the default. + if ($link_template) { + $uri = $entity->urlInfo($link_template); + } + else { + $uri = $entity->urlInfo(); + } + + if ($expected) { + $this->assertSame($expected, $uri['route_name']); + $this->assertSame($entity, $uri['options']['entity']); + } + else { + $this->assertEmpty($uri); + } + } + + /** + * Provides test data for testUrlInfo(). + */ + public function providerTestUrlInfo() { + return array( + array('Drupal\Tests\Core\Entity\TestEntity', 'canonical', FALSE), + array('Drupal\Tests\Core\Entity\TestEntity', 'edit-form', 'test_entity_type.edit'), + array('Drupal\Tests\Core\Entity\TestEntity', FALSE, FALSE), + array('Drupal\Tests\Core\Entity\TestConfigEntity', 'canonical', FALSE), + array('Drupal\Tests\Core\Entity\TestConfigEntity', 'edit-form', 'test_entity_type.edit'), + // Test that overriding the default $rel parameter works. + array('Drupal\Tests\Core\Entity\TestConfigEntity', FALSE, 'test_entity_type.edit'), + ); + } + + /** + * Tests the urlInfo() method when an entity is still "new". + * + * @see \Drupal\Core\Entity\EntityInterface::isNew() + * + * @covers ::urlInfo() + * + * @expectedException \Drupal\Core\Entity\EntityMalformedException + */ + public function testUrlInfoForNewEntity() { + $entity = new TestEntity(array(), 'test_entity_type'); + $entity->urlInfo(); + } + + /** + * Tests the url() method. + * + * @covers ::url() + */ + public function testUrl() { + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->exactly(3)) + ->method('getLinkTemplates') + ->will($this->returnValue(array( + 'canonical' => 'test_entity_type.view', + ))); + + $this->entityManager + ->expects($this->exactly(4)) + ->method('getDefinition') + ->with('test_entity_type') + ->will($this->returnValue($entity_type)); + + $invalid_entity = new TestEntity(array(), 'test_entity_type'); + $this->assertSame('', $invalid_entity->url()); + + $no_link_entity = new TestEntity(array('id' => 'test_entity_id'), 'test_entity_type'); + $this->assertSame('', $no_link_entity->url('banana')); + + $valid_entity = new TestEntity(array('id' => 'test_entity_id'), 'test_entity_type'); + $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); + $valid_entity->setUrlGenerator($url_generator); + $url_generator->expects($this->exactly(2)) + ->method('generateFromRoute') + ->will($this->returnValueMap(array( + array( + 'test_entity_type.view', + array('test_entity_type' => 'test_entity_id'), + array('entity_type' => 'test_entity_type', 'entity' => $valid_entity), + '/entity/test_entity_type/test_entity_id', + ), + array( + 'test_entity_type.view', + array('test_entity_type' => 'test_entity_id'), + array('absolute' => TRUE, 'entity_type' => 'test_entity_type', 'entity' => $valid_entity), + 'http://drupal/entity/test_entity_type/test_entity_id', + ), + ))); + + $this->assertSame('/entity/test_entity_type/test_entity_id', $valid_entity->url()); + $this->assertSame('http://drupal/entity/test_entity_type/test_entity_id', $valid_entity->url('canonical', array('absolute' => TRUE))); + } + + /** + * Tests the url() method for "admin-form". + * + * @covers ::urlRouteParameters() + */ + public function testUrlForAdminForm() { + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->once()) + ->method('getLinkTemplates') + ->will($this->returnValue(array( + 'admin-form' => 'test_entity_type.admin_form', + ))); + $entity_type->expects($this->exactly(2)) + ->method('getBundleEntityType') + ->will($this->returnValue('test_entity_type_bundle')); + + $this->entityManager + ->expects($this->exactly(3)) + ->method('getDefinition') + ->with('test_entity_type') + ->will($this->returnValue($entity_type)); + + $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); + $url_generator->expects($this->once()) + ->method('generateFromRoute') + ->with('test_entity_type.admin_form', array( + 'test_entity_type_bundle' => 'test_entity_bundle', + 'test_entity_type' => 'test_entity_id', + )) + ->will($this->returnValue('entity/test_entity_type/test_entity_bundle/test_entity_id')); + + $entity = new TestEntityWithBundle(array('id' => 'test_entity_id', 'bundle' => 'test_entity_bundle'), 'test_entity_type'); + $entity->setUrlGenerator($url_generator); + + $this->assertSame('entity/test_entity_type/test_entity_bundle/test_entity_id', $entity->url('admin-form')); + } + + /** + * Tests the getSystemPath() method. + * + * @covers ::getSystemPath() + */ + public function testGetSystemPath() { + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->exactly(2)) + ->method('getLinkTemplates') + ->will($this->returnValue(array( + 'canonical' => 'test_entity_type.view', + ))); + + $this->entityManager + ->expects($this->exactly(3)) + ->method('getDefinition') + ->with('test_entity_type') + ->will($this->returnValue($entity_type)); + + $no_link_entity = new TestEntity(array('id' => 'test_entity_id'), 'test_entity_type'); + $this->assertSame('', $no_link_entity->getSystemPath('banana')); + + $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); + $url_generator->expects($this->once()) + ->method('getPathFromRoute') + ->with('test_entity_type.view', array('test_entity_type' => 'test_entity_id')) + ->will($this->returnValue('entity/test_entity_type/test_entity_id')); + + $valid_entity = new TestEntity(array('id' => 'test_entity_id'), 'test_entity_type'); + $valid_entity->setUrlGenerator($url_generator); + + $this->assertSame('entity/test_entity_type/test_entity_id', $valid_entity->getSystemPath()); + } + + /** + * Tests the retrieval of link templates. + * + * @covers ::hasLinkTemplate() + * @covers ::linkTemplates() + * + * @dataProvider providerTestLinkTemplates + */ + public function testLinkTemplates($entity_class, $expected) { + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->exactly(2)) + ->method('getLinkTemplates') + ->will($this->returnValue(array( + 'canonical' => 'test_entity_type.view', + ))); + + $this->entityManager + ->expects($this->exactly(2)) + ->method('getDefinition') + ->with('test_entity_type') + ->will($this->returnValue($entity_type)); + + $entity = new $entity_class(array('id' => 'test_entity_id'), 'test_entity_type'); + $this->assertSame($expected['canonical'], $entity->hasLinkTemplate('canonical')); + $this->assertSame($expected['bananas'], $entity->hasLinkTemplate('bananas')); + } + + /** + * Provides test data for testLinkTemplates(). + */ + public function providerTestLinkTemplates() { + return array( + array('Drupal\Tests\Core\Entity\TestEntity', array( + 'canonical' => TRUE, + 'bananas' => FALSE, + )), + array('Drupal\Tests\Core\Entity\TestEntityWithTemplates', array( + 'canonical' => TRUE, + 'bananas' => TRUE, + )), + ); + } + +} + +class TestConfigEntity extends ConfigEntityBase { +} + +class TestEntity extends Entity { + + /** + * Sets the URL generator. + * + * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator + * + * @return $this + */ + public function setUrlGenerator(UrlGeneratorInterface $url_generator) { + $this->urlGenerator = $url_generator; + return $this; + } + +} + +class TestEntityWithTemplates extends TestEntity { + + /** + * {@inheritdoc} + */ + protected function linkTemplates() { + $templates = parent::linkTemplates(); + $templates['bananas'] = 'test_entity_type.bananas'; + return $templates; + } + +} + +class TestEntityWithBundle extends TestEntity { + + /** + * The entity bundle. + * + * @var string + */ + protected $bundle; + + /** + * {@inheritdoc} + */ + public function bundle() { + return $this->bundle; + } + +}