3 namespace Drupal\embed\Access;
5 use Drupal\Core\Access\AccessResult;
6 use Drupal\Core\Routing\RouteMatchInterface;
7 use Drupal\Core\Routing\Access\AccessInterface;
8 use Drupal\Core\Session\AccountInterface;
9 use Drupal\editor\EditorInterface;
10 use Drupal\embed\EmbedButtonInterface;
11 use Symfony\Component\HttpKernel\Exception\HttpException;
13 class EmbedButtonEditorAccessCheck implements AccessInterface {
16 * Checks whether the embed button is enabled for the given text editor.
18 * Returns allowed if the editor toolbar contains the embed button or neutral
22 * pattern: '/foo/{editor}/{embed_button}'
24 * _embed_button_filter_access: 'TRUE'
27 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
28 * The current route match.
29 * @param \Drupal\Core\Session\AccountInterface $account
30 * The currently logged in account.
32 * @return \Drupal\Core\Access\AccessResultInterface
35 public function access(RouteMatchInterface $route_match, AccountInterface $account) {
36 $parameters = $route_match->getParameters();
38 $access_result = AccessResult::allowedIf($parameters->has('editor') && $parameters->has('embed_button'))
39 // Vary by 'route' because the access result depends on the 'editor' and
40 // 'embed_button' route parameters.
41 ->addCacheContexts(['route']);
43 if ($access_result->isAllowed()) {
44 $editor = $parameters->get('editor');
45 $embed_button = $parameters->get('embed_button');
46 if ($editor instanceof EditorInterface && $embed_button instanceof EmbedButtonInterface) {
48 // Besides having the 'editor' route parameter, it's also necessary to
49 // be allowed to use the text format associated with the text editor.
50 ->andIf($editor->getFilterFormat()->access('use', $account, TRUE))
51 // And on top of that, the 'embed_button' needs to be present in the
52 // text editor's configured toolbar.
53 ->andIf($this->checkButtonEditorAccess($embed_button, $editor));
57 // No opinion, so other access checks should decide if access should be
59 return $access_result;
63 * Checks if the embed button is enabled in an editor configuration.
65 * @param \Drupal\embed\EmbedButtonInterface $embed_button
66 * The embed button entity to check.
67 * @param \Drupal\editor\EditorInterface $editor
68 * The editor entity to check.
70 * @return \Drupal\Core\Access\AccessResultInterface
73 * @throws \Symfony\Component\HttpKernel\Exception\HttpException
74 * When the received Text Editor entity does not use CKEditor. This is
75 * currently only capable of detecting buttons used by CKEditor.
77 protected function checkButtonEditorAccess(EmbedButtonInterface $embed_button, EditorInterface $editor) {
78 if ($editor->getEditor() !== 'ckeditor') {
79 throw new HttpException(500, 'Currently, only CKEditor is supported.');
83 $settings = $editor->getSettings();
84 foreach ($settings['toolbar']['rows'] as $row) {
85 foreach ($row as $group) {
86 if (in_array($embed_button->id(), $group['items'])) {
93 return AccessResult::allowedIf($has_button)
94 ->addCacheableDependency($embed_button)
95 ->addCacheableDependency($editor);