I have some improvements to suggest. I am unable to use entity_dependency in it's current form as it doesn't provide me with all the info I need about the dependencies. The thing is; entity_dependency is made aware of the things I need to know, it just doesn't record them anywhere.
The limitation goes right back to entity_dependency_add() which is called directly by most hook implementations, so even invoking the hooks provided by this module and handling the result with custom code is not sufficient. My current solution is to include a simplified version of this module into my module, which not only produces duplicate code, but does not benefit from the abstraction of this module and integration potentially provided by other modules.
So I would please ask you to include these changes so that I can direct my users to use this module, and for additional dependency handling to be handled through entity_dependency hooks.
I will outline the changes here.
In the method hasChildren() a module_invoke_all is performed, however it takes no notice of which module provided the dependencies, or rather in most cases on behalf of which module the dependencies were provided. I propose to record the module name in the dependency.
In a given dependency we have recorded 'type' and 'id', however this is sometimes not enough to identify an object in an array of provided objects. A delta value signifying which object it was in the array should be recorded, this will frequently be '0' since single objects are often given, however for implementations such as fields this is very useful. (If it it bothersome that delta is always included, even when not needed, an amendment can be made to the patch to only include it when necessary)
Similarly the name of the property whose value is recorded in 'id' should be recorded.
For the field implementation the 'langcode' and 'field_name' should be recorded. Together with the delta and property this gives us a full way to identify exactly where the dependency originated from. Additionally the field implementation should override the recorded 'module' to represent the correct field module, rather than simply 'field'.
Notes:
- This does not require changing a typical hook implementation for this module (as may be present in other modules). The only hook implementation that was changed was field_entity_dependencies().
- This does not compromise or affect current usage or behaviour of the module, as it adds information to an internal variable, but does not change or remove anything.
- All typical entity properties or field properties that create dependencies will now contain the new data.
- taxonomy_node_export_dependency() is the only hook/dependency that is not improved, partly because it doesn't use the entity_dependency_add() helper function, and partly because I can't think of a way to add improvements in line with this request to that dependency. It doesn't simply report on an entity property but uses PHP logic to make that determination.
- I named a variable $dep, because calling it $dependency was creating problems.
- Any hook implementation can add these new values manually, and they will not be overriden by the default handling.
Usage. The new data is not attached to entities, but can be retrieved like so:
<?php
$entities = array(array('type' => 'node', 'id' => $node->nid));
$iterator = new EntityDependencyIterator($entities);
for ($iterator->rewind(); $iterator->valid(); $iterator->next()) {
$iterator->hasChildren();
dpm($iterator->dependencies);
}
?>
I have attached a patch with the proposed changes.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | entity_dependency-more-dependency-data-2.patch | 4.76 KB | danielb |
| entity_dependency_more_dependency_data-1.patch | 3.34 KB | danielb |
Comments
Comment #1
danielb commentedI was thinking, there should be a way to handle situations where the property isn't directly on the entity like $entity->property but could be nested further down like $entity->something['property'] or even more complex.
There isn't any existing hook I'm aware of that would need this, but for example something like books would require a more complex system.
A potential solution would be to have a parents array, but I wonder if using a callback to set/get the property would be more flexible, something like that could even add value to the taxonomy hook I couldn't deal with earlier.
Comment #2
danielb commentedI've been thinking about it and looking over it, and the callback method seems too convoluted.
I think entity_dependency_add() should be able to handle a parents array, in addition to a simple string property
So if you have $node->property you can do:
entity_dependency_add($dependencies, $node, 'node', 'property');or
entity_dependency_add($dependencies, $node, 'node', array('property'));but if you have $node->book['property'] you would have to supply:
entity_dependency_add($dependencies, $node, 'node', array(array('book', 'property')));Note the nested array. The function would then dig down through those parents, and at each iteration distinguish between array/object syntax (sigh).
I'll come up with the code.
Still can't deal with that taxonomy hook, it's just too weird. Why can't taxonomy entities have a 'full mode' or something where all the relevant data is attached :/
Actually in reverse, when saving a term, it does in fact have a 'parent' property http://api.drupal.org/api/drupal/modules%21taxonomy%21taxonomy.module/fu...
Maybe that could still be handled then as $term->parent['delta'] hmmm~! I'm a little excited
It could be handled like so
you beauty, this data would be very handy to correct an import of a taxonomy term
Comment #3
danielb commentedThis is a new patch which includes the changes from the previous patches, and it adds the ability to entity_dependency_add() to handle an array of parents to target a property that is nested down further within the structure of the object. I've removed the check for the anonymous user id 0 because it was redundant with the !empty($value) check.
I am in the process of testing this functionality with a Book implementation at #1589344: Book module?
The taxonomy_entity_dependencies() function is also improved as per #2.
As before, the current usage should not be compromised, only added to.
Comment #4
danielb commentedI've kinda figured out what the limitation is that isn't allowing me to do the Book stuff properly. We're assuming that the property that relates the entity to the dependency is an entity id - and that just might not always be the case. Things can be related through other ways.
Unfortunately in the case of books (or anything that might be related by path/menus) even if we say in the dependency "it's related through mlid" (e.g.
$dependency['keys'] = array('mlid');or something like that) what can really be done by that in a automated reusable way? There is no $node->path['mlid'] or anything like that, it's all custom work. *sigh* I guess it's still worth noting that it's a connection made through mlid in the dependency just so the developer using it can detect that if they want to.Someone made a module for exporting books, I'm going to study it a little to see if I can get any more insight.
Comment #5
danielb commentedThese newly returned keys in the $dependency should be documented in the api file at hook_entity_dependencies().
In addition to the ones noted in these patches I've also devised a 'relationship' array key for a situation where there is a relationship held through something other than an entity id http://drupal.org/node/1589344#comment-6028322
There would ideally be support for another array key for a relationship not held through *any* property, but that requires custom callbacks to get and set the relationship value, but I'm not there yet. By 'support' I don't imply anything huge, just that it would be a documented convention, not anything actually used internally within this module.
Comment #6
danielb commentedI've made it a bit inconsistent by having fields return field_name/language/delta/property and some things return a properties array to drill down to the property. I think fields are a special case so it's ok, but it *could* be changed to give an array for consistency.
Now I'll reveal why these changes are awesome. You can change the property that stores the id like so:
Why would you want to do that? Because when you move entities to another site, or duplicate them on the current site, or god knows what, the entity ids can change and we can't rely on those anymore. So this is how you would update the dependency to reflect the new entity ids, as long as you have a way to reliably identify an entity other than by it's entity id (e.g. uuid, or through user input) the solution will become apparent. And since you can't rely on dependent entities coming first we can do things with this function like set placeholders until the dependent entity rears it's ugly head, and have a process that fixes things up at that point.
Comment #7
Remon commentedCan't agree more, that is EXACTLY where I'm stuck at now. Wondering if this patch is ever going to be looked at.