Commit 20b6bb32 authored by effulgentsia's avatar effulgentsia

Issue #2606398 by blackra, chx, anil280988, sdstyles, xjm: Add...

Issue #2606398 by blackra, chx, anil280988, sdstyles, xjm: Add EntityInterface::toUrl() and EntityInterface::toLink() and mark urlInfo(), url() and link() as deprecated
parent db73cab1
......@@ -387,6 +387,7 @@ public function urlInfo($rel = 'edit-form', array $options = []) {
* {@inheritdoc}
*/
public function url($rel = 'edit-form', $options = array()) {
// Do not remove this override: the default value of $rel is different.
return parent::url($rel, $options);
}
......@@ -394,9 +395,19 @@ public function url($rel = 'edit-form', $options = array()) {
* {@inheritdoc}
*/
public function link($text = NULL, $rel = 'edit-form', array $options = []) {
// Do not remove this override: the default value of $rel is different.
return parent::link($text, $rel, $options);
}
/**
* {@inheritdoc}
*/
public function toUrl($rel = 'edit-form', array $options = []) {
// Unless language was already provided, avoid setting an explicit language.
$options += ['language' => NULL];
return parent::toUrl($rel, $options);
}
/**
* {@inheritdoc}
*/
......
......@@ -173,6 +173,13 @@ public function label() {
* {@inheritdoc}
*/
public function urlInfo($rel = 'canonical', array $options = []) {
return $this->toUrl($rel, $options);
}
/**
* {@inheritdoc}
*/
public function toUrl($rel = 'canonical', array $options = []) {
if ($this->id() === NULL) {
throw new EntityMalformedException(sprintf('The "%s" entity cannot have a URI as it does not have an ID', $this->getEntityTypeId()));
}
......@@ -252,26 +259,33 @@ protected function linkTemplates() {
* {@inheritdoc}
*/
public function link($text = NULL, $rel = 'canonical', array $options = []) {
if (is_null($text)) {
return $this->toLink($text, $rel, $options)->toString();
}
/**
* {@inheritdoc}
*/
public function toLink($text = NULL, $rel = 'canonical', array $options = []) {
if (!isset($text)) {
$text = $this->label();
}
$url = $this->urlInfo($rel);
$url = $this->toUrl($rel);
$options += $url->getOptions();
$url->setOptions($options);
return (new Link($text, $url))->toString();
return new Link($text, $url);
}
/**
* {@inheritdoc}
*/
public function url($rel = 'canonical', $options = array()) {
// While self::urlInfo() will throw an exception if the entity is new,
// While self::toUrl() will throw an exception if the entity has no id,
// the expected result for a URL is always a string.
if ($this->isNew() || !$this->hasLinkTemplate($rel)) {
if ($this->id() === NULL || !$this->hasLinkTemplate($rel)) {
return '';
}
$uri = $this->urlInfo($rel);
$uri = $this->toUrl($rel);
$options += $uri->getOptions();
$uri->setOptions($options);
return $uri->toString();
......
......@@ -101,7 +101,29 @@ public function bundle();
public function label();
/**
* Gets the URI elements of the entity.
* Gets the URL object for the 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 \Drupal\Core\Url
* The URL object.
*
* @deprecated in Drupal 8.0.0, intended to be removed in Drupal 9.0.0
* Use toUrl() instead.
*
* @see \Drupal\Core\Entity\EntityInterface::toUrl
*/
public function urlInfo($rel = 'canonical', array $options = array());
/**
* Gets the URL object for the entity.
*
* The entity must have an id already. Content entities usually get their IDs
* by saving them.
*
* URI templates might be set in the links array in an annotation, for
* example:
......@@ -128,8 +150,12 @@ public function label();
* the available options.
*
* @return \Drupal\Core\Url
* The URL object.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
* @throws \Drupal\Core\Entity\Exception\UndefinedLinkTemplateException
*/
public function urlInfo($rel = 'canonical', array $options = array());
public function toUrl($rel = 'canonical', array $options = array());
/**
* Gets the public URL for this entity.
......@@ -142,11 +168,16 @@ public function urlInfo($rel = 'canonical', array $options = array());
*
* @return string
* The URL for this entity.
*
* @deprecated in Drupal 8.0.0, intended to be removed in Drupal 9.0.0
* Please use toUrl() instead.
*
* @see \Drupal\Core\Entity\EntityInterface::toUrl
*/
public function url($rel = 'canonical', $options = array());
/**
* Generates the HTML for a link to this entity.
* Deprecated way of generating a link to the entity. See toLink().
*
* @param string|null $text
* (optional) The link text for the anchor tag as a translated string.
......@@ -159,9 +190,34 @@ public function url($rel = 'canonical', $options = array());
*
* @return string
* An HTML string containing a link to the entity.
*
* @deprecated in Drupal 8.0.0, intended to be removed in Drupal 9.0.0
* Please use toLink() instead.
*
* @see \Drupal\Core\Entity\EntityInterface::toLink
*/
public function link($text = NULL, $rel = 'canonical', array $options = []);
/**
* Generates the HTML for a link to this entity.
*
* @param string|null $text
* (optional) The link text for the anchor tag as a translated string.
* If NULL, it will use the entity's label. Defaults to NULL.
* @param string $rel
* (optional) The link relationship type. Defaults to 'canonical'.
* @param array $options
* See \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute() for
* the available options.
*
* @return \Drupal\Core\Link
* A Link to the entity.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
* @throws \Drupal\Core\Entity\Exception\UndefinedLinkTemplateException
*/
public function toLink($text = NULL, $rel = 'canonical', array $options = []);
/**
* Indicates if a link template exists for a given key.
*
......
......@@ -1031,6 +1031,13 @@ public function urlInfo($rel = 'edit-form', array $options = []) {
return $this->storage->urlInfo($rel, $options);
}
/**
* {@inheritdoc}
*/
public function toUrl($rel = 'edit-form', array $options = []) {
return $this->storage->toUrl($rel, $options);
}
/**
* {@inheritdoc}
*/
......@@ -1038,6 +1045,13 @@ public function link($text = NULL, $rel = 'edit-form', array $options = []) {
return $this->storage->link($text, $rel, $options);
}
/**
* {@inheritdoc}
*/
public function toLink($text = NULL, $rel = 'edit-form', array $options = []) {
return $this->storage->toLink($text, $rel, $options);
}
/**
* {@inheritdoc}
*/
......
......@@ -57,6 +57,8 @@ protected function setUp() {
}
/**
* Tests for the Entity::link() method
*
* @covers ::link
*
* @dataProvider providerTestLink
......@@ -98,7 +100,7 @@ public function testLink($entity_label, $link_text, $expected_text, $link_rel =
/** @var \Drupal\Core\Entity\Entity $entity */
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [
['id' => $entity_id, 'label' => $entity_label, 'langcode' => 'es'],
$entity_type_id
$entity_type_id,
]);
$expected_link = Link::createFromRoute(
......@@ -116,6 +118,64 @@ public function testLink($entity_label, $link_text, $expected_text, $link_rel =
$this->assertSame($expected, $entity->link($link_text, $link_rel, $link_options));
}
/**
* Tests for the Entity::toLink() method
*
* @covers ::toLink
*
* @dataProvider providerTestLink
*/
public function testToLink($entity_label, $link_text, $expected_text, $link_rel = 'canonical', array $link_options = []) {
$language = new Language(['id' => 'es']);
$link_options += ['language' => $language];
$this->languageManager->expects($this->any())
->method('getLanguage')
->with('es')
->willReturn($language);
$route_name_map = [
'canonical' => 'entity.test_entity_type.canonical',
'edit-form' => 'entity.test_entity_type.edit_form',
];
$route_name = $route_name_map[$link_rel];
$entity_id = 'test_entity_id';
$entity_type_id = 'test_entity_type';
$expected = '<a href="/test_entity_type/test_entity_id">' . $expected_text . '</a>';
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->once())
->method('getLinkTemplates')
->willReturn($route_name_map);
$entity_type->expects($this->any())
->method('getKey')
->willReturnMap([
['label', 'label'],
['langcode', 'langcode'],
]);
$this->entityManager
->expects($this->any())
->method('getDefinition')
->with($entity_type_id)
->will($this->returnValue($entity_type));
/** @var \Drupal\Core\Entity\Entity $entity */
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [
['id' => $entity_id, 'label' => $entity_label, 'langcode' => 'es'],
$entity_type_id,
]);
$expected_link = Link::createFromRoute(
$expected_text,
$route_name,
[$entity_type_id => $entity_id],
['entity_type' => $entity_type_id, 'entity' => $entity] + $link_options
);
$result_link = $entity->toLink($link_text, $link_rel, $link_options);
$this->assertEquals($expected_link, $result_link);
}
/**
* Provides test data for testLink().
*/
......
......@@ -28,6 +28,8 @@ class EntityUrlTest extends UnitTestCase {
protected $entityManager;
/**
* The mocked URL generator.
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $urlGenerator;
......@@ -50,12 +52,15 @@ protected function setUp() {
/**
* Tests the urlInfo() method.
*
* Note that urlInfo() is a deprecated alias for toUrl().
* See testToUrl().
*
* @covers ::urlInfo
*
* @dataProvider providerTestUrlInfo
* @dataProvider providerTestToUrl
*/
public function testUrlInfo($entity_class, $link_template, $expected, $langcode = NULL) {
/** @var $entity \Drupal\Core\Entity\EntityInterface */
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->getMockForAbstractClass($entity_class, array(array('id' => 'test_entity_id'), 'test_entity_type'));
$uri = $this->getTestUrlInfo($entity, $link_template, [], $langcode);
......@@ -75,27 +80,57 @@ public function testUrlInfo($entity_class, $link_template, $expected, $langcode
}
}
}
/**
* Tests the toUrl() method.
*
* @covers ::toUrl
*
* @dataProvider providerTestToUrl
*/
public function testToUrl($entity_class, $link_template, $expected, $langcode = NULL) {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->getMockForAbstractClass($entity_class, array(array('id' => 'test_entity_id'), 'test_entity_type'));
$uri = $this->getTestToUrl($entity, $link_template, [], $langcode);
$this->assertSame($expected, $uri->getRouteName());
$this->assertSame($entity, $uri->getOption('entity'));
if ($langcode) {
$this->assertEquals($langcode, $uri->getOption('language')->getId());
}
else {
if ($entity instanceof ConfigEntityInterface) {
// Config entities do not provide a language with their URIs.
$this->assertEquals(NULL, $uri->getOption('language'));
}
else {
$this->assertEquals(LanguageInterface::LANGCODE_NOT_SPECIFIED, $uri->getOption('language')->getId());
}
}
}
/**
* @covers ::urlInfo
* Tests for Entity::toUrl() exercising different language options.
*
* @covers ::toUrl
*/
public function testUrlInfoWithSpecificLanguageInOptions() {
/** @var $entity \Drupal\Core\Entity\EntityInterface */
public function testToUrlWithSpecificLanguageInOptions() {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(array('id' => 'test_entity_id'), 'test_entity_type'));
// Ensure that a specified language overrides the current translation
// language.
$uri = $this->getTestUrlInfo($entity, 'edit-form', [], 'en');
$uri = $this->getTestToUrl($entity, 'edit-form', [], 'en');
$this->assertEquals('en', $uri->getOption('language')->getId());
$uri = $this->getTestUrlInfo($entity, 'edit-form', ['language' => new Language(['id' => 'fr'])], 'en');
$uri = $this->getTestToUrl($entity, 'edit-form', ['language' => new Language(['id' => 'fr'])], 'en');
$this->assertEquals('fr', $uri->getOption('language')->getId());
}
/**
* Provides test data for testUrlInfo().
*/
public function providerTestUrlInfo() {
public function providerTestToUrl() {
return array(
array('Drupal\Core\Entity\Entity', 'edit-form', 'entity.test_entity_type.edit_form', NULL),
// Specify a langcode.
......@@ -108,19 +143,20 @@ public function providerTestUrlInfo() {
}
/**
* Tests the urlInfo() method with an invalid link template.
* Tests the toUrl() method with an invalid link template.
*
* @covers ::urlInfo
* @covers ::toUrl
*
* @expectedException \Drupal\Core\Entity\Exception\UndefinedLinkTemplateException
*
* @expectedExceptionMessage No link template 'canonical' found for the 'test_entity_type' entity type
*
* @dataProvider providerTestUrlInfoForInvalidLinkTemplate
* @dataProvider providerTestToUrlForInvalidLinkTemplate
*/
public function testUrlInfoForInvalidLinkTemplate($entity_class, $link_template) {
/** @var $entity \Drupal\Core\Entity\EntityInterface */
public function testToUrlForInvalidLinkTemplate($entity_class, $link_template) {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $this->getMockForAbstractClass($entity_class, array(array('id' => 'test_entity_id'), 'test_entity_type'));
$uri = $this->getTestUrlInfo($entity, $link_template);
$uri = $this->getTestToUrl($entity, $link_template);
$this->assertEmpty($uri);
}
......@@ -128,7 +164,7 @@ public function testUrlInfoForInvalidLinkTemplate($entity_class, $link_template)
/**
* Provides test data for testUrlInfoForInvalidLinkTemplate().
*/
public function providerTestUrlInfoForInvalidLinkTemplate() {
public function providerTestToUrlForInvalidLinkTemplate() {
return array(
array('Drupal\Core\Entity\Entity', 'canonical'),
array('Drupal\Core\Entity\Entity', FALSE),
......@@ -139,6 +175,9 @@ public function providerTestUrlInfoForInvalidLinkTemplate() {
/**
* Creates a \Drupal\Core\Url object based on the entity and link template.
*
* Method urlInfo() is deprecated and replaced with toUrl().
* See also getTestToUrl().
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The test entity.
* @param string $link_template
......@@ -184,17 +223,64 @@ protected function getTestUrlInfo(EntityInterface $entity, $link_template, array
}
/**
* Tests the urlInfo() method when an entity is still "new".
* Creates a \Drupal\Core\Url object based on the entity and link template.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The test entity.
* @param string $link_template
* The link template.
* @param string $langcode
* The langcode.
*
* @return \Drupal\Core\Url
* The URL for this entity's link template.
*/
protected function getTestToUrl(EntityInterface $entity, $link_template, array $options = [], $langcode = NULL) {
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->any())
->method('getLinkTemplates')
->will($this->returnValue(array(
'edit-form' => 'test_entity_type.edit',
)));
if ($langcode) {
$entity->langcode = $langcode;
}
$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->toUrl($link_template, $options);
}
else {
if ($entity instanceof ConfigEntityInterface) {
$uri = $entity->toUrl('edit-form', $options);
}
else {
$uri = $entity->toUrl('canonical', $options);
}
}
return $uri;
}
/**
* Tests the toUrl() method when an entity is still "new".
*
* @see \Drupal\Core\Entity\EntityInterface::isNew()
*
* @covers ::urlInfo
* @covers ::toUrl
*
* @expectedException \Drupal\Core\Entity\EntityMalformedException
*/
public function testUrlInfoForNewEntity() {
public function testToUrlForNewEntity() {
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(array(), 'test_entity_type'));
$entity->urlInfo();
$entity->toUrl();
}
/**
......@@ -236,7 +322,7 @@ public function testUrl() {
if ($route_name === 'entity.test_entity_type.canonical' && $route_parameters === array('test_entity_type' => 'test_entity_id') && array_keys($options) === ['absolute', 'entity_type', 'entity', 'language'] && $options['language'] == $language) {
return '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)));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment