543d498624a1d8eaf35a696157b44fad1a462fbf
[yaffs-website] / web / modules / contrib / embed / src / Access / EmbedButtonEditorAccessCheck.php
1 <?php
2
3 namespace Drupal\embed\Access;
4
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;
12
13 class EmbedButtonEditorAccessCheck implements AccessInterface {
14
15   /**
16    * Checks whether the embed button is enabled for the given text editor.
17    *
18    * Returns allowed if the editor toolbar contains the embed button or neutral
19    * otherwise.
20    *
21    * @code
22    * pattern: '/foo/{editor}/{embed_button}'
23    * requirements:
24    *   _embed_button_filter_access: 'TRUE'
25    * @endcode
26    *
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.
31    *
32    * @return \Drupal\Core\Access\AccessResultInterface
33    *   The access result.
34    */
35   public function access(RouteMatchInterface $route_match, AccountInterface $account) {
36     $parameters = $route_match->getParameters();
37
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']);
42
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) {
47         return $access_result
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));
54       }
55     }
56
57     // No opinion, so other access checks should decide if access should be
58     // allowed or not.
59     return $access_result;
60   }
61
62   /**
63    * Checks if the embed button is enabled in an editor configuration.
64    *
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.
69    *
70    * @return \Drupal\Core\Access\AccessResultInterface
71    *   The access result.
72    *
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.
76    */
77   protected function checkButtonEditorAccess(EmbedButtonInterface $embed_button, EditorInterface $editor) {
78     if ($editor->getEditor() !== 'ckeditor') {
79       throw new HttpException(500, 'Currently, only CKEditor is supported.');
80     }
81
82     $has_button = FALSE;
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'])) {
87           $has_button = TRUE;
88           break 2;
89         }
90       }
91     }
92
93     return AccessResult::allowedIf($has_button)
94       ->addCacheableDependency($embed_button)
95       ->addCacheableDependency($editor);
96   }
97
98 }