The Entity Restrictions API was added in WordPoints version 2.2.0, and supersedes the WordPoints_Entity_Restricted_VisibilityI interface that was added in 2.1.0. It provides a way to restrict some users from viewing particular entities or their children (attributes and relationships). For example, posts can be private, so if a particular post doesn’t have a public status we need to check whether the user has the 'read_post' capability for it before we allow them to view it. In another example, some posts have password protected content, and so we need to check if a particular post’s content is password protected before we allow a user to view it.

Restriction Types #

There are currently two main kinds of restrictions, each of which is registered separately:

  • know — These are restrictions that should prevent the user from even knowing that the particular entity or entity child in question exists. (Private posts would be an example of an entity restricted in this way.)
  • view — These restrictions prevent a user from being able to view an entity or entity child. They might be able to know that it exists in some way, but they aren’t allowed to see it. (Password protected post content would be an example of this—the use knows that the post has content, but they aren’t allowed to see it unless they know the password.)

Additional types of restrictions may be added in the future.

Restriction Registries #

The registry for each type of restriction is a multilevel registry, where restrictions can be registered for a particular entity type, a particular child of a particular entity, or even as a generic restriction that applies to all entities.

The registries are children of the entity restrictions app:

Using the App #

However, you generally shouldn’t access these registries directly. The proper way to check if a user is restricted from an entity is to use the entity restrictions app directly, like this:

As you can see, calling the restriction getter on the app will return a restriction object that provides several methods for you. Before we discuss these methods further, note that this object is actually a wrapper that will contain all of the different relevant restrictions, and will check each of them internally when you call these methods. This allows you to do a simple check without having to loop over each of the restrictions yourself. Remember, multiple restrictions can apply to the same type of entity, and in addition, any generic restrictions will also be automatically included, as will the know restrictions when other restriction types are being checked (since a user can’t do anything else to an entity if they can’t even know that it exists!).

Restriction Interface #

Now, let’s take a look at the restriction interface, which will explain exactly what each of those methods we called in the above example does. The interface’s name is WordPoints_Entity_RestrictionI, and it is shared by all restriction types, including generic restrictions, restrictions for entity children, and the restriction wrapper returned by the app. The interface requires the following methods:

  • __construct( $entity_id, array $hierarchy ) — Each restriction is constructed with the ID of the entity in question (in the case of restrictions for entity children, this is the ID of the entity that is the parent of the child in question), and the hierarchy for that entity. The hierarchy is just the list of slugs leading to that entity or entity child. For the user entity, it would just be array( 'user' ), for a post’s content, it would be array( 'post\post', 'content' ).
  • applies() — This method checks whether the restriction applies to the particular entity that it was constructed with. For example, for a restriction for posts with private statuses, we would check if the post with that ID was public or not. If the post’s status wasn’t public, then we’d know that this restriction applied to that post, so this method would return true.
  • user_can( $user_id ) — This method checks if a particular user has the ability to view the entity in question, or to do whatever this particular restriction type is for. For a restriction for private posts, we’d check user_can( 'read_post', $user_id, $post_id ), for example. If the user could, we’d return true.

Example Restriction #

Here is the post status restriction, for an example:

As you can see, we’ve consolidated some of the logic into the constructor, to reduce duplication between the user_can() and applies() methods.

Registering Restrictions #

Restrictions of each type are stored in separate registries, so each type of restriction has to be registered separately. Here is an example of registering some know restrictions, but just by changing know to view in each location, you can register view restrictions instead.