From 62f5a2ee0be200e20fa484271db370e6dfb0f570 Mon Sep 17 00:00:00 2001
From: Ron Shimshock <ron@shimshockgroup.com>
Date: Thu, 12 May 2016 13:58:27 -0500
Subject: [PATCH] Add input filter

---
 jw_player_filter/README.txt               |  83 ++++++++++++++++++
 jw_player_filter/jw_player_filter.info    |   4 +
 jw_player_filter/jw_player_filter.install |   6 ++
 jw_player_filter/jw_player_filter.module  | 137 ++++++++++++++++++++++++++++++
 4 files changed, 230 insertions(+)
 create mode 100644 jw_player_filter/README.txt
 create mode 100644 jw_player_filter/jw_player_filter.info
 create mode 100644 jw_player_filter/jw_player_filter.install
 create mode 100644 jw_player_filter/jw_player_filter.module

diff --git a/jw_player_filter/README.txt b/jw_player_filter/README.txt
new file mode 100644
index 0000000..a59f666
--- /dev/null
+++ b/jw_player_filter/README.txt
@@ -0,0 +1,83 @@
+JW Player Filter module.
+
+SUMMARY
+-----------------------------------------------
+The JW Player Filter module is an add-on for the JW Player module. The filter
+can be included in Drupal text formats to convert shortcode markup into
+embedded JW Player media players. This allows content contributors to add
+video and audio files inline in nodes and other entities, and have the final
+result render as a JW Player.
+
+
+REQUIREMENTS
+-----------------------------------------------
+* This module requires the JW Player module to be installed.
+
+
+INSTALLATION
+-----------------------------------------------
+* Install the module via drush or the site's Modules page (admin/modules).
+
+
+BASIC USAGE
+-----------------------------------------------
+The site administrator needs to configure the filter similar to other text
+format filters. Navigate to the Text formats page (admin/config/content/formats),
+select the text format to configure, and enable "JW Player Filter".
+
+It is important to set the JW Player Filter to be fairly early in the
+filter processing order (low weight), otherwise other filters will cause the
+JW Player to not render correctly.
+
+Once the filter has been applied to a text format, content can be created
+or edited to include embedded JW Player players inline. This is done using
+the [jwplayer] shortcode markup.
+
+Shortcode markup is a specially formatted text that the filter identifies
+as having JW Player parameters, and converts the codes into an embedded player.
+The shortcode always starts with a left bracket and 'jwplayer' (no quotes), and
+ends with a right bracket.
+
+In between the "[jwplayer" and "]" are a list of parameters, each separated by
+a vertical bar. The possible parameters are:
+
+* file = URL of the media file to be rendered (required).
+* image = URL of the preview image to be shown before playback starts.
+* preset = machine name of the JW Player preset created in Drupal.
+* image_style = machine name of the Drupal image style to be applied to the
+  preview image.
+* width = player width in pixels.
+* height = player height in pixels.
+
+Only "file" is a required parameter. All others are optional. There should be
+no spaces between vertical tabs, and no spaces within any parameter.
+
+
+EXAMPLES
+-----------------------------------------------
+Below are examples of how to use the JW Player filter shortcode markup:
+
+* Display a video called "my-video.mp4" using a preset with name of "My Preset"
+  (machine name is "my_preset"):
+
+  [jwplayer|file=http://mysite.com/my-video.mp4|preset=my_preset]
+
+* Display a video called "news_video.mp4", with a preview image named
+  "news_clip.jpg", image style named "16 by 9" (machine name of "16_by_9"),
+  and preset named "16x9 - 100% width" (machine name of "16x9_100_width"):
+
+  [jwplayer|file=http://mysite.com/sites/default/files/video/news_video.mp4|image=http://mysite.com/sites/default/files/image/news_clip.jpg|image_style=16_by_9|preset=16x9_100_width]
+
+* Display an audio file called "todays-podcast.mp3", with a player that has
+  a width of 400 pixels and a height of 33 pixels:
+
+  [jwplayer|file=http://mysite.com/todays-podcast.mp3|width=400|height=33]
+
+
+LIMITATIONS
+-----------------------------------------------
+1) For JW Player Filter to work correctly, it is necessary to disable filter
+   caching. This causes a performance hit on any page where the filter is used.
+   It is highly recommended to create a separate text format specifically for
+   embedding inline JW Player players. This will ensure site caching is not
+   disabled on pages where no players are present.
diff --git a/jw_player_filter/jw_player_filter.info b/jw_player_filter/jw_player_filter.info
new file mode 100644
index 0000000..62ccf46
--- /dev/null
+++ b/jw_player_filter/jw_player_filter.info
@@ -0,0 +1,4 @@
+name = JW Player Filter
+description = Substitute shortcode markup with an embedded media file in JW Player.
+core = 7.x
+dependencies[] = jw_player
diff --git a/jw_player_filter/jw_player_filter.install b/jw_player_filter/jw_player_filter.install
new file mode 100644
index 0000000..eb38132
--- /dev/null
+++ b/jw_player_filter/jw_player_filter.install
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Update functions for jw_player_filter.
+ */
diff --git a/jw_player_filter/jw_player_filter.module b/jw_player_filter/jw_player_filter.module
new file mode 100644
index 0000000..a519f61
--- /dev/null
+++ b/jw_player_filter/jw_player_filter.module
@@ -0,0 +1,137 @@
+<?php
+/**
+ * @file
+ * Hook implementations and functions for JW Player Filter.
+ */
+
+/**
+ * Implements hook_filter_info().
+ */
+function jw_player_filter_info() {
+  $filters = array();
+  $filters['jw_player_shortcode'] = array(
+    'title' => t('JW Player Filter'),
+    'description' => t('Substitutes [jwplayer] shortcode markup with an embedded media file.'),
+    'process callback' => 'jw_player_jw_player_shortcode_process',
+    'tips callback' => 'jw_player_jw_player_shortcode_tips',
+    'cache' => FALSE,
+    'weight' => 0,
+  );
+  return $filters;
+}
+
+/**
+ * Helper function to provide on screen tips for using the filter.
+ *
+ * @return string
+ *   String to be displayed within input filter tips.
+ */
+function jw_player_jw_player_shortcode_tips($filter, $format, $long = FALSE) {
+  return t('You may insert media with [jwplayer] shortcode markup. Available parameters include: <em>file</em>, <em>image</em>, <em>preset</em>, <em>image_style</em>, <em>width</em>, and <em>height</em>. A value for <em>file</em> is required, and <em>preset</em> and <em>image_style</em> must be machine names. No quotes should be included. Example: <strong>[jwplayer|file=http://site.com/video.mp4|preset=my_preset_settings]</strong>');
+}
+
+/**
+ * Callback function to perform the content processing.
+ *
+ * @param string $text
+ *   Text to be processed by input filter.
+ *
+ * @return string
+ *   Modified text where shortcodes have been replaced by rendered elements.
+ */
+function jw_player_jw_player_shortcode_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+  // Detect JW Player shortcode in the context.
+  $regex = '/(\[(\<br \/\>|\s)*jwplayer(\<br \/\>|\s)*(\|([a-zA-Z0-9_.\s]+=[-a-zA-Z0-9+.,\(\){}:&@#\/\?<>\"%=~_\'\"\s]+))*(\<br \/\>|\s)*\])/';
+  preg_match_all($regex, $text, $matches);
+  $shortcodes = $matches[0];
+  if (!empty($shortcodes)) {
+    foreach ($shortcodes as $shortcode) {
+      $element = _jw_player_filter_prepare_player($shortcode);
+      if (!$element) {
+        continue;
+      }
+
+      // Get the markup for this player.
+      $new_markup = render($element);
+
+      // Replace the original shortcode with the markup.
+      $text = str_replace($shortcode, $new_markup, $text);
+    }
+  }
+  return $text;
+}
+
+/**
+ * Prepares a render array for theme_jw_player_player().
+ *
+ * It is similar to jw_player_field_formatter_view()
+ * with modifications for inline shortcodes.
+ *
+ * @param string $shortcode
+ *   A shortcode string.
+ *
+ * @return array $element
+ *   A renderable array element.
+ *
+ * @see jw_player_field_formatter_view()
+ */
+function _jw_player_filter_prepare_player($shortcode) {
+  $shortcode = str_replace('<br />', '', $shortcode);
+  $shortcode = preg_replace('/\[(\s)*jwplayer(\s)*(\||\])/', '', $shortcode);
+  $shortcode = str_replace(']', '', $shortcode);
+  $args = preg_split('/\|/', $shortcode);
+  // Validate and add parameters.
+  $item = array();
+  foreach ($args as $fvar) {
+    $key_val = preg_split('/=/', $fvar, 2);
+    // Build element as long as keys are not empty.
+    if (!empty($key_val[0])) {
+      $key_val[0] = trim($key_val[0]);
+      // Strip out damaging auto link filter.
+      $key_val[1] = trim(preg_replace('/<(.)*>/U', '', $key_val[1]));
+      switch ($key_val[0]) {
+        case 'file':
+        case 'image':
+        case 'preset':
+        case 'image_style':
+          $item[$key_val[0]] = $key_val[1];
+          break;
+        default:
+          $item['option'][$key_val[0]] = $key_val[1];
+          break;
+      }
+    }
+  }
+  // Only render if a file exists.
+  $element = array();
+  if (isset($item['file'])) {
+    $element = array(
+      '#type' => 'jw_player',
+      '#player_type' => 'player',
+      '#theme' => 'jw_player_player',
+      '#preset' => isset($item['preset']) ? $item['preset'] : '',
+      '#image_style' => isset($item['image_style']) ? $item['image_style'] : '',
+      '#files' => array(
+        array(
+          'file' => $item['file'],
+          'image' => isset($item['image']) ? $item['image'] : '',
+        ),
+      ),
+    );
+    if (isset($item['option'])) {
+      foreach ($item['option'] as $key => $value) {
+        $element['#options'][$key] = $value;
+      }
+    }
+
+    // Build #html_id based on url, player type, and preset.
+    $items[0]['url'] = $item['file'];
+    $settings = array(
+      'player_type' => $element['#player_type'],
+      'jwplayer_preset' => $element['#preset'],
+    );
+    $element['#html_id'] = jw_player_build_player_id($items, $settings);
+  }
+
+  return $element;
+}
-- 
2.8.2

