Entity relationships are the part of the Entity API that represent connections between different entities. For example, a post entity is related to the user entity that is the author of the post.
Each relationship that a type of entity has is represented by a class. Often the which entity(ies) an entity relates to is stored in a field one of the entity objects in the database. So let’s use the post author relationship as an example, since the ID of the user who is the author of a post is stored on the post_author
field of the WP_Post
object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /** * Represents the relationship between a Post and its author. * * @since 2.1.0 */ class WordPoints_Entity_Post_Author extends WordPoints_Entity_Relationship_Stored_Field { /** * @since 2.1.0 */ protected $storage_type = 'db'; /** * @since 2.1.0 */ protected $primary_entity_slug = 'post'; /** * @since 2.1.0 */ protected $related_entity_slug = 'user'; /** * @since 2.1.0 */ protected $related_ids_field = 'post_author'; /** * @since 2.1.0 */ public function get_title() { return __( 'Author', 'wordpoints' ); } } |
As you can see, we extend the WordPoints_Entity_Relationship_Stored_Field
class, since the ID of the post author is stored on an entity field as pointed out above. In other cases we might need to extend WordPoints_Entity_Relationship
directly, but here we can just let this class to most of the heavy lifting for us. So all we have to do is define a few properties and a simple method:
$storage_type
— How this entity relationship is stored. In this case, it is stored in the database, so the value of this field is'db'
.$primary_entity_slug
— The slug of the primary entity in the relationship. This in this case, it is the'post'
.$related_entity_slug
— The slug of the related entity. In the case of the post author relationship, the post author is a'user'
. For one-to-many relationships, we would append{}
to the slug of the related entity to indicate that it is an array, like this:'user{}'
. But in this case, each post has just one author.$related_ids_field
— The field on the primary entity object where the ID(s) of the related entity(ies) are stored. The ID of the user that is the author of a post is stored in thepost_author
field for that post.get_title()
— This method should return the title of the relationship. Note that you shouldn’t include the name of the primary arg here: use'Author'
, not'Post Author'
.
If your entity relationship isn’t stored on a field of the primary entity, you would need to do something like this instead:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * Represents the relationship of between a User and their Roles. * * @since 2.1.0 */ class WordPoints_Entity_User_Roles extends WordPoints_Entity_Relationship implements WordPoints_Entityish_StoredI { /** * @since 2.1.0 */ protected $primary_entity_slug = 'user'; /** * @since 2.1.0 */ protected $related_entity_slug = 'user_role{}'; /** * @since 2.1.0 */ protected $related_ids_field = 'roles'; /** * @since 2.1.0 */ protected function get_related_entity_ids( WordPoints_Entity $entity ) { return $entity->get_the_attr_value( $this->related_ids_field ); } /** * @since 2.1.0 */ public function get_title() { return __( 'Roles', 'wordpoints' ); } /** * @since 2.1.0 */ public function get_storage_info() { return array( 'type' => 'db', 'info' => array( 'type' => 'table', 'table_name' => $GLOBALS['wpdb']->usermeta, 'primary_id_field' => 'user_id', 'related_id_field' => array( 'type' => 'serialized_array', 'field' => 'meta_value', ), 'conditions' => array( array( 'field' => 'meta_key', 'value' => $GLOBALS['wpdb']->get_blog_prefix() . 'capabilities', ), ), ), ); } } |
You can see that we have to define two additional methods:
get_related_entity_ids()
— This method is passed the ID of the primary entity in a relationship, and should return the ID(s) of the related entity(ies). In the example above, the roles of a user actually are provided on theWP_User
object via theroles
property, even though they aren’t stored in a field on the user roles table.get_storage_info()
— This method needs to return information about how this entity is stored. In the example above, this is pretty complex, although it will usually be simpler than that. For more information about how to provide storage info for a relationship, check out the relationship storage info docs.
Once you’ve created your entity relationship class, you just need to register your class so that WordPoints knows that it exists:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /** * Register entities when the entities app is initialized. * * @since 1.0.0 * * @WordPress\action wordpoints_init_app_registry-apps-entities * * @param WordPoints_App_Registry $entities The entities app. */ function my_prefix_wordpoints_entities_init( $entities ) { $children = $entities->get_sub_app( 'children' ); $children->register( 'post', 'author', 'WordPoints_Entity_Post_Author' ); // More entities and entity children could be registered here. } add_action( 'wordpoints_init_app_registry-apps-entities' , 'my_prefix_wordpoints_entities_init' ); |
As you can see, we hook into the initialization of the entities registry, just as we do when registering a new entity. So you can register all of your entities and entity children in a single function. We just get the entity children class registry, which is a sub-app of the entities app, and register our relationship with the entity slug and a child slug that is unique for that entity.