The uri() method is currently ugly to use because it returns an array, so you need a temporary variable everywhere.

We could add the following two functions to help with this:

function entity_url(EntityInterface $entity, $options = array())
function entity_l(EntityInterface $entity, $label = NULL, $options = array())

label would default to $entity->label() when empty.

Alternatively, these could be methods on the class, but we agreed that functions make more sense.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

+1 for those helpers. Those would be nice methods as well, however I fear to clutter the EntityInterface with lots of unrelated utility methods if we continue like that. That said, let's start doing more helpers/other systems that just take an entity as parameter.

jcisio’s picture

Assigned: Unassigned » jcisio
jcisio’s picture

Status: Active » Needs review
FileSize
1.54 KB

Here is a patch. I keep the $text argument name in l(). I was wondering about argument order (in l(), the first argument is $text), however, I think here as wrapper functions, the first argument should always be $entity.

Berdir’s picture

Status: Needs review » Needs work
+++ b/core/modules/entity/entity.moduleundefined
@@ -412,6 +412,51 @@ function entity_uri($entity_type, $entity) {
+ * @param $entity
+ *   The entity for which to generate a path.
+ * @param $options
+ *   An associative array of additional options to pass to the url() function.
+ *
+ * @return
+ *   The url of the entity, or NULL if url is unavailable.

8.x now requires the type for @param and @return, in the case of classes, this should be the fully qualified name, e.g. Drupal\entity\EntityInterface.

Also, let's add a @see for EntityInterface::uri() (again full name) and url()

+++ b/core/modules/entity/entity.moduleundefined
@@ -412,6 +412,51 @@ function entity_uri($entity_type, $entity) {
+ * Format the url of an entity as a HTML anchor tag.
+ *
+ * @param $entity
+ *   The entity for which to generate a path.
+ * @param $text
+ *   The link text for the anchor tag. Default to entity label.
+ * @param $options
+ *   An associative array of additional options to pass to the url() function.
+ *
+ * @return

Same here for the arguments and also @see for l() and EntityInterface::uri().

We might also want to add reverse references and maybe even a sentence to the documentation of EntityInterface::uri() that points you to these new helper functions.

jcisio’s picture

Status: Needs work » Needs review
FileSize
2.33 KB

Addressed #5.

fgm’s picture

Status: Needs review » Needs work

We may want to leave unexpected results behave "better" instead of failing when they could still provide usable results. That would be a design choice, though (typical PHP vs "fail early"). Otherwise good for me.

+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+ * Returns the url of an entity.

As in all occurrences in this patch, URL is normally uppercase in text.

+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+  }

This test does not cover the case of uri() returning some non-NULL value (although it should). Although the default implementation in Entity::uri() always returns array or NULL, inherited implementations could return something else, since the return value is not checked by type hinting. We might want to leave such a result untouched and return it instead of converting it to NULL.

+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+    }

As for entity_url(), we probably want to use (string) $uri if it is a non-NULL scalar anyway.

fago’s picture

Issue tags: +Needs tests

Also, it's used nowhere as of now. So I guess at least we should add some basic tests for it.

jcisio’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
2.37 KB

- Fixed capitalization of URL (anyway, I think we should we should do the same thing for 'uri' too).
- I don't fix the other two, as described in the EntityInterface, ::uri() should return an array or NULL. Also, anything other than an array is unusable.

jcisio’s picture

It was a cross post so that the tag was removed. However I don't think tests are needed. They are basically wrapper functions, and we already have tests for Entity::uri().

fago’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+  if (is_array($uri)) {

Let's use isset() here as this is faster (microoptimizations..).

+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+ *   An associative array of additional options to pass to the url() function.

It's passed to l(), so I guess it should be documented as for l().

+++ b/core/modules/entity/entity.module
@@ -413,6 +413,56 @@ function entity_uri($entity_type, $entity) {
+  if (is_array($uri)) {

Same here.

They are basically wrapper functions, and we already have tests for Entity::uri().

Yes, still we want make sure the basic wrapper works and extending the test to take care of that should be rather simple.

jcisio’s picture

Status: Needs work » Needs review
FileSize
3.29 KB

Fixed some errors in #10 and add tests for Entity::uri() and entity_url.

fgm’s picture

Just one more assertion for entity_l(), maybe ?

Also, to nitpick, variables pointing to user accounts are usually named $account(something) not $user(something)

jcisio’s picture

- If entity_url passes, there is no way entity_l won't pass. They are pratically the same and the behavior of url() and l() are well known.
- In tests, in most cases, $userN are used instead of $account for new created accounts.

fago’s picture

Status: Needs review » Needs work
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityApiTest.php
@@ -91,4 +91,17 @@ class EntityApiTest extends WebTestBase {
+    $this->assertTrue(is_string(entity_url($user1)), 'Entity URL has been created.');

Let's better test the right string is returned, i.e. url(...). Just having a string doesn't make a right URL.

- If entity_url passes, there is no way entity_l won't pass. They are pratically the same and the behavior of url() and l() are well known.

entity_url() doesn't invoke entity_l() so I can't follow the reasoning. Let's make sure we have complete tests for both.

jcisio’s picture

Status: Needs work » Needs review

Let's better test the right string is returned, i.e. url(...). Just having a string doesn't make a right URL.

As I commented in the test, url is managed by the entity controller, we don't know it. So I don't know how to write a better test, unless I copy the code in entity_url into the test, then compare the result with entity_url's, which, IMO, is not very useful.

entity_url() doesn't invoke entity_l() so I can't follow the reasoning. Let's make sure we have complete tests for both.

Both entity_url() and entity_l() use the same logic: they use EntityInterface::uri() output and send to url() and l(). The test is basically uri() test. So if one passes, the other should pass (could you give a counterexample?).

That said, I think we could add another test: assert if entity_l() result has the format of <a[.+?]>THE-GIVEN-TEXT</a>. But I'm not sure it is useful. It'd better add tests for l() and url().

fago’s picture

Status: Needs review » Needs work

As I commented in the test, url is managed by the entity controller, we don't know it. So I don't know how to write a better test, unless I copy the code in entity_url into the test, then compare the result with entity_url's, which, IMO, is not very useful.

Just make use of url() for the test, i.e. compare url('user/X') with entity_url($user), so we verify the result is as expected.

Both entity_url() and entity_l() use the same logic: they use EntityInterface::uri() output and send to url() and l(). The test is basically uri() test. So if one passes, the other should pass (could you give a counterexample?).

That holds assuming that both functions are written the same. The tests are there to verify both work independent of that assumption. So, again just add a simple assertion that makes sure l($entity->label(), url("user/1")) equals the output of entity_l().

jcisio’s picture

How can we assume that entity_url($user) would return url('user/X')? Only the user module knows that, and there is already a test for that in the user module.

I know that simpletest is not unit test, but...

I leave this issue for more suggestion.

Berdir’s picture

Status: Needs work » Needs review
FileSize
3.33 KB

Extended the tests, we don't need to know what it should return, but we do know that it needs to be the same as calling url() or l() ourself.

ygerasimov’s picture

Lets enhance the test to check custom title and link options.

corvus_ch’s picture

Status: Needs review » Reviewed & tested by the community

Looking good.

catch’s picture

Status: Reviewed & tested by the community » Needs review

Hmm I'm not really sure between the procedural helpers vs. class methods but yeah it doesn't seem useful to have these in the main interface at least.

Doesn't have to happen here, but there must be somewhere we can use this on core already? Could we include one conversion in the patch then add a novice follow-up to do the rest?

Berdir’s picture

Here we go. I think I actually converted most usages now that already use uri(), I guess we have more that are still using hardcoded links and so on. And there are quite a few that do need additional arguments.

Nicely shows that these functions are useful and help to simplify code I think. Let's see if I didn't mess anything up.

Status: Needs review » Needs work

The last submitted patch, entity-l-conversion-1637342-22.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
777 bytes
11.12 KB

Missed one.

corvus_ch’s picture

Status: Needs review » Needs work

Drupal\user\RegisterFormController::save() can profit from the new functions. For this is the only place I could find, I suggest that we fix this in this patch.

Berdir’s picture

Status: Needs work » Needs review
FileSize
1.05 KB
12.18 KB

Ok, fixed that one. As said before, I assume there are still some hardcoded links around, I suggest we check and tackle that in a follow-up.

Status: Needs review » Needs work

The last submitted patch, entity-l-conversion-1637342-26.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
1.66 KB
13.54 KB

Fixed the other two cases that used $uri.

corvus_ch’s picture

Status: Needs review » Reviewed & tested by the community

This one's looking good again.

fago’s picture

Yep, looks great!

penyaskito’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
14.05 KB

[edited]

The conflict was because of two @see phpdoc to url() in EntityInterface that have been moved to StorableInterface.

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs tests, -Entity system, -Novice, -sprint

The last submitted patch, entity-l-conversion-1637342-31.patch, failed testing.

penyaskito’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
Issue tags: +Needs tests, +Entity system, +Novice, +sprint

The last submitted patch, entity-l-conversion-1637342-31.patch, failed testing.

penyaskito’s picture

I were wrong in #31, editing comment for not confusing anyone else.

penyaskito’s picture

Status: Reviewed & tested by the community » Needs review
penyaskito’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

This doesn't apply anymore :/
Needs rerolling again.

penyaskito’s picture

Status: Needs work » Needs review

Rerolled again.

penyaskito’s picture

oops!

penyaskito’s picture

Issue tags: -Needs reroll
Berdir’s picture

Status: Needs review » Needs work

One of the re-rolls seems to have lost two conversions in the node and term preprocess functions:


--- b/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1334,7 +1334,8 @@
     'link_attributes' => array('rel' => 'author'),
   ));
 
-  $variables['node_url']  = entity_url($node);
+  $uri = $node->uri();
+  $variables['node_url']  = url($uri['path'], $uri['options']);
   $variables['title']     = check_plain($node->title);
   $variables['page']      = $variables['view_mode'] == 'full' && node_is_page($node);
 
reverted:
--- b/core/modules/taxonomy/taxonomy.module
+++ a/core/modules/taxonomy/taxonomy.module
@@ -629,7 +629,8 @@
   $variables['term'] = $variables['elements']['#term'];
   $term = $variables['term'];
 
+  $uri = $term->uri();
+  $variables['term_url']  = url($uri['path'], $uri['options']);
-  $variables['term_url']  = entity_url($term);
   $variables['term_name'] = check_plain($term->name);
   $variables['page']      = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term);
 
dcam’s picture

Status: Needs work » Needs review
FileSize
13.54 KB

Rerolled #35 with the missing changes to the preprocess functions shown in #41.

dcam’s picture

Rerolled #42 due to recent entity system changes.

Lars Toomre’s picture

Issue tags: -Needs tests

If this patch gets re-rolled again, can the following be added as well to clean up the docs?

+++ b/core/includes/entity.incundefined
@@ -344,6 +344,56 @@ function entity_prepare_view($entity_type, $entities) {
+ * @param $text

Can we add @param type hint here? Also explanation should start with '(optional)' as well as in the description for $options variable.

Berdir’s picture

Issue tags: -Entity system, -Novice, -sprint

Status: Needs review » Needs work
Issue tags: +Entity system, +Novice, +sprint

The last submitted patch, entity-l-conversion-1637342-43.patch, failed testing.

andypost’s picture

Berdir’s picture

Issue summary: View changes
Status: Needs work » Closed (duplicate)
Issue tags: -Novice, -sprint

I think we can close this one, now that we have $entity->url().