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