From 74686c7a85ea9b36abba5a41edb6b05d2ad783ad Mon Sep 17 00:00:00 2001
From: Aaron Winborn <aaron@aaronwinborn.com>
Date: Tue, 1 Nov 2011 17:29:06 -0400
Subject: [PATCH] Issue #1293908 by becw, aaron: Respect file type
 restrictions in media browser library view.

---
 js/media.browser-views-ajax.js |   24 +++++++++
 media.module                   |  101 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+), 0 deletions(-)
 create mode 100644 js/media.browser-views-ajax.js

diff --git a/js/media.browser-views-ajax.js b/js/media.browser-views-ajax.js
new file mode 100644
index 0000000..91bc05a
--- /dev/null
+++ b/js/media.browser-views-ajax.js
@@ -0,0 +1,24 @@
+/**
+ * @file
+ *
+ * Modifies Views ajax to add the media browser parameters.
+ */
+(function ($) {
+
+  Drupal.behaviors.mediaBrowserViewsAJAX = {
+    attach: function (context, settings) {
+      for (var view in Drupal.settings.views.ajaxViews) {
+        Drupal.settings.views.ajaxViews[view].types = '';
+        for (var type in Drupal.settings.media.browser.library.types) {
+          Drupal.settings.views.ajaxViews[view].types += Drupal.settings.media.browser.library.types[type] + ' ';
+        }
+        Drupal.settings.views.ajaxViews[view].schemes = '';
+        for (var scheme in Drupal.settings.media.browser.library.schemes) {
+          Drupal.settings.views.ajaxViews[view].schemes += Drupal.settings.media.browser.library.schemes[scheme] + ' ';
+        }
+        Drupal.settings.views.ajaxViews[view].file_extensions = Drupal.settings.media.browser.library.file_extensions;
+      }
+    }
+  };
+
+})(jQuery);
diff --git a/media.module b/media.module
index 96199e6..8836e62 100644
--- a/media.module
+++ b/media.module
@@ -1179,3 +1179,104 @@ function media_load_all_exports($module, $directory, $extension, $name = NULL) {
 
   return $return;
 }
+
+/**
+ * Return the parameters required for altering the default media browser view.
+ */
+function media_browser_view_params() {
+  $params = &drupal_static(__FUNCTION__, array());
+
+  if (empty($params)) {
+    foreach (array('types', 'schemes') as $param) {
+      // If we're coming via views/ajax, the params will be in $_POST.
+      if (isset($_POST[$param])) {
+        $post_params = explode(' ', $_POST[$param]);
+        foreach ($post_params as $post_param) {
+          $params[$param][$post_param] = $post_param;
+        }
+      }
+      else {
+        // Otherwise, they'll be in $_GET.
+        module_load_include('inc', 'media', 'includes/media.browser');
+        $browser_params = media_set_browser_params();
+        if (isset($browser_params[$param])) {
+          foreach ($browser_params[$param] as $browser_param) {
+            $params[$param][$browser_param] = $browser_param;
+          }
+        }
+      }
+    }
+    if (isset($_POST['file_extensions'])) {
+      $params['file_extensions'] = $_POST['file_extensions'];
+    }
+    else {
+      module_load_include('inc', 'media', 'includes/media.browser');
+      $browser_params = media_set_browser_params();
+      if (isset($browser_params['file_extensions'])) {
+        $params['file_extensions'] = $browser_params['file_extensions'];
+      }
+    }
+  }
+  return $params;
+}
+
+/**
+ * Implementation of hook_views_pre_build().
+ *
+ * Alter the media browser library view to restrict the type drop-down based on
+ * the media browser parameters. Note that the parameters come from the HTTP
+ * query and should be treated as user input.
+ */
+function media_views_pre_build (&$view) {
+  if ($view->name == 'media_default') {
+    $params = media_browser_view_params();
+    if (isset($params['types'])) {
+      $view->filter['type']->options['value'] = $params['types'];
+      $view->filter['type']->options['expose']['reduce'] = 1;
+    }
+  }
+}
+
+/**
+ * Implements hook_views_query_alter().
+ *
+ * Alter the media browser library view to exclude files based on the media
+ * browser parameters. Note that the parameters come from the HTTP query and
+ * should be treated as user input.
+ */
+function media_views_query_alter(&$view, &$query) {
+  if ($view->name == 'media_default') {
+    drupal_add_js(drupal_get_path('module', 'media') . '/js/media.browser-views-ajax.js');
+
+    $params = media_browser_view_params();
+
+    // Restrict files by type.
+    if (!empty($params['types'])) {
+      $where_group = $query->set_where_group();
+      $field = $query->base_table . '.type';
+      $query->add_where($where_group, $field, $params['types'], 'IN');
+    }
+
+    // Restrict files by URI scheme.
+    if (!empty($params['schemes'])) {
+      $where_group = $query->set_where_group('OR');
+      $field = $query->base_table . '.uri';
+      foreach ($params['schemes'] as $scheme) {
+        $value = db_like($scheme) . '%';
+        $query->add_where($where_group, $field, $value, 'LIKE');
+      }
+    }
+
+    // Restrict files by extension.
+    if (!empty($params['file_extensions'])) {
+      $where_group = $query->set_where_group('OR');
+      $field = $query->base_table . '.uri';
+      foreach (explode(' ', $params['file_extensions']) as $extension) {
+        // @todo MySQL is generally case insensitve, but case may be a problem
+        //   on other databases.
+        $value = '%.' . db_like(trim($extension, '.'));
+        $query->add_where($where_group, $field, $value, 'LIKE');
+      }
+    }
+  }
+}
-- 
1.7.5.4

