Field access

We've seen so far how the entity-level access works. However, a very similar system also exists for the fields inside entities. If you look inside the EntityAccessControlHandler, you'll note that there is a fieldAccess() method. This is called whenever access needs to be checked on a given field. For example, the FieldItemList::access() method does just that and delegates to the entity handler. Inside that, a call is made to checkFieldAccess(), which is what we can implement in our access handler subclass to customize access rules if we need to.

In a similar way, we have multiple operations that access can be checked for, but view will be your most common one. For example, when manually rendering an entity using the entity builder handler, as we've seen before, each field is being checked for access to the view operation. The same goes, this time, when an entity form is being built for the entity to edit it. Each field that is being rendered in the form gets checked for access first using the edit operation.

Again, we also have access hooks that other modules can implement to have a say in whether or not fields should be accessible:

In this case, we don't have an entity type or a field type-specific hook that we can implement. However, we have an alter hook that we can use to alter the access rules proposed by other modules.

Similar to the entity-level access handler, the field-level one takes its input from multiple sources—subclass and hook implementations. However, the order and combination of these are different. First, the access handler subclass is called (via the checkFieldAccess() method). Then, all the hook_entity_field_access() hooks are invoked to provide their input. Both of these in turn are then alterable by implementing hook_entity_field_access_alter(). Finally, the resulting access rules are combined into an orIf() and returned. So, the same principles are available as we saw at the entity level, but in a different order.