diff --git a/includes/media.fields.inc b/includes/media.fields.inc index 5a57f86..f0632ec 100644 --- a/includes/media.fields.inc +++ b/includes/media.fields.inc @@ -108,8 +108,8 @@ function media_field_widget_form(&$form, &$form_state, $field, $instance, $langc '#process' => array_merge($element_info['#process'], array('media_field_widget_process')), '#media_options' => array( 'global' => array( - 'types' => array_filter($widget_settings['allowed_types']), - 'enabledPlugins' => array_filter($instance['widget']['settings']['browser_plugins']), + 'types' => $widget_settings['allowed_types'], + 'enabledPlugins' => $instance['widget']['settings']['browser_plugins'], 'schemes' => $widget_settings['allowed_schemes'], 'file_directory' => isset($field_settings['file_directory']) ? $field_settings['file_directory'] : '', 'file_extensions' => isset($field_settings['file_extensions']) ? $field_settings['file_extensions'] : variable_get('file_entity_default_allowed_extensions', 'jpg jpeg gif png txt doc docx xls xlsx pdf ppt pptx pps ppsx odt ods odp mp3 mov mp4 m4a m4v mpeg avi ogg oga ogv weba webp webm'), diff --git a/media.media.inc b/media.media.inc index ab7b032..913b364 100644 --- a/media.media.inc +++ b/media.media.inc @@ -38,98 +38,3 @@ function media_media_browser_plugin_info() { return $info; } - -/** - * Implements hook_query_media_browser_alter(). - */ -function media_query_media_browser_alter($query) { - // Ensure that the query is against the file_managed table. - $tables = $query->getTables(); - if (empty($tables['file_managed'])) { - throw new Exception(t('Media browser being queried without the file_managed table.')); - } - $alias = $tables['file_managed']['alias']; - - // How do we validate these? I don't know. - // I think PDO should protect them, but I'm not 100% certain. - $params = media_get_browser_params(); - - $types = !empty($params['types']) ? $params['types'] : NULL; - $url_include_patterns = !empty($params['url_include_patterns']) ? $params['url_include_patterns'] : NULL; - $url_exclude_patterns = !empty($params['url_exclude_patterns']) ? $params['url_exclude_patterns'] : NULL; - $allowed_schemes = !empty($params['schemes']) ? array_filter($params['schemes']) : array(); - $extensions = !empty($params['file_extensions']) ? array_filter(explode(' ', $params['file_extensions'])) : array(); - - $or_condition = db_or(); - - if (!empty($allowed_schemes)) { - // Include local files with the allowed extensions and types. - $local_wrappers = array_intersect_key(media_get_local_stream_wrappers(), $allowed_schemes); - if (!empty($extensions) && !empty($local_wrappers)) { - // Extension filtering. - $local_condition = db_or(); - foreach (array_keys($local_wrappers) as $scheme) { - foreach ($extensions as $extension) { - $local_condition->condition($alias . '.uri', db_like($scheme . '://') . '%' . db_like('.' . $extension), 'LIKE'); - } - } - $or_condition->condition($local_condition); - } - if (!empty($types) && !empty($local_wrappers)) { - // Type filtering. - $local_condition = db_or(); - foreach (array_keys($local_wrappers) as $scheme) { - $local_condition->condition($alias . '.type', $types, 'IN'); - } - $or_condition->condition($local_condition); - } - - // Include remote files with the allowed file types. - // We cant filter extensions here, because remote file filenames usually - // are a url or a parameter of a query. - $remote_wrappers = array_intersect_key(media_get_remote_stream_wrappers(), $allowed_schemes); - if (!empty($types) && !empty($remote_wrappers)) { - $remote_condition = db_and(); - $wrapper_condition = db_or(); - foreach (array_keys($remote_wrappers) as $scheme) { - $wrapper_condition->condition($alias . '.uri', db_like($scheme . '://') . '%', 'LIKE'); - } - $remote_condition->condition($wrapper_condition); - $remote_condition->condition($alias . '.type', $types, 'IN'); - $or_condition->condition($remote_condition); - } - } - else { - if (!empty($types)) { - $query->condition($alias . '.type', $types, 'IN'); - } - if (!empty($extensions)) { - foreach ($extensions as $extension) { - $or_condition->condition($alias . '.uri', db_like('.' . $extension), 'LIKE'); - } - } - } - - if ($or_condition->count()) { - $query->condition($or_condition); - } - - if ($url_include_patterns) { - $query->condition($alias . '.uri', '%' . db_like($url_include_patterns) . '%', 'LIKE'); - // Insert stream related restrictions here. - } - if ($url_exclude_patterns) { - $query->condition($alias . '.uri', '%' . db_like($url_exclude_patterns) . '%', 'NOT LIKE'); - } - - if (!user_access('administer files')) { - $query->condition($alias . '.uri', db_like('private://') . '%', 'NOT LIKE'); - } - - // @todo This is possibly redundant since it's already filtered in the view. - $query->condition($alias . '.status', FILE_STATUS_PERMANENT); - - foreach (array_keys(file_entity_get_hidden_stream_wrappers()) as $name) { - $query->condition($alias . '.uri', db_like($name . '://') . '%', 'NOT LIKE'); - } -} diff --git a/media.module b/media.module index 849555b..7660361 100644 --- a/media.module +++ b/media.module @@ -21,7 +21,6 @@ function media_hook_info() { 'media_browser_plugin_info_alter', 'media_browser_plugins_alter', 'media_browser_params_alter', - 'query_media_browser_alter', ); return array_fill_keys($hooks, array('group' => 'media')); @@ -1070,6 +1069,73 @@ function media_set_browser_params() { } /** + * Implements hook_query_media_browser_alter(). + */ +function media_query_media_browser_alter($query) { + // Ensure that the query is against the file_managed table. + $tables = $query->getTables(); + + if (empty($tables['file_managed'])) { + throw new Exception(t('Media browser being queried without the file_managed table.')); + } + + $alias = $tables['file_managed']['alias']; + + // How do we validate these? I don't know. + // I think PDO should protect them, but I'm not 100% certain. + $params = media_get_browser_params(); + + // Gather any file restrictions. + $types = !empty($params['types']) ? $params['types'] : array(); + $schemes = !empty($params['schemes']) ? $params['schemes'] : array(); + $extensions = !empty($params['file_extensions']) ? explode(' ', $params['file_extensions']) : array(); + + $or = db_or(); + + // Filter out files with restricted types. + if (!empty($types)) { + $query->condition($alias . '.type', $types, 'IN'); + } + + // Filter out files with restricted schemes. + if (!empty($schemes)) { + $local_or = db_or(); + $local_and = db_and(); + + // Gather all of the local stream wrappers. + $local_stream_wrappers = media_get_local_stream_wrappers(); + + foreach ($schemes as $scheme) { + // Only local files have extensions. + // Filter out files with restricted extensions. + if (!empty($extensions) && isset($local_stream_wrappers[$scheme])) { + debug($scheme); + $mimetypes = array(); + foreach ($extensions as $extension) { + $mimetype = media_get_extension_mimetype($extension); + $mimetypes[] = $mimetype; + } + $local_and->condition($alias . '.uri', db_like($scheme . '://') . '%', 'LIKE'); + $local_and->condition($alias . '.filemime', $mimetypes, 'IN'); + } + else { + debug($scheme); + $local_or->condition($alias . '.uri', db_like($scheme . '://') . '%', 'LIKE'); + } + } + if ($local_and->count()) { + $local_or->condition($local_and); + } + + $or->condition($local_or); + } + + if ($or->count()) { + $query->condition($or); + } +} + +/** * Implements hook_ctools_plugin_api(). * * Lets CTools know which plugin APIs are implemented by Media module. @@ -1212,6 +1278,30 @@ function media_get_browser_plugin_info() { } /** + * Gets the MIME type mapped to a given extension. + * + * @param string $extension + * A file extension. + * + * @return string + * The MIME type associated with the extension or FALSE if the extension does + * not have an associated MIME type. + * + * @see file_mimetype_mapping() + */ +function media_get_extension_mimetype($extension) { + include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc'; + $mimetype_mappings = file_mimetype_mapping(); + + if ($id = $mimetype_mappings['extensions'][$extension]) { + return $mimetype_mappings['mimetypes'][$id]; + } + else { + return FALSE; + } +} + +/** * Helper function to get a list of local stream wrappers. */ function media_get_local_stream_wrappers() { diff --git a/tests/media.test b/tests/media.test index b72035e..893c949 100644 --- a/tests/media.test +++ b/tests/media.test @@ -610,6 +610,56 @@ class MediaBrowserLibraryTestCase extends MediaFileFieldTestCase { } /** + * Tests the media browser settings. + */ +class MediaBrowserSettingsTestCase extends MediaFileFieldTestCase { + public static function getInfo() { + return array( + 'name' => 'Media browser settings test', + 'description' => 'Tests the media browser settings.', + 'group' => 'Media', + ); + } + + /** + * Tests the media browser settings. + */ + function testBrowserSettings() { + // Perform the tests with all permutations of $scheme, $type and $extension. + foreach (array('public', 'private') as $scheme) { + foreach (array('image', 'document') as $type) { + foreach (array('jpg', 'txt') as $extension) { + $file = $this->createFileEntity(array('scheme' => $scheme, 'uid' => $this->admin_user->uid, 'type' => $type, 'filemime' => media_get_extension_mimetype($extension))); + + $options = array( + 'query' => array( + 'enabledPlugins' => array( + 'media_default--media_browser_1' => 'media_default--media_browser_1', + ), + 'schemes' => array($scheme), + 'types' => array($type), + 'file_extensions' => $extension, + ), + ); + + // Verify that the file is displayed. + $this->drupalGet('media/browser', $options); + $this->assertResponse(200); + $xpath = $this->buildXPathQuery('//ul[@class="media-list-thumbnails"]/li/div[@data-fid=:fid]/@data-fid', array( + ':fid' => $file->fid, + )); + $this->assertFieldByXPath($xpath, TRUE, format_string('File with file ID %fid found.', array('%fid' => $file->fid))); + + // Verify that no other files are also displayed. + $files = $this->xpath('//ul[@class="media-list-thumbnails"]/li/div[@data-fid]'); + $this->assertEqual(count($files), 1, 'There is only one file that matches the current browser configuration.'); + } + } + } + } +} + +/** * Tests the media browser 'My files' tab. */ class MediaBrowserMyFilesTestCase extends MediaFileFieldTestCase {