7334122938618a72dd0c51b5361d15c3cbfe3297
[yaffs-website] / web / modules / contrib / video_embed_field / modules / video_embed_wysiwyg / src / Plugin / Filter / VideoEmbedWysiwyg.php
1 <?php
2
3 namespace Drupal\video_embed_wysiwyg\Plugin\Filter;
4
5 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
6 use Drupal\Core\Session\AccountProxyInterface;
7 use Drupal\filter\FilterProcessResult;
8 use Drupal\filter\Plugin\FilterBase;
9 use Drupal\video_embed_field\Plugin\Field\FieldFormatter\Video;
10 use Drupal\video_embed_field\ProviderManagerInterface;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12 use Drupal\Core\Render\RendererInterface;
13
14 /**
15  * The filter to turn tokens inserted into the WYSIWYG into videos.
16  *
17  * @Filter(
18  *   title = @Translation("Video Embed WYSIWYG"),
19  *   id = "video_embed_wysiwyg",
20  *   description = @Translation("Enables the use of video_embed_wysiwyg."),
21  *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE
22  * )
23  */
24 class VideoEmbedWysiwyg extends FilterBase implements ContainerFactoryPluginInterface {
25
26   /**
27    * The video provider manager.
28    *
29    * @var \Drupal\video_embed_field\ProviderManagerInterface
30    */
31   protected $providerManager;
32
33   /**
34    * The renderer.
35    *
36    * @var \Drupal\Core\Render\RendererInterface
37    */
38   protected $renderer;
39
40   /**
41    * The current user.
42    *
43    * @var \Drupal\Core\Session\AccountProxyInterface
44    */
45   protected $currentUser;
46
47   /**
48    * VideoEmbedWysiwyg constructor.
49    *
50    * @param array $configuration
51    *   Plugin configuration.
52    * @param string $plugin_id
53    *   Plugin ID.
54    * @param mixed $plugin_definition
55    *   Plugin definition.
56    * @param \Drupal\video_embed_field\ProviderManagerInterface $provider_manager
57    *   The video provider manager.
58    * @param \Drupal\Core\Render\RendererInterface $renderer
59    *   The renderer.
60    * @param \Drupal\Core\Session\AccountProxyInterface $current_user
61    *   The current user.
62    */
63   public function __construct(array $configuration, $plugin_id, $plugin_definition, ProviderManagerInterface $provider_manager, RendererInterface $renderer, AccountProxyInterface $current_user) {
64     parent::__construct($configuration, $plugin_id, $plugin_definition);
65     $this->providerManager = $provider_manager;
66     $this->renderer = $renderer;
67     $this->currentUser = $current_user;
68   }
69
70   /**
71    * {@inheritdoc}
72    */
73   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
74     return new static($configuration, $plugin_id, $plugin_definition, $container->get('video_embed_field.provider_manager'), $container->get('renderer'), $container->get('current_user'));
75   }
76
77   /**
78    * {@inheritdoc}
79    */
80   public function process($text, $langcode) {
81
82     $response = new FilterProcessResult($text);
83
84     foreach ($this->getValidMatches($text) as $source_text => $embed_data) {
85       if (!$provider = $this->providerManager->loadProviderFromInput($embed_data['video_url'])) {
86         continue;
87       }
88
89       $autoplay = $this->currentUser->hasPermission('never autoplay videos') ? FALSE : $embed_data['settings']['autoplay'];
90       $embed_code = $provider->renderEmbedCode($embed_data['settings']['width'], $embed_data['settings']['height'], $autoplay);
91
92       // Add the container to make the video responsive if it's been
93       // configured as such. This usually is attached to field output in the
94       // case of a formatter, but a custom container must be used where one is
95       // not present.
96       if ($embed_data['settings']['responsive']) {
97         $embed_code = [
98           '#type' => 'container',
99           '#attributes' => [
100             'class' => ['video-embed-field-responsive-video'],
101           ],
102           'children' => $embed_code,
103         ];
104       }
105
106       // Replace the JSON settings with a video.
107       $text = str_replace($source_text, $this->renderer->render($embed_code), $text);
108
109       // Add the required responsive video library only when at least one match
110       // is present.
111       $response->setAttachments(['library' => ['video_embed_field/responsive-video']]);
112       $response->setCacheContexts(['user.permissions']);
113     }
114
115     $response->setProcessedText($text);
116     return $response;
117   }
118
119   /**
120    * Get all valid matches in the WYSIWYG.
121    *
122    * @param string $text
123    *   The text to check for WYSIWYG matches.
124    *
125    * @return array
126    *   An array of data from the text keyed by the text content.
127    */
128   protected function getValidMatches($text) {
129     // Use a look ahead to match the capture groups in any order.
130     if (!preg_match_all('/(<p>)?(?<json>{(?=.*preview_thumbnail\b)(?=.*settings\b)(?=.*video_url\b)(?=.*settings_summary)(.*)})(<\/p>)?/', $text, $matches)) {
131       return [];
132     }
133     $valid_matches = [];
134     foreach ($matches['json'] as $delta => $match) {
135       // Ensure the JSON string is valid.
136       $embed_data = json_decode($match, TRUE);
137       if (!$embed_data || !is_array($embed_data)) {
138         continue;
139       }
140       if ($this->isValidSettings($embed_data['settings'])) {
141         $valid_matches[$matches[0][$delta]] = $embed_data;
142       }
143     }
144     return $valid_matches;
145   }
146
147   /**
148    * Check if the given settings are valid.
149    *
150    * @param array $settings
151    *   Settings to validate.
152    *
153    * @return bool
154    *   If the required settings are present.
155    */
156   protected function isValidSettings($settings) {
157     foreach (Video::defaultSettings() as $setting => $default) {
158       if (!isset($settings[$setting])) {
159         return FALSE;
160       }
161     }
162     return TRUE;
163   }
164
165 }