Hello everybody,

I think the Entity is a new concept in Drupal 7, some body need an example to work with the Entity. It will be interesting for me to see an entity example module to know about entity concept more.

Thank you all,
mrsinguyen

Files: 
CommentFileSizeAuthor
#101 entity_example-893842-101.patch31.29 KBMichaelCole
PASSED: [[SimpleTest]]: [MySQL] 2,485 pass(es). View
#99 Screenshot at 2012-01-20 09:52:16.png39.44 KBrogical
#96 examples.entity_example_with_tests_893842_96.patch28.18 KBrfay
PASSED: [[SimpleTest]]: [MySQL] 2,483 pass(es). View
#94 examples.entity_example_with_tests_893842_94.patch28.2 KBrfay
FAILED: [[SimpleTest]]: [MySQL] 2,474 pass(es), 9 fail(s), and 0 exception(es). View
#91 893842_entity_example.patch28.19 KBMile23
FAILED: [[SimpleTest]]: [MySQL] 2,455 pass(es), 21 fail(s), and 1 exception(es). View
#88 examples.entity_example_893842_88.patch25.71 KBrfay
FAILED: [[SimpleTest]]: [MySQL] 2,459 pass(es), 21 fail(s), and 1 exception(es). View
#85 examples.entity_example_893842_84.patch17.52 KBrfay
PASSED: [[SimpleTest]]: [MySQL] 2,291 pass(es). View
#79 examples.entity_example_893842_79.patch15.23 KBrfay
PASSED: [[SimpleTest]]: [MySQL] 2,291 pass(es). View
#59 basicentity-893842-59.patch10.73 KBronald_istos
PASSED: [[SimpleTest]]: [MySQL] 2,293 pass(es). View
#35 entity_example_more_tests.patch18.42 KByakoub
PASSED: [[SimpleTest]]: [MySQL] 1,959 pass(es). View
#33 entity_example.patch15.91 KByakoub
PASSED: [[SimpleTest]]: [MySQL] 1,959 pass(es). View
#26 entity_example.tar_.gz3.11 KByakoub
#25 entity_example.patch13.09 KByakoub
PASSED: [[SimpleTest]]: [MySQL] 1,963 pass(es). View
#25 entity_example.tar_.gz2.45 KByakoub
#21 examples.entity_example_893842_21.patch12.66 KBrfay
PASSED: [[SimpleTest]]: [MySQL] 1,957 pass(es). View
#15 entity_example.zip3.65 KBandypost

Comments

rfay’s picture

andypost has one in progress. We just need to get him to post it.

andypost’s picture

Subscribe, I'm waiting for decision on #823428: Impossible to alter node URLs efficiently

jpstrikesback’s picture

Subscribe

Alan D.’s picture

Subscribe - just trying to figure this one out myself. Have you a rough example completed yet?

ronald_istos’s picture

Andy, I've been working on an example as well. Do you mind sharing why you think that issue is relevant- I realise it is relevant for consistency within core and when dealing with "core" entities, etc but not quite sure how it impacts handling of outside entities. I assume they would still have their uri callback called and not bypassed whatever the outcome of that issue (or am I missing something?).

thanks

hadsie’s picture

I'd love to see an example for this whatever the state the module is in :). I'm currently struggling my way through building a module that creates it's own entity and any examples would be quite useful.

ivanjaros’s picture

+++++

threewestwinds’s picture

I'd like to add a request for this as well. I ended up reading through the field attach API because I didn't know where fields were stored for a loaded node. Ouch.

Taxonomy terms are an easy to understand way to talk about entities, and manipulating them would make a good example.

rfay’s picture

I pinged andypost about this. I guess the issue you were waiting on isn't going to go in? Well, let's make it work anyway.

Thanks!
-Randy

andypost’s picture

Status: Active » Needs work

I need to remove some code from my example, please wait a week

rfay’s picture

Thanks so much, @andypost.

ivanjaros’s picture

How its looking? Weekend is comming :)

rfay’s picture

Status: Needs work » Active
ivanjaros’s picture

Any news ?

andypost’s picture

Status: Active » Needs review
FileSize
3.65 KB

So here is a promised example. I think there's no need to simplify it, so I leave entity with some fields...

Also this example shows how to work with date field because drupal 7 core does not support storing date fields.

I think this example could be a bit extended with delete functionality and to provide some visible placeholder for "manage display" to demonstrate an ability to rearrange entity fields and attached fields

rfay’s picture

andypost++

ivanjaros’s picture

Thanks Andy!!! Could you add a revisions into it?

andypost’s picture

Let's commit current code and Open separate issue about "Could you add a revisions into it?"

@rfay Also do we need project's component for this example?

rfay’s picture

Let's start by just getting this integrated and in. Patience, ivanjaros :-)

podarok’s picture

subscribe...
waiting for a module page for it

rfay’s picture

Status: Needs review » Needs work
FileSize
12.66 KB
PASSED: [[SimpleTest]]: [MySQL] 1,957 pass(es). View

Thanks for the excellent work on this, @andypost. This will serve as a great basis.

Attached is a minor update moving some paths around and adding a couple of comments.

Here are the things we still need to do to make this happen:

  • This is a teaching example, so ever function needs to be explained in the comments. This is all still magic to me, so I don't quite grok the majority of this.
  • Document hook_schema(): Are these arbitrary values? Can I put whatever I want in there? Or is this a cookbook thing that is always done this way?
  • This will need tests. Functional tests are fine - just tests that go through the various functionality and make sure it works. Anybody can contribute to these.
  • I think we should change the usage of 'entity_example' and 'example_entity' just a bit so that people can tell the difference between what's a path, what's a name of an entity, etc. etc.
  • We need to try to explain "Why would we want to make an entity?" "Why would we make an entity like this?" "What kinds of things does this entity accomplish?"

I am more than happy to clean up comments, improve English style, etc. But right now I don't know enough about what this is supposed to do to be able to add the comments myself.

@andypost: In this patch I moved a couple of menus around, but apparently didn't finish the job correctly. And after creating an entity and then visiting examples/entity_example/2, I get

    * Notice: Trying to get property of non-object in entity_example_page_title() (line 129 of /home/rfay/workspace/d7git/sites/all/modules/examples/entity_example/entity_example.module).
    * Warning: Attempt to assign property of non-object in entity_example_page() (line 137 of /home/rfay/workspace/d7git/sites/all/modules/examples/entity_example/entity_example.module).
    * Notice: Trying to get property of non-object in entity_example_page() (line 140 of /home/rfay/workspace/d7git/sites/all/modules/examples/entity_example/entity_example.module).
    * Warning: Attempt to assign property of non-object in field_attach_prepare_view() (line 1090 of /home/rfay/workspace/d7git/modules/field/field.attach.inc).
    * Notice: Trying to get property of non-object in entity_example_page() (line 141 of /home/rfay/workspace/d7git/sites/all/modules/examples/entity_example/entity_example.module).
    * Warning: Attempt to assign property of non-object in entity_prepare_view() (line 7428 of /home/rfay/workspace/d7git/includes/common.inc).
    * Notice: Trying to get property of non-object in entity_example_page_title() (line 129 of /home/rfay/workspace/d7git/sites/all/modules/examples/entity_example/entity_example.module).
andypost’s picture

Another great and maybe cleaner example http://www.istos.it/blog/drupal-entities/drupal-entities-part-3-programm...

Maybe we could make this code cleaner by taking some simple example then I choosen

+++ entity_example/entity_example.moduleundefined
@@ -0,0 +1,351 @@
+  $items['examples/entity_example/%entity_example'] = array(
+    'title' => 'Example entity',
+    'title callback' => 'entity_example_page_title',
+    'title arguments' => array(1),
+    'page callback' => 'entity_example_page',
+    'page arguments' => array(1),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['examples/entity_example/%entity_example/view'] = array(
+    'title' => 'View',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+  $items['examples/entity_example/%entity_example/edit'] = array(
+    'title' => 'Edit',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('entity_example_form_edit', 1),
+    'access arguments' => array('administer example entity'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 10,

This hunk all title & page arguments should be increased by 1 because %entity_example has index=2 ones moved into deeper level of menu hierarchy

Powered by Dreditor.

rfay’s picture

Marked excellent #1018686: Add Entity example to Examples Project as a duplicate and asked to move over here. That one already has a test. Perhaps we can get the best of each?

geerlingguy’s picture

Subscribe.

yakoub’s picture

FileSize
2.45 KB
13.09 KB
PASSED: [[SimpleTest]]: [MySQL] 1,963 pass(es). View

here is my example for an entity implementation

disregard the attached "tar.gz" , it is outdated

yakoub’s picture

FileSize
3.11 KB

attached up to date "tar.gz" package

yakoub’s picture

does my version require more work ?
if so give me some guide lines please .

rfay’s picture

Status: Needs work » Needs review

Thanks very much for your contribution and eagerness! We'll get it reviewed. Everything *always* needs more work but we'll try to be specific.

WIthout a thorough review, here are some things that will be required:

1. The commenting is not up to Drupal commenting standards. Please remember that the entire purpose of this is to teach people how to use something. So every function needs to be explained, with complete sentences. Please see http://drupal.org/coding-standards.

2. Always remember that people will use this as a start for everything they do. So it must be clearly stated how they would convert this into their own entity.

3. The test is *very much* appreciated. But a casual look says that there should be more test coverage than this. True?

4. I think it would be easier to work with this as a patch. That way the tests will get run. Would you mind rerolling as a patch?

Thanks so much!
-Randy

yakoub’s picture

thanks for your reply , i will work on all those issues soon .

i'm not sure what rerolling mean , is the patch i attached above in the right format ?
when i'm done working i will create a new patch like the one above and attach it

jpstrikesback’s picture

@ yakoub

re-roll = a new patch against the target revision with your new changes :)

how to create a patch:
http://drupal.org/patch/create
There are also links in there for git workflow if you use git.

When you upload as a .patch file (rather than an archive) tests can be run against it :)

ilo’s picture

So, we do have three entity examples here.. How are we going to handle this?

jpstrikesback’s picture

entity cage fight

yakoub’s picture

FileSize
15.91 KB
PASSED: [[SimpleTest]]: [MySQL] 1,959 pass(es). View

i did more work on documentation
and i introduced entity_cleanup_example to clean after uninstall as an answer to bug 943772
but i still haven't worked on adding more tests , i'll try to do that tomorrow

ilo’s picture

Thanks for working on this, yakoub, I'll try to make a review in the following days!

yakoub’s picture

FileSize
18.42 KB
PASSED: [[SimpleTest]]: [MySQL] 1,959 pass(es). View

i added more tests

ilo’s picture

I have to admin, still haven't found any clue in the .module file about when a developer has to make the decission of use a custom entity over the regular CRUD operations. So, from my point of view right now, entities are a great-fantastic-magic thing that can do a lot of things and integrate pretty well, that you choose to code because... :?

What are the pros/cons of/for developing an entity? could an entity extend another? these are question that the example must solve.

Thanks for working on this!

rfay’s picture

I agree that entities must be "sold" - we have to explain the context of why one will use them.

andypost pointed out the excellent article http://www.istos.it/blog/drupal-entities/drupal-entities-part-3-programm..., which is part of a series on entities.

Also, the excellent Drupal 7 Module Development book has a good section.

yakoub’s picture

i don't think the purpose of an example module is to explain the philosophy
behind entities , my objective from this exercise is just figure out technically how
entities are implemented so that latter when encountering new projects ,
i might identify objects that should be implemented as entities .

nonetheless , now that i have figured the technical aspect i am intrigued on researching
the questions you stated , first thing comes to mind is the loader class that i haven't used ..

ilo’s picture

You are right, the purpose of the module is not to explain what entities are, but the example must outline when NOT to use an entity at all (CONS: e.g. you have to code the views in your entity controller) and what/why do you use entities (PROS: e.g. you just get Field API as bonus without any worries), and this outline must show each implemented purpose function (take a look to example_mail, starting from the header, each different function has a didactic signature explaining why it was there).

Anyway, a good summary about why / why not is just in the second part: http://www.istos.it/blog/drupal-entities/drupal-entities-part-2-what-whe...

jpstrikesback’s picture

The Istos posts are good.

The Drupal 7 Module Development chapter on content is good, here are a few reasons from D7MD (the book states brief quotes are allowed for critical articles & reviews):

- We may need entities that have entirely different permission handling or
workflow than nodes, such as products in an e-commerce system.

- We may be accessing entities that are not stored in Drupal's local database,
such as a legacy data store.

- We may need to have internal variants, like node types, but nodes don't
support "sub-type types"

Off the top of my head a few examples and reasons to use Entities:

Entities get their own table for their core data that doesn't contain fields for comment, sticky, author, grants, etc so you get to create the data model that suits your application rather than bending it around the Node data model.

At the same time Entities can use all the core API's that make Node, Taxonomy, Comments & User entities great (Fields can be attached, etc)

Just as a pointer to use-cases for custom entities, a good project to look at is Drupal Commerce, there they have created a entity for Products, this entity is not a normal piece of "content" it is a data object of sorts and the way it is displayed is via a Product Display Field. The separation of the two allows one to act on data & content separately...

So one reason to use entities over another Node Bundle (Type) is that you may not want the "Entity" to be standard web content.

In the Relation project there are custom entities to describe the relationship between two other entities - say a Node & a User, this relation entity might be used for all kinds of reasons, programatic and display.

There's some thoughts to pick from, hopefully useful :)

Alan D.’s picture

Totally unrelated but useful example of an entity was a module that I tried to publish on do. It was a countries db that allows users to extend it with additional fields on top of the name, iso2, iso3, etc. Examples of these would be image fields for flag icons or additional textfields for Olympic country codes, capitals, languages, etc. Much simpler to grasp than a relationship as a entity, and unlike products, where a page callback for the content is typically required, this is just for data storage. (Although I have used view based callbacks to display pages that have been tagged with a certain country)

The project was functional up to D7 Beta 1, but hasn't had support due to conflicting functionality with countries_api. Anyway here is the CVS url if you want to take a look. Has many useful additional examples in there, like a country FAPI element, country fields, etc.

/cvs/drupal-contrib/contributions/modules/countries

ilo’s picture

@jpstrikesback blockquote is a good example of reasoning for me, however it is incomplete. It describes why to use entities instead of nodes, but still misses the point about why use entities instead of our custom CRUD, and I'm not only refering as 'fieldable' entity... what about the cache, the default hooks, the exportable properties and other things like that? anyone that we can just recall without having to digg into common.inc ?

yakoub’s picture

i thought about it for some time , and reached a conclusion that
there are few rare examples where objects can't be implemented as nodes / users / taxonomy ..

so the best motivation to implement an entity in my opinion is simply having a different
work flow for the object than what is implemented for nodes / users .. , that is enough reason
for me to write an entity

i would like to note , that even in drupal 6 as a programmer i have several times
implemented objects and features using hook_menu and fapi without using nodes api

the question is not "why should we implement an entity ?" ,
rather "why we bother with nodes and user , now that we have entities ?"

lathan’s picture

Hmmm, I was looking just for an example like this, but you don't seem to be using the Entity API in your example? Why is this not the case as most modules for D7 are now implementing entity's using that API.... og_groups, profile2 and commerce is even going to back port at some stage to Entity API.

The really neat bit about Entity API from what I understand is that it provides all that views goodness out the box.. no need to define those methods to do relation ships.... duno I really think doing an example using that is a better option for most people.

Oh well back to the drawing board.

yakoub’s picture

because entity api is not part of core , it is a contributed module

people worked for three years on drupal7 core , and now you think all this should
be thrown away and replaced with some contributed module ?

lathan’s picture

@yakoub hold on to your horses, ey. I was simply asking why! Just thought that since every body was using entity api, it would be a more useful example. But hey flap your wings.

rfay’s picture

Examples does do only core examples.

I would be very much in favor of an entity API example - but it should either be a new project (entity_examples?) or could be bundled with Entity. It would be great.

ilo’s picture

IMO, Entity API 'example' should go as documentation in the Entity API module page, or we may end including ctools examples to handle multistep forms.

There are two or three different entity examples in this issue already, but just need a review and some love.

mlncn’s picture

There a reason this is not RTBC yet? I can see some comment style issues but i'll commit to cleaning those up after its committed, too; it seems solid enough to go in, then we can work on smaller patches.

rfay’s picture

Seems like there are quite a lot of typos and the like.

I don't have a lot of experience with entities, so will have to rely on others for RTBC. Are we agreed on #35?

yakoub’s picture

i am of course ready to further my contribution , and learn more about entities .

Dave Reid’s picture

Version: » 7.x-1.x-dev
andypost’s picture

Main reason to use own entities against nodes is a separation of permission, administration.

Example I've provided comes from real project - we have different moderators for content so 'administer nodes' gives access to admin/content page that confusing admins with a mix of content, profiles (D6 content_profile) and promo content, so there's no way to filter this dashboard without separation of content to different screens.

EDIT: Another great example of entities is http://dgo.to/field_collection

I'm not quite understand the example provided by @yakoub:
- entity is sophisticated, bundles of teacher and student are 'out of box' but it' not clean what could happen when we add another entity with different personality (director for example).
- this example mimics a node entity but I think better to use a simpler (a core's user entity) example which has one bundle.

PS: all patches are needs a bit of love about trailing whitespace.

+++ entity_example/entity_cleanup_example/entity_cleanup_example.infoundefined
@@ -0,0 +1,5 @@
+package = Example modules ¶

Please set-up you editor to remove trailing white-space at the end of lines on save

+++ entity_example/entity_example.infoundefined
@@ -0,0 +1,5 @@
+package = Example modules ¶

the same and a lot of latter

Powered by Dreditor.

yakoub’s picture

you know what ? i think you are right , my example sucks .. so go on and let someone else provide you with an entity example .

ronald_istos’s picture

Hi - thought this is an appropriate place to let you know that I've started a Model Entity project which aims to a. provide a fully working example taking the more realistic route (i.e. not relying purely on core functionality) b. develop the associated document that answers the why? question for entities. Code is about 70% there - will post in the next couple of days unless people come back with "this is a really bad idea".

wojtha’s picture

Subscribing.

linclark’s picture

ronald_istos, when you say that the module doesn't rely purely on core functionality, do you mean it relies on Entity API? If so, it seems like it might be a good patch for the Entity API project.

ronald_istos’s picture

@linclark don't want to hijack this thread more than I already did - I've tried to explain the reasoning on the project page - http://drupal.org/project/model - summary is that we need a bit more flexibility than what an example within the EnityAPI module space would afford us (including the possibility to adopt an alternative approach). Also allows the model to iterate and develop externally. I would like to have several different examples that definitely go beyond the scope of EntityAPI - (for example - using RDFa).

ronald_istos’s picture

Status: Needs review » Needs work
FileSize
10.73 KB
PASSED: [[SimpleTest]]: [MySQL] 2,293 pass(es). View

Had a look at the examples above - I think they are all ok or fixable but wanted to toss in my own suggestion. My aim is to document the code sufficiently (we could do more), and do an implementation which does not distract with domain specific. I feel it needs to be a generic example that people can easily adapt. So here is my patch - needs a test which I have not done yet but let us choose this or one of the ones above and get an example in.

cmcintosh’s picture

Also updating the Drupal.org documentation would be GREAT!

wjaspers’s picture

subbing.
Is there any example of how to attach custom views handlers to entities without explicitly focusing on a single table?

Mile23’s picture

This is great, Ronald. I'd suggest having the entity name be the same as the module name, because, e.g. basic_load() doesn't belong in a file called entity_example.module.

Run Coder on it and see what else it says. :-)

Thanks!

Levure’s picture

subscribe

pjeutr’s picture

An external database example would be great.

I needed some workarounds, basically copy load from DrupalEntityControllerInterface into my own controller and throw db_set_active around the queery .

    db_set_active('legacy');
    $query = $this->buildQuery($ids, $conditions);
    $queried_entities = $query
        ->execute()
        ->fetchAllAssoc($this->idKey);
    db_set_active();

Save was working like this.

public function save($basic) {
  //drupal_write_record() erroneous when running on non default database connection
  //http://drupal.org/node/955512
  drupal_get_schema();
  db_set_active('legacy');
  if ($newRecord) {
    drupal_write_record('basic', $basic);
  }
  else {
    drupal_write_record('basic', $basic, 'id');
  }
  field_attach_insert('basic', $basic);
  db_set_active();
  module_invoke_all('entity_insert', 'basic', $basic);
   
  return $basic;
}
firdous.ali86’s picture

is custom entity supported by apachesolr module? like node types

rfay’s picture

I did finally at least get *started* on looking at these examples on the plane. Thanks so much for your contributions here, which have already helped many.

yakoub’s picture

i just want to apologize for my comment #54 , i could have phrased it to sound better .

but what caused my frustration was idea that the example should show something "special" and "ooolaalaa"
because frankly when i want to learn about something that is exactly what pisses me off:
why should someone who want to see a technical example about field attach api be bothered by the author's need to "shine" and implement something that is totally not relevant to the reader .

i mean sure given some complicated entity model then various developers can come up with cool solutions but how would that model be relevant to the reader , who often have project time constraints and all that he/she wants is just get on with the technical stuff so they can concentrate on their own entity model ?

NealB’s picture

I created a sandbox project for a minimalistic entity example. I left out everything inessential. The different parts are split into separate files: the controller class, the page and form callbacks, and the hook implementations. It is not fieldable, but adding fields would be simple.

http://drupal.org/sandbox/Kurmangazy/1282660

I would be happy to contribute it to the examples module.

Thanks.

rfay’s picture

Thanks! Looking forward to looking at it. We just have too many choices here :-)

yakoub’s picture

how is it minimalistic when you specifically add methods to entity controller that is not part of the default entity process ?

you also define "view modes" for the entity that is not used anywhere in your code

i also see no point of implementing an entity that is not fieldable , although entity info structure specifically has a property for "fieldable" .. can someone explain that for me ?
as i see it the only benefit of entities is enabling field api .

NealB’s picture

"how is it minimalistic when you specifically add methods to entity controller that is not part of the default entity process ?"

The create, save, and delete functions didn't need to be added to the controller. They could have been regular functions. It makes sense to separate them from the submit callbacks, though, for the sake of clarity and code reuse. I was taking the lead of the "Drupal 7 Module Development" book by adding them to the controller. Since load() is already there, it creates a nice symmetry.

"you also define "view modes" for the entity that is not used anywhere in your code"

True. That could be left out.

"as i see it the only benefit of entities is enabling field api ."

There are reasons to create entities without fields. The file and taxonomy_vocabulary entities in core are not fieldable. At a minimum, the purpose of creating an entity is to tell Drupal about your database table. Then you get loading and caching and a common interface with other entities, to some extent.

Neal

Mile23’s picture

You know, I'm glad people are posting examples here, but there's an important thing missing: Entities don't automatically call hooks. Some of these examples miss the hooks for inserting/updating and deleting.

As an exercise, I tried to rectify all that for a generic example implementation. I ended up with class GenericCRUDEntityController, which subclasses DrupalDefaultEntityController. As far as I'm concerned, making a factory class like this would be the best practice for an API that's based on a factory class. However, once that happens, it's kind of not an example any more and becomes its own project.

Anyway, it's in a sandbox here: http://drupal.org/sandbox/Mile23/1289524 It re-implements NealB's example using this new factory subclass. It lacks tests.

If there's hue and cry I can try to make it more example-y.

yakoub’s picture

i think those hooks were designed to give developers implementation flexibility, and your controller class takes that flexibility away .

Mile23’s picture

Yes, the entity API hook system was designed so that developers could, for instance, respond to an entity being inserted. But if you look at core, the places where hook_entity_insert is invoked is in modules which implement their own entities, not the entity system itself.

For instance, look at node_save(). About halfway down, it does this:

module_invoke_all('entity_' . $op, $node, 'node');

This is an example of a module invoking hook_entity_insert(), because even though hook_entity_insert() is clearly part of the published API, the entity system does not actually do it.

Thus, if you want to teach someone how to make an entity, you also have to teach them how to fill the promise that the API makes.

Developers rolling their own CRUD system can of course ignore GenericCRUDEntityController and make their own, or subclass and override it.

And, also: I added a hook system so that developers could implement their own hook API in a subclass. For instance, node has its own API of hooks, such as hook_node_insert(). This could easily be re-implemented in GenericCRUDEntityController by subclassing and overriding invoke_hook().

yakoub’s picture

before that call there is
module_invoke_all('node_' . $op, $node, 'node');
whose to say which should come first ?
maybe some particular module needs to perform certain operations before or after that certain hook .

but more important there is also the field_attach calls that you make in your code which as well should be left for the developer to decide when and how to call them .

other wise if people don't want that flexibility then they might as well use nodes and forget about implementing their own entity .

Mile23’s picture

"before that call there is module_invoke_all('node_' . $op, $node, 'node'); whose to say which should come first ?"

This document, for one: http://api.drupal.org/api/drupal/modules--node--node.api.php/group/node_...

"but more important there is also the field_attach calls that you make in your code which as well should be left for the developer to decide when and how to call them."

Yes and no. If I'm implementing an entity, then I might choose to do it a different way than some other implementation, but the calling order should reflect the API. Other modules should be able to act on your entities, and calling the hooks in the right order is the way to do this.

These kinds of issues are why it's hard to make a good example of entity API, and why I decided to make a generic implementation that could be uniform and would illustrate the steps. 'For real' projects will no doubt scrap this code, or override it, for code that's more efficient and suited to the needs of the project.

Alan D.’s picture

When developing these examples, it would be nice if you choose unique names. If the module and entity share the same name, you can not simple do a search and replace. :(

So maybe name all modules with the prefix "_example" but leave the entity name short?

rfay’s picture

It's really important to be able to distinguish between names that are important (that are forced to be the name they are for "magic naming" functionality, and names that are chosen by the programmer. For that reason, we try to distinguish between module name and things like entity name, etc.

rfay’s picture

Status: Needs work » Needs review
FileSize
15.23 KB
PASSED: [[SimpleTest]]: [MySQL] 2,291 pass(es). View

OK, I have *finally* spent some time with this and tried to consolidate some of the ideas in the earlier modules. I'd like to get this done and in, as it's a very valuable resource.

I went with a fieldable entity, with an explanation of how to do that, and with bundles, but with an explanation of how to omit.

The only thing I'm really stuck on right now (would appreciate some help) is that the "Manage display" doesn't properly handle things declared in hook_field_extra_fields(), although you can move them around in the manage fields area.

Will rework the tests once we have a model that can work. Thanks so much to all of you who have worked on this.

yakoub’s picture

there is a dpm in entity_example_basic_admin_page

rfay’s picture

Thanks - yeah, that needs to be replaced with the decent table view from one of the examples. I think it was yours that had it. Sorry I missed that. Plane ride ended too soon :-)

rfay’s picture

If any of you entity pioneers are willing to take a look (and maybe try out) #79 and let me know why the extra_fields are not configurable in the "manage display" it would be much appreciated. I'd really like to get past that, which I think is the only blocker; the work for #80 can easily be brought over from @yakoub's version.

gilzero’s picture

sub++

andypost’s picture

Status: Needs review » Needs work

Also I'd like to point to encapsulated save() method but no delete(). Suppose module should point why better to save and delete entity in controller class but load itself by the different way.

+++ b/entity_example/entity_example.moduleundefined
@@ -0,0 +1,393 @@
+    'bundles' => array(
+      'first_example_bundle' => array(
+        'label' => 'First example bundle',
+        // 'admin' key is used by the Field UI to provide field and
+        // display UI pages.
+        'admin' => array(
+          'path' => 'admin/structure/entity_example_basic/manage',
+          'access arguments' => array('administer entity_example_basic entities'),
+        ),
+      ),

It looks like troubles are caused by missed 'bundle argument' key so field api cant find a bundle

rfay’s picture

Status: Needs work » Needs review
FileSize
17.52 KB
PASSED: [[SimpleTest]]: [MySQL] 2,291 pass(es). View

The problem with "manage display" was that the #view_mode was not set in the $entity->content_array.

This version fixes things up; the dpm() is replaced with a nice table.

@andypost I didn't quite understand #84 - could you repeat (or offer a patch). Thanks!

IMO this is getting close.

yakoub’s picture

in hook_menu you should define for the entity page local tasks (tabs) for 'view' and 'edit'

rfay’s picture

I've added view and edit tabs, delete capability, and loads of tests (started out based on @yakoub's tests). Still tweaking the tests. Thanks all for the help!

rfay’s picture

FileSize
25.71 KB
FAILED: [[SimpleTest]]: [MySQL] 2,459 pass(es), 21 fail(s), and 1 exception(es). View

Here's my work in progress. I want to post it so I don't forget where I left it. There's still some work to be done debugging the tests.

Status: Needs review » Needs work

The last submitted patch, examples.entity_example_893842_88.patch, failed testing.

Mile23’s picture

Wow, good work on tackling that Randy.

@andypost: Strictly speaking the controller class doesn't need to do the save or delete, and load could be a class method. 6 of one, half dozen of another for this kind of project. But Drupal gives us a controller class so it's probably best to encapsulate.

Mile23’s picture

Status: Needs work » Needs review
FileSize
28.19 KB
FAILED: [[SimpleTest]]: [MySQL] 2,455 pass(es), 21 fail(s), and 1 exception(es). View

Q: How do you avoid your relatives at Xmas time?

A: See below. :-)

Some stuff I did to it:

  • Some work on the docblocks.
  • Refactored most of entity_example_basic_add() to $controller->create();
  • Added a class interface (since it's supposed to illustrate best practices and stuff..)
  • Added hook_entity_presave() to $controller->save(); There might be other missing hooks that I didn't catch.

We might consider moving the controller class to an .inc file, though I'm not clear on the benefits of having it in the dynamic cache system that files[] gives us.

The last submitted patch, 893842_entity_example.patch, failed testing.

rfay’s picture

Thanks! We should be getting close. IMO we don't have to move things like this into .inc files, as we're illustrating code, and not everybody even agrees about the constant separation of php files (except for code organization).

rfay’s picture

FileSize
28.2 KB
FAILED: [[SimpleTest]]: [MySQL] 2,474 pass(es), 9 fail(s), and 0 exception(es). View

#91 with the tests working...

Status: Needs review » Needs work

The last submitted patch, examples.entity_example_with_tests_893842_94.patch, failed testing.

rfay’s picture

Status: Needs work » Needs review
FileSize
28.18 KB
PASSED: [[SimpleTest]]: [MySQL] 2,483 pass(es). View

Oops. Doesn't run as /examples on the testbot.

Status: Needs review » Needs work

The last submitted patch, examples.entity_example_with_tests_893842_96.patch, failed testing.

rfay’s picture

Component: Other » Entity Example
Status: Needs work » Needs review

The fail was some kind of glitch, to this is NR. It does still need the links added to the parent directory.

rogical’s picture

Status: Needs review » Needs work
FileSize
39.44 KB

errors on patch #96:

rogical@rogical-desktop:/opt/development/test/sites/all/modules/examples$ git apply -v examples.entity_example_with_tests_893842_96.patch
Checking patch entity_example/entity_example.info...
Checking patch entity_example/entity_example.install...
Checking patch entity_example/entity_example.module...
Checking patch entity_example/entity_example.test...
examples.entity_example_with_tests_893842_96.patch:680: new blank line at EOF.
+
Applied patch entity_example/entity_example.info cleanly.
Applied patch entity_example/entity_example.install cleanly.
Applied patch entity_example/entity_example.module cleanly.
Applied patch entity_example/entity_example.test cleanly.
warning: 1 line adds whitespace errors.

errors on examples/entity_example/basic/add
aa

MichaelCole’s picture

Hi, RFay asked for some feedback on the entity_example module, so I created this issue. This is from the patch: http://drupal.org/node/893842#comment-5420018

Thoughts about this example:

Code clarity:
- It would help to split all entity code into it's own file (separate from form code).

- Move the Controller code to the top. It's the "lead" in the API story.

Code comments:
- What's the relationship between data in hook_entity_info() and the controller class.

- I still haven't read a good explanation of "bundles", although intuitively I understand them as types for my own entity.
- Bundles are for Entity, as CCK types are for Nodes. Nodes are Entities themselves.

- What is the data structure of an Entity? In EntityAPI, it's an object. In this example, it's a ?

- What is the life cycle of this data structure?
- How do I add a field to the db? hook_schema
- How do I add it to the data structure? Or how does Drupal load it automagically?
- How is that field's data loaded from the database?
- How is that field's data saved to the database?

- What is the life cycle of the controller?
- Created when?
- Creates new Entity structures when?

Etc:
- I'd like to understand how to declare bundles without using Features to import/export them.

My context of this feedback is:
- Entities are awesome, and are taking Drupal to the next level. Heck Yeah Awesome!
- The entity system is very hard to document and example.
- In my experience, that's an indication that the API needs another iteration or two to be complete.
- The mixture of hooks and classes doesn't help. Why does Drupal need hooks when it has the controller class?
- The entity system in D7 is the entity system we have, and my impression EntityAPI module is bridging the gap to the next version of the Entity API.
- I'm using the EntityAPI and Model as the basis for my work, but the Model example doesn't include fields, so I'm poking around other places.
- I just read through the code on this - I didn't verify it works.

A general question is: "What's the purpose of this example?" Does it serve the reader better to point them at Model or the commerce Line Item example?

A readme with links to these examples, and a statement: At the end of using this example, the reader should understand ... would be nice.

MichaelCole’s picture

FileSize
31.29 KB
PASSED: [[SimpleTest]]: [MySQL] 2,485 pass(es). View

Here's a patch that does some of this...

MichaelCole’s picture

Status: Needs work » Needs review
rfay’s picture

@MichaelCole, to help reviewers, could you mention exactly what you did in this patch, maybe post an interdiff? Thanks for your work on this!

Also, a new post worth mentioning here, and perhaps in the patch: http://www.trellon.com/content/blog/creating-own-entities-entity-api

lathan’s picture

For those who are looking for a Entity API solution visit http://drupal.org/project/model its a bootstrap module that you can use to get going.

rogical’s picture

Yes, I just created my own entity from model. And model is just created for helping creating your own entities.

I think there's no need to add entity example anymore.

rfay’s picture

Model actually came out of this issue. But we don't do contrib stuff here. Model is a great thing, but there are plenty of people who don't want to use a contrib, so this example will go in. If I'm not mistaken, the code points to Model.

Michelle’s picture

I think there's no need to add entity example anymore.

Sure there is. Right from the Model project page:

I did consider whether this module would be more suitable in the Example for Developers project but it makes use of functionality outside of core which excludes it.

Michelle

Alan D.’s picture

Actually I think that we need 4 examples:

  1. Core single bundle entity
  2. Core multi-bundle entity
  3. Entity API single
  4. Entity API multi

:)

If developing for a one-off project that doesn't need special integration, use core. It is faster and more stable. If programming for contrib, I would lean towards Entity API integration as you get a lot of features for free. However, just parse the issue queues of any module that uses the Entity API - ones like "Uninstall breaks site." is very common! This is an issue with every hanging off a cached class registry that simply reminds me as a stack of cards.

The only thing that I would love to see is the creation of template modules that can be used with doing 1 min of search 'n replace:

/**
 * Usage:
 * Replace __MODULE__ with your module name. Eg: bridge
 * Replace __ENTITY_NAME__ with the machine name of your entity. Eg: deck
 * etc,
 */

function __MODULE___entity_info() {
  $info['__ENTITY_NAME__'] = array(
    // A human readable label to identify our entity.
    'label' => t('Enter the entity name here'),
    ....
}

rfay’s picture

Just so everybody knows: Too much time and blood has already been spent on this. It's going in in mostly the form it's already taken. It's almost ready... I would have committed #96 or #101

rogical’s picture

  1. Core single bundle entity
  2. Core multi-bundle entity
  3. Entity API single
  4. Entity API multi

Just suggest to add:
5. query entity programmatically with field conditions
6. crud entity programmatically

rfay’s picture

Status: Needs review » Fixed

Never had a response from @MichaelCole about #101 , so I committed #96

http://drupalcode.org/project/examples.git/commitdiff/2b6382a

New issues, including whatever people think they want to do, are welcome, but this one is done. Followups in new issues.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.