You are here

public function VideoFilter::process in Video Filter 8

Performs the filter processing.

Parameters

string $text: The text string to be filtered.

string $langcode: The language code of the text to be filtered.

Return value

\Drupal\filter\FilterProcessResult The filtered text, wrapped in a FilterProcessResult object, and possibly with associated assets, cacheability metadata and placeholders.

Overrides FilterInterface::process

See also

\Drupal\filter\FilterProcessResult

File

src/Plugin/Filter/VideoFilter.php, line 52

Class

VideoFilter
Render Video Filter.

Namespace

Drupal\video_filter\Plugin\Filter

Code

public function process($text, $langcode) {
  if (preg_match_all('/\\[video(\\:(.+))?( .+)?\\]/isU', $text, $matches_code)) {

    // Load all codecs.
    $plugins = array_filter($this->settings['plugins']);
    if (empty($this->settings['plugins'])) {
      $plugins = $this->plugin_manager
        ->getDefinitions();
    }
    foreach ($matches_code[0] as $ci => $code) {
      $video = [
        'source' => $matches_code[2][$ci],
      ];

      // Pick random out of multiple sources separated by comma (,).
      if ($this->settings['allow_multiple_sources'] && strstr($video['source'], ',')) {
        $sources = explode(',', $video['source']);
        $random = array_rand($sources, 1);
        $video['source'] = $sources[$random];
      }

      // Find codec.
      foreach ($plugins as $plugin_info) {
        $id = !empty($plugin_info['id']) ? $plugin_info['id'] : $plugin_info;
        $plugin = $this->plugin_manager
          ->createInstance($id);
        $codec = [];
        $regexp = $plugin
          ->getRegexp();
        $codec['regexp'] = !is_array($regexp) ? [
          $regexp,
        ] : $regexp;

        // Try different regular expressions.
        foreach ($codec['regexp'] as $delta => $regexp) {
          if (preg_match($regexp, $video['source'], $matches)) {
            $video['codec'] = $codec;
            $video['codec']['delta'] = $delta;
            $video['codec']['ratio'] = $plugin
              ->getRatio();
            $video['codec']['control_bar_height'] = $plugin
              ->getControlBarHeight();
            $video['codec']['matches'] = $matches;
            $video['codec']['id'] = $id;
            break 2;
          }
        }
      }

      // Codec found.
      if (isset($video['codec'])) {

        // Override default attributes.
        if (!empty($matches_code[3][$ci]) && preg_match_all('/\\s+([a-zA-Z_]+)\\:(\\s+)?([0-9a-zA-Z\\/]+)/i', $matches_code[3][$ci], $matches_attributes)) {
          foreach ($matches_attributes[0] as $ai => $attribute) {
            $video[$matches_attributes[1][$ai]] = $matches_attributes[3][$ai];
          }
        }

        // Use configured ratio if present, otherwise use that from the codec,
        // if set. Fall back to 1.
        $ratio = 1;
        if (!empty($video['ratio']) && preg_match('/(\\d+)\\/(\\d+)/', $video['ratio'], $tratio)) {

          // Validate given ratio parameter.
          $ratio = $tratio[1] / $tratio[2];
        }
        elseif (!empty($video['codec']['ratio'])) {
          if (is_float($video['codec']['ratio']) || is_int($video['codec']['ratio'])) {
            $ratio = $video['codec']['ratio'];
          }
          elseif (preg_match('/(\\d+)\\s*\\/\\s*(\\d+)/', $video['codec']['ratio'], $cratio)) {
            $ratio = $cratio[1] / $cratio[2];
          }
        }

        // Sets video width & height after any user input has been parsed.
        // First, check if user has set a width.
        if (isset($video['width']) && !isset($video['height'])) {
          $video['height'] = $this->settings['height'] != '' ? $this->settings['height'] : 400;
        }
        elseif (isset($video['height']) && !isset($video['width'])) {
          $video['width'] = $video['height'] * $ratio;
        }
        elseif (isset($video['height']) && isset($video['width'])) {
          $video['width'] = $video['width'];
          $video['height'] = $video['height'];
        }
        elseif (!isset($video['height']) && !isset($video['width'])) {
          $video['width'] = $this->settings['width'] != '' ? $this->settings['width'] : 400;
          $video['height'] = $this->settings['height'] != '' ? $this->settings['height'] : 400;
        }

        // Default value for control bar height.
        $control_bar_height = 0;
        if (isset($video['control_bar_height'])) {

          // Respect control_bar_height option if present.
          $control_bar_height = $video['control_bar_height'];
        }
        elseif (isset($video['codec']['control_bar_height'])) {

          // Respect setting provided by codec otherwise.
          $control_bar_height = $video['codec']['control_bar_height'];
        }

        // Resize to fit within width and height repecting aspect ratio.
        if ($ratio) {
          $scale_factor = min([
            $video['height'] - $control_bar_height,
            $video['width'] / $ratio,
          ]);
          $video['height'] = round($scale_factor + $control_bar_height);
          $video['width'] = round($scale_factor * $ratio);
        }
        $video['align'] = isset($video['align']) && in_array($video['align'], [
          'left',
          'right',
          'center',
        ]) ? $video['align'] : NULL;

        // Let modules have final say on video parameters.
        \Drupal::moduleHandler()
          ->alter('video_filter_video', $video);
        $iframe = $plugin
          ->iframe($video);
        $flash = $plugin
          ->flash($video);
        $html = $plugin
          ->html($video);

        // Add CSS classes to elements.
        $video['classes'] = $this
          ->classes($video);

        // iframe.
        if (!empty($iframe['src'])) {
          $video['iframe'] = $iframe;
          $element = [
            '#theme' => 'video_filter_iframe',
            '#video' => $video,
          ];
          $replacement = \Drupal::service('renderer')
            ->render($element);
        }
        elseif (!empty($flash['src'])) {
          $defaults = [
            'movie' => $video['source'],
            'wmode' => 'transparent',
            'allowFullScreen' => 'true',
          ];
          $flash['properties'] = array_merge($defaults, is_array($flash['properties']) && count($flash['properties']) ? $flash['properties'] : []);
          $video['flash'] = $flash;
          $element = [
            '#theme' => 'video_filter_flash',
            '#video' => $video,
          ];
          $replacement = \Drupal::service('renderer')
            ->render($element);
        }
        elseif (!empty($html)) {
          $video['html'] = $html;
          $element = [
            '#theme' => 'video_filter_html',
            '#video' => $video,
          ];
          $replacement = \Drupal::service('renderer')
            ->render($element);
        }
        else {

          // Plugin doesn't exist.
          $replacement = '<!-- VIDEO FILTER - PLUGIN DOES NOT EXISTS FOR: ' . $video['source'] . ' -->';
        }
      }
      else {
        $replacement = '<!-- VIDEO FILTER - INVALID CODEC IN: ' . $code . ' -->';
      }
      $text = str_replace($code, $replacement, $text);
    }
  }
  return new FilterProcessResult($text);
}