Add support for more entity types

Created on 13 February 2024, 9 months ago
Updated 4 March 2024, 9 months ago

Could you point me to the docs where it says how to use this for custom entities?

✨ Feature request
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States frob US

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @frob
  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    Hi frob!

    In order to support a custom entity type, make sure that your entity type has the following:

    • Is a content entity type
    • Has a numeric id key
    • Supports bundles
    • Has a canonical link template
    • Is revisionable

    Expressed in terms of the annotation these are the keys that you need to integrate with access policy. (Note: other keys have been removed for brevity).

    /**
     * @ContentEntityType(
     *   id = "example",
     *   label = @Translation("Example"),
     *   revision_data_table = "example_field_revision",
     *   entity_keys = {
     *     "revision" = "vid",
     *   },
     *   bundle_entity_type = "example_type",
     *   links = {
     *     "canonical" = "/example/{entity_id}",
     *   }
     * )
     */
    class ExampleEntity extends ContentEntityBase {
    
    }
    
  • πŸ‡ΊπŸ‡ΈUnited States frob US

    I see, that is what I thought when I read the code. I have a custom entity 'announcement' that doesn't have revisions or a canonical reference. Looks like if I add it to AccessPolicyInformation::isParagraph like this.

        return $entity_type->id() == 'paragraph' || $entity_type->id() == 'announcement';
    

    It might make sense to turn isParagraphinto an api that allows developers to specifically add custom entities to the allowed entities list.

  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    I had considered adding a hook like hook_access_policy_entity_types_alter($entity_types). However, I decided against it (for the time being) because Access Policy makes assumptions based on those features and allowing developers to bypass those could lead to some unpredictable bugs which I just don't have the bandwidth to support.

    I can say that for your use case, it's safe to add a canonical link to your entity type. You could even just have it point to the edit form. For example, this is how media does it.

     *   links = {
     *     "canonical" = "/media/{media}/edit",
     *   }
    

    To give some context, I added that requirement so that it would support both Dynamic and Manual selection modes. If want to use Manual selection mode you'll need to have a canonical link.

    In regards to making revisions (and bundles) optional by adding an API. That is unexplored territory and each will need its own issue and test coverage. The access_policy field for example is a base field that supports revisions; would it still behave properly if it was added to an entity without revisions?

    So while I completely understand the motivation to add a hook of some kind, there's simply a lot more that needs to be investigated first.

    But definitely apply a local patch to the module and let me know what issues you run into. I'd be very curious to learn what you find.

  • First commit to issue fork.
  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    I spent some more time investigating this, specifically finding a way to relax the entity type constraints while also avoiding unpredictable behavior caused by entity types provided by contrib. The original culprit was the Crop module which triggered fatal errors. You can see the issue here: https://www.drupal.org/project/access_policy/issues/3384483 πŸ› Unable to run access_policy_update_9001 Fixed .

    Here is a patch with some changes that opens up access policy to other entity types. I removed the revision requirement and copied some logic from the Display modes pages. This seemed to make a lot of sense in this context. All my automated tests passed and the crop entity was still excluded. Yay!

    I still need to add tests for non-revisionable entity types but this is the direction that I would go in. Please feel free to give it a try and let me know if you run into any issues.

  • Assigned to partdigital
  • πŸ‡ΊπŸ‡ΈUnited States partdigital
  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    partdigital β†’ changed the visibility of the branch 3421025-how-to-use to hidden.

  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    I've opened an MR. I still want to add some automated tests but this will probably be the final production code.

    To summarize the changes, in order to Integrate with access policy, your entity type must

    • Be a content entity type
    • Support Bundles
    • Have a view builder class
    • Have a route for the field_ui_base_route property

    If you want to support Manual selection mode:

    • You need to have a canonical link template.
    • Have a local task defined for the route associated with that link template.

    I tested this on core and contrib including:

    Comments
    Unfortunately I had to disable support for comments because of this issue: https://www.drupal.org/project/drupal/issues/2879087 πŸ“Œ Use comment access handler instead of hardcoding permissions Needs work

    Profile
    This supports access policy, however it only supports Dynamic mode because no local tasks have been defined for that entity. There is an issue to address it: https://www.drupal.org/project/profile/issues/3139127 β†’

  • πŸ‡ΊπŸ‡ΈUnited States partdigital
  • Pipeline finished with Skipped
    9 months ago
    #96821
  • Status changed to Fixed 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    The MR has been merged. To add support for a custom entity type, your entity type must:

    • Be a content entity type
    • Have a valid entity id key
    • Have a view builder class
    • Have a route for the field_ui_base_route property
    • Support Bundles

    Here is an example expressed in terms of annotation:

    /**
     * @ContentEntityType(
     *   id = "example",
     *   label = @Translation("Example"),
     *   handlers = {
     *     "view_builder" = "Drupal\example\ExampleViewBuilder",
     *   },
     *   entity_keys = {
     *     "id" = "id",
     *   },
     *   bundle_entity_type = "example_type",
     *   field_ui_base_route = "entity.example.edit_form",
     * )
     */
    class ExampleEntity extends ContentEntityBase {
    
    }
    
  • Issue was unassigned.
  • Status changed to Active 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States frob US

    I ended up going a different direction.

  • Status changed to Fixed 9 months ago
  • πŸ‡ΊπŸ‡ΈUnited States frob US

    Sorry, I didn't mean to change all the fields.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024