I propose the entity template set $entity_type and remove the need for an intermediary custom base class for each entity type. This way all Drupal entities will be supported.
Background
This module does a lot of really great things to help speed up development. However, there is one thing that confuses me on how it works. And that is how this module doesn't support all Drupal entities out of the box. That is, unless you create a custom base class that minimally contains a __construct method to load the entity.
It's nice that this modules provides this base class for nodes and users, and the additional modules provide commerce, message, and organic group entities. But what was very confusing is that it doesn't work out of the box for taxonomy terms or other custom entities (such as ones created with ECK). This is confusing because entity_metadata_wrapper() supports them, as do other functions from the entity module (entity_load(), entity_load_single(), etc).
What was even more confusing is that the module let me create custom wrappers for taxonomy terms and ECK entities. But they didn't work because they couldn't load the entities. There wasn't any warning when I created the wrappers with drush, and the project page even seemed to indicate that all entities were supported.
6. This process works for other entity types, as well: Users, Commerce Products, OG Memberships, Messages etc. Just follow the command pattern: drush wrap ENTITY_TYPE
When I dug into the code, I was further confused because the "supported" entities seemed to be custom entity loading within their __construct() methods (node_load, user_load, etc.). Why is the code using these specific loading methods instead of using Entity API's unified method of loading entities: entity_load_single()? I see that WdEntityWrapper falls back to this, but it also requires that you have set the entity type as the first parameter. This is actually a violation of good OOP practices because the children classes (WdNodeWrapper, WdUserWrapper, etc.) don't have this as the first parameter!
Using entity_load_single() in WdEntityWrapper for all loading lets us now support all Drupal entities.
Proposal
- Change WdEntityWrapper __construct() to use a single parameter, $entity. This is what the children classes do already.
- Update the entity class template to set $entity_type rather than requiring an intermediary base class just to do the loading.
Comments
Comment #1
pianomansam CreditAttribution: pianomansam commentedHere is a quick patch file that does what I suggest. I've tested it on non-supported entities and nodes.
Comment #2
pianomansam CreditAttribution: pianomansam commentedComment #4
zengenuity CreditAttribution: zengenuity commentedThis seems like a good change. I'm going to wrap it in with another update I'm working on to add a command to generate entity base classes, so it may be a few weeks before I commit this.
Comment #5
brockfanning CreditAttribution: brockfanning commentedI agree this would be a good change. One thing that might be an issue is the static create() method. In WdEntityWrapper it creates a new WdEntityWrapper object. If I understand right, with this change, the new object would have no idea what entity type to use. Probably an easy fix, but just bringing it up.
Comment #6
zengenuity CreditAttribution: zengenuity commented@brockfanning is correct that the create functionality is an issue. I've reworked the patch to make that functional, and also fixed a several other spots in the provided base classes where it was failing after the changes.
The main issue with this change is that it's going to break sites with a custom entity base class. Since there are only 53 reported installs of this module, and since it only affects users who have written a custom base class and not ones that are only using generated bundle classes, I'm fine with making the API-breaking change. I'll put instructions for fixing at the top of the release notes. (People need to add the $entity_type variable, and remove their constructor, as was done with the provided base classes.)
The specific issue that will break current sites is that I had to reverse the parameters in WdEntityWrapper's constructor. You can now optionally pass an entity type in. If you do, it uses that. Otherwise, it reads from the variable that @pianomansam added.
I just ran a test with this patch applied, and I was able to create an entity with ECK, and then immediately generate wrapper classes for the bundles, without writing any base class. The generated wrapper classes work well, though they do not have methods for the properties of the entity. I'm going to work on that in #2455063: Add scaffold tool for new entity base classes.
Comment #7
zengenuity CreditAttribution: zengenuity commentedComment #9
zengenuity CreditAttribution: zengenuity commentedComment #11
zengenuity CreditAttribution: zengenuity commentedActually, now I've thought of a way to support base entity wrappers written before the constructor change. I've added this code to the beginning of
WdEntityWrapper::__construct()
.I just dropped this latest version into a project where I wrote several custom entity base wrapper classes as well as used node, user and OG membership bundle wrappers, and it didn't blow up. Functionality all seems intact. Also passes tests on the rewritten base classes included in the patch.
Comment #12
zengenuity CreditAttribution: zengenuity commentedI would appreciate it if some people could test these changes with existing projects or in-development projects where you already have some code written against the module, and report back whether it upgrades cleanly. I think it should at this point.
Comment #13
brockfanning CreditAttribution: brockfanning commentedI'm only in the in-development stage at this point, but I tried updating the module code with this patch, and things still worked. I also tried regenerating all the bundle classes I had generated previously and re-adding my custom changes, and it still worked well.
Comment #14
pianomansam CreditAttribution: pianomansam commentedMy two custom ECK entities, nodes, and taxonomy term all updated correctly and continue to work.
Comment #16
zengenuity CreditAttribution: zengenuity commentedThat's good enough for me. Committed. Thanks. I'll roll out out a new stable release with this change once I get the base entity class scaffolding tool done.
Comment #17
pianomansam CreditAttribution: pianomansam commentedGreat! Think you could roll #2464707: Image url helper function doesn't use image_style_url() into the update too?
Comment #18
zengenuity CreditAttribution: zengenuity commentedYes, that made it into the release: https://www.drupal.org/node/2468523