Closed (fixed)
Project:
Relation
Version:
7.x-1.x-dev
Component:
Miscellaneous
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
23 Oct 2015 at 20:03 UTC
Updated:
18 Nov 2015 at 07:54 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
solotandem commentedAttached patch implements proposed resolution.
Comment #3
mikran commentedWe already have a function to get relation endpoints (
relation_get_endpoints) and this can be used here as well. It needs new parameters so that endpoints can be filtered by direction and probably also a parameter to control whether entities should be loaded or if entity_id is enough.What about non-binary relation types?
$endpoint_typeusually refers to entity type.$directionor something like that could be a less confusing name for the variable.Comment #4
solotandem commented@mikran, thanks for taking a look at this request. Let me address each of your comments in turn starting with the terminology one as this affects the other two.
Regarding the claim that "$endpoint_type usually refers to entity type," I would refer you to the module code where this term is used for precisely the purpose of identifying the 'source' and 'target' endpoints in each of these files:
For this reason, this term was used in the patch at hand.
Yes, there is a function to return the endpoints, plural, i.e. all of them. There is not a function to return a single endpoint or, as is needed here (for token use), the entity_id from a single endpoint. Adding a function appears quite reasonable.
Yes, what about non-binary relation types? As the module comment reads regarding arity, "In nearly all cases you will want to leave this set to 2." I have not used a relation with arity > 2 for production use. Not recalling the specifics of how they are handled, I tried these today in order to respond to this comment. Based on this trial, I would question whether the module supports a directional relation with arity > 2. In other words, can it distinguish between the source and target entities on a directional relation with arity > 2? Are the database columns sufficient to indicate the 'endpoint type'? Similarly, are the parameters to
relation_create()orrelation_save()sufficient for same? Andrelation_endpoint_field_presave()simply sets$item['r_index'] = $delta;. So are not the r_index columns being asked to serve the dual purpose of being:Does not the latter imply that the endpoint type is not being stored? (There are no other columns.)
For example, I created both directional and non-directional relations with arity = 4. Both had the same 4 node bundles for source (and target for the directional). For the non-directional relation, the database entries are fine. However, looking in the endpoints table, how am I to distinguish between those that are the source and the target endpoints for the directional relation? Is my code supposed to maintain this information?
Given that relation itself does not appear to handle a directional relation with arity > 2, is not the statement
$r_index = $endpoint_type == 'source' ? 0 : 1;sufficient for the use cases it can handle, i.e. a binary relation that is directional? And for a non-directional relation there is really only a 'source' endpoint type whose r_index should be zero (for purposes of this new function).
As the 'todo' comment on this function indicates, it is left as an assignment for the reader to implement returning a specific endpoint among the source or target endpoints. All it is trying to do at this point is return the first one, which it does if I am not mistaken.
Another example, see relation_rules_get_specific_endpoints()
The above code returns all but the first endpoint if the endpoint_type is 'target'. It returns only the first endpoint if endpoint_type is 'source' and the relation is directional. How does that respect arity > 2 and/or directional relations?
In summary, does this 'need work' or is it ready for review and testing?
Comment #5
mikran commentedYou're right! My bad, I didn't verify my claim there.
Relation does not support many-to-many directional relations but one-to-many directional relations are supported. And really, implementation specifics are almost same as binary relations, r_index 0 is the source and r_index >0s are the targets in order. So you can do things like relation type: "album" (artist -> song a, song b, song c, ...). (this is the only bug issue I know of this kinds of relations #2110529: admin/content/relation is wrong for non binary directional relations, so nothing major)
I think it might have been the idea that one day many-to-many relations would be supported too but I doubt that will ever happen in D7 version.
Yes I think this is still 'needs work' on that point that target should work for any r_index >0 endpoint.
and
with
relation_get_endpointsyou could get all endpoint ids of given entity type from relation and use the first of the returned ids. That way it would work on one-to-many relations and it would improve the developer experience as therelation_get_endpointscould then be used to retrieve just source or target endpoints and optionally just entity ids instead of loaded entities. If 'target' endpoint is requested then we actually mean all r_index > 0 endpoints. New footprint (to keep it backwards compatible):relation_get_endpoints($relation, $entity_type = NULL, $endpoint_type = NULL, $load_entities = TRUE), right?This added
relation_get_endpoint_entityidfunction is basically escaping the endpoints-foreach as soon as matching endpoint is found but the relation is fully loaded already so I don't think the new function is really needed for performance reasons either.Comment #6
solotandem commented@mikran, I revised the patch as follows:
The reason for adding relation_get_endpoints_by_endpoint_type() is twofold:
I would remove the following from relation_get_endpoints() and simply return an empty array; if compatability with existing code is a concern, this should be reasonably safe as it would evaluate to FALSE. It is retained simply to respect the style of the existing code.
Comment #7
mikran commentedI really like the direction this is going now. And I agree it's better to return an empty array there. So this is RTBC from me when those @todos are fixed the way you recommended.
Comment #8
solotandem commentedThe attached patch removes the @todos:
if (empty($items))code block inrelation_get_endpoints()relation_get_endpoints_by_endpoint_type()fromrelation_rules_get_specific_endpoints().Comment #9
mikran commented