Belongs to #1346214: [meta] Unified Entity Field API, architectural discussions should happen there.

- Add the defined interfaces (already in entity-property-fago)
- Start to implement this for the TestEntity (working on this, will be in entity-property-berdir soon)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Berdir’s picture

Ok, commited an initial, largely hardcoded version of the entity property API.

The following part of the tests already work:

  public function testReadWrite() {
    $name = $this->randomName();
    $user = $this->drupalCreateUser();
    $entity = entity_create('entity_test', array('name' => $name, 'uid' => $user->uid));

    // Access the name property.
    $this->assertTrue($entity->name instanceof EntityPropertyInterface, 'Property implements interface');
    $this->assertTrue($entity->name[0] instanceof EntityPropertyItemInterface, 'Property item implements interface');

    $this->assertEqual($name, $entity->name->value, 'Name value can be read.');
    $this->assertEqual($name, $entity->name[0]->value, 'Name value can be read through list access.');

    // Change the name.
    $new_name = $this->randomName();
    $entity->name->value = $new_name = $this->randomName();
    $this->assertEqual($new_name, $entity->name->value, 'Updated Name value can be read.');

    // Access the user property.
    $this->assertTrue($entity->user instanceof EntityPropertyInterface, 'Property implements interface');
    $this->assertTrue($entity->user[0] instanceof EntityPropertyItemInterface, 'Property item implements interface');

    $this->assertEqual($user->uid, $entity->user->value, 'User id can be read.');
    $this->assertEqual($user->name, $entity->user->entity->name, 'User name value can be read.');

    // Change the assigned user.
    $new_user = $this->drupalCreateUser();
    $entity->user->entity = $new_user;
    $this->assertEqual($new_user->uid, $entity->user->value, 'User id can be read.');
    $this->assertEqual($new_user->name, $entity->user->entity->name, 'User name value can be read.');
  }

Saving doesn't work yet, because the properties are protected and then drupal_write_record() recieves EntityProperty objects and freaks out. But we will need to stop using that function anyway for the upcoming _property_data tables anyway.

fmizzell’s picture

$entity->user->entity->name

Do we really have to do that? can we get rid of "entity": $entity->user->name

tim.plunkett’s picture

AFAIK, a class may not implement two interfaces with the same method names.

And PropertyContainerInterface duplicates a half dozen method names, conflicting with EntityInterface and PropertyListInterface.

Berdir’s picture

FileSize
75.97 KB

As I understand we don't want to get rid of entity however, for these cases, the idea is that the object will provide convenience methods, so that you can do:

$entity->user()->name->value, or $node->author()->label().

Having the same method in multiple interfaces is fine as long as they don't conflict.

Having these e.g. is fine:

function get($name)
function get($name, $langcode = NULL)

This wouldn't work:

function get($name);
function get($name, $langcode);

The get/set methods from EntityInterface have an additional langcode, in other cases there is (or will be) additional documentation. And the validate()/access() methods are in parallel interfaces, which are, in the case of entity properties combined, but that's not required so that's why they are in both.

See the attached image, which contains a simple and incomplete class diagramm of all these classes.

tim.plunkett’s picture

Did you try using your branch? It fatal errored for every conflicting method. None of them have different signatures, so they're not overloaded or anything.

Berdir’s picture

Yes, as I said, the tests were passing for me. A least the ReadWrite tests.

Crell’s picture

I still firmly believe that entity() should be a method of a reference property, not an extra-magic pseudo-object-property. It's way more clear what you're doing there, and easier to standardize, and doesn't create a magic constant value.

miro_dietiker’s picture

Referring to my document that tries to cover the topic on how to build a perfect multilingual / revisionnable system that allows to finally make content translation unneeded without regressions for typical advanced usecases.
http://techblog.md-systems.ch/blog/2012-06-drupal-8-multilingual-and-rev...
Feedback as comments there appreciated. (signup required..)

fago’s picture

I've done more work on that recently, check the entity-property branch. It's basically working, but still lots of stuff is open and todo. Let's figure the details out in specific issues -> I've create a bunch of those, please just add yours as well.

fago’s picture

Status: Active » Closed (fixed)

As said, let's figure the details out in specific issues. For status-updates and the like, I'd suggest to use the core-issue #1696640: Implement API to unify entity properties and fields which we then can use for posting the initial patch as well.

Given that, this issue is useless, so let's close. Please follow the core-issue instead and/or post to specific sandbox issues. Thanks!