Overview

In #3516648: Update `ExperienceBuilderController` to pass current user's XB high-level permissions to the client we added permission flags for config, and in #3516657: Update `ApiContentControllers::list()` to expose available content entity operations in `meta` we added link-rel meta operations for content.

But we need some way to provide permission flags for _creating_ content, as the meta operations require the content to exist already!

Proposed resolution

ExperienceBuilderController needs to:
1. Find all content entities that can use XB
2. For each of them, check 'create' operation requirements, per bundle if bundleable
3. Add the flags on drupalSettings.xb.permissions
3. Provide a UI label too

So, expected end result is something like:

diff --git a/src/Controller/ExperienceBuilderController.php b/src/Controller/ExperienceBuilderController.php
index 6cac6da64..cf0fa6ad2 100644
--- a/src/Controller/ExperienceBuilderController.php
+++ b/src/Controller/ExperienceBuilderController.php
@@ -122,6 +122,11 @@ HTML;
             'codeComponents' => $this->currentUser->hasPermission(JavaScriptComponent::ADMIN_PERMISSION),
             'contentTemplates' => $this->currentUser->hasPermission(ContentTemplate::ADMIN_PERMISSION),
           ],
+          'contentEntityCreateOperations' => [
+            // And of course add the necessary cacheability!
+            'xb_page' => $has_permission ? '<singular entity label>' : FALSE,
+            // …repeat for all other content entities that have an XB field
+          ],
         ],
       ],
       // Note: the tokens here are under our control, and this accepts no user

Expand \Drupal\Tests\experience_builder\Kernel\Controller\ExperienceBuilderControllerTest::testControllerExposedPermissions

User interface changes

The UI will be able to check access to show the pertinent operations.

CommentFileSizeAuthor
#12 3513566-12-alt.patch8.02 KBwim leers
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

penyaskito created an issue. See original summary.

penyaskito’s picture

I think we should still do this for page + node--article, even if #3498525: [META] Allow Canvas to be used on any content entity type (bundle), as long as it has certain entity type characteristics would definitely need to refactor this.

wim leers’s picture

Component: Page builder » Internal HTTP API
Issue tags: +beta blocker
Related issues: +#3513566: [later phase] [PP-1] Add generic create entity support (currently just `Page` content entities)

#4++

This is a beta blocker because without this, the following will always be visible:

Secondarily, this hard-blocked #3513566: [later phase] [PP-1] Add generic create entity support (currently just `Page` content entities).

wim leers’s picture

Title: Provide the client with permissions flags for create content » Provide the client with `create` operation access information similar to #3516657
Issue summary: View changes

Adjusted the proposal.

Note that this can assume a single XB field per content entity type+bundle, if that changes in #3526189: Spike: explore merits of one Canvas field per exposed slot in content templates, it'll be up to that issue to tweak the logic introduced here.

penyaskito’s picture

Assigned: Unassigned » penyaskito

penyaskito’s picture

Assigned: penyaskito » wim leers
Status: Active » Needs review

#4 might not be true and this might be future-proof .🎉

wim leers’s picture

Assigned: wim leers » penyaskito
Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs followup

Looks great!

One question, plus needs a follow-up for fixing cacheability.

Already approved 👍

penyaskito’s picture

Assigned: penyaskito » wim leers

Back to Wim per !1178.
I'm 50% on each option, so your call. The client UI will probably need to check the absence of the key anyway.

wim leers’s picture

Assigned: wim leers » Unassigned
Issue tags: -Needs followup
Related issues: +#3531858: CanvasController's response must vary by access result cacheability
StatusFileSize
new8.02 KB

I wanted to merge this, but on a final pass I'm afraid that the proposal was too incomplete after my adjustment in #6. 😅

The MR lets the XB UI know which content entities can be created, and what the label for that should be. But … it doesn't let you know where that is! 😅

So: this should AFAICT:

  1. use \Drupal\experience_builder\Resource\XbResourceLinkCollection
  2. point to experience_builder.api.content.create

(So: much like \Drupal\experience_builder\Controller\ApiContentControllers::getEntityOperations().)

This would then also immediately give us a nice way to pass the cacheability to make #3531858: CanvasController's response must vary by access result cacheability tighter scoped; otherwise that would have to go and modify the method this had just added.

Nope, that's because XB controls the "create entity" route: experience_builder.api.content.create — which is why simple booleans suffice, and the XB UI can then call its contentApi.createContent.

Attaching the patch that I had written locally, but which fails on the way it tries to pass the label via XbResourceLink's target attributes, because it's a translatable string, not a plain string.

  • wim leers committed 3bbebc8f on 0.x authored by penyaskito
    Issue #3529895 by penyaskito, wim leers: Provide the client with `create...
wim leers’s picture

jessebaker’s picture

Assigned: Unassigned » penyaskito
Status: Fixed » Needs work

I'm slightly too late to the party but I've just merged in upstream changes over at #3516641: Make the XB UI show only UI elements/operations available to the current user and the shape of the permissions object is now more complex as a result of this and as a result is going to make the FE code more complex to work around it.

Previously xb.permissions was a simple

interface permissions {
  [key: string]: boolean;
}

This made it easy for the FE to quickly assert if a user had or did not have a given permission by simply checking that list of booleans.

Can this new contentEntityCreateOperations object be moved into the root of drupalSettings.xb instead of inside the permissions object?

wim leers’s picture

#15: or … what about going from this which was merged:

"permissions": {
  …
  "contentTemplates": false,
  "contentEntityCreateOperations":{
    "xb_page":{"xb_page":"Page"},
     "node":{"article":"Amazing article"}
   }
}

to

"permissions": {
  …
  "contentTemplates": false,
  "create:xb_page": 'Page",
  "create:node:article": "Amazing article",
}

?

(Casting that string to a boolean is trivial.)

jessebaker’s picture

I think the format of contentEntityCreateOperations which was merged is more useful because it's easy to iterate over to build the list of "New x" buttons in the UI. Your proposal in #16 means, to build the list of "New x" buttons, I would have to iterate over the permissions object, filter to just keys that starts with 'create:' and then split the key by : to get the entity type and bundle info.

Maybe there is some value to having the permissions listed in the permissions object as you propose, but I think only if that was in addition to still having the info in the original format elsewhere e.g. drupalSettings.xb.contentEntityCreateOperations

"contentEntityCreateOperations":{
    "xb_page":{"xb_page":"Page"},
     "node":{"article":"Amazing article"}
   }

penyaskito’s picture

Status: Needs work » Needs review

Follow-up MR moving the contentEntityCreateOperations outside of xb.permissions

  • wim leers committed 0313cc0e on 0.x authored by penyaskito
    Issue #3529895 by penyaskito, wim leers, jessebaker: Follow-up: move the...
wim leers’s picture

Assigned: penyaskito » Unassigned
Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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