diff --git a/includes/file.inc b/includes/file.inc index 4423b2d6b037a36f637bc50b298cf32a8748dfa9..6395c632337bcf8a8ea7cb556b13390b6812ee62 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -90,16 +90,24 @@ * * A stream is referenced as "scheme://target". * + * @param $filter + * Optionally filter out all types except these. Defaults to + * STREAM_WRAPPERS_ALL, which returns all registered stream wrappers. + * * @return * Returns the entire Drupal stream wrapper registry. * @see hook_stream_wrappers() * @see hook_stream_wrappers_alter() */ -function file_get_stream_wrappers() { - $wrappers = &drupal_static(__FUNCTION__); +function file_get_stream_wrappers($filter = STREAM_WRAPPERS_ALL) { + $wrappers_storage = &drupal_static(__FUNCTION__); - if (!isset($wrappers)) { + if (!isset($wrappers_storage)) { $wrappers = module_invoke_all('stream_wrappers'); + foreach ($wrappers as $scheme => $info) { + // Add defaults. + $wrappers[$scheme] += array('type' => STREAM_WRAPPERS_NORMAL); + } drupal_alter('stream_wrappers', $wrappers); $existing = stream_get_wrappers(); foreach ($wrappers as $scheme => $info) { @@ -115,9 +123,25 @@ function file_get_stream_wrappers() { } stream_wrapper_register($scheme, $info['class']); } + // Pre-populate the static cache with the filters most typically used. + $wrappers_storage[STREAM_WRAPPERS_ALL][$scheme] = $wrappers[$scheme]; + if (($info['type'] & STREAM_WRAPPERS_WRITE_VISIBLE) == STREAM_WRAPPERS_WRITE_VISIBLE) { + $wrappers_storage[STREAM_WRAPPERS_WRITE_VISIBLE][$scheme] = $wrappers[$scheme]; + } } } - return $wrappers; + + if (!isset($wrappers_storage[$filter])) { + $wrappers_storage[$filter] = array(); + foreach ($wrappers_storage[STREAM_WRAPPERS_ALL] as $scheme => $info) { + // Bit-wise filter. + if ($info['type'] & $filter == $filter) { + $wrappers_storage[$filter][$scheme] = $info; + } + } + } + + return $wrappers_storage[$filter]; } /** diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc index 8ed5c851766dd4dfd3279789e828c955ed0aed77..b4edb0933735b266498d78a6177771bff4073435 100644 --- a/includes/stream_wrappers.inc +++ b/includes/stream_wrappers.inc @@ -20,6 +20,65 @@ * @link http://bugs.php.net/bug.php?id=47070 */ +/** + * Stream wrapper bit flags that are the basis for composite types. + */ + +/** + * Stream wrapper bit flag -- a filter that matches all wrappers. + */ +define ('STREAM_WRAPPERS_ALL', 0x0000); + +/** + * Stream wrapper bit flag -- refers to a local file system location. + */ +define ('STREAM_WRAPPERS_LOCAL', 0x0001); + +/** + * Stream wrapper bit flag -- refers to a remote filesystem location. + */ +define ('STREAM_WRAPPERS_REMOTE', 0x0002); + +/** + * Stream wrapper bit flag -- wrapper is readable (almost always true). + */ +define ('STREAM_WRAPPERS_READ', 0x0004); + +/** + * Stream wrapper bit flag -- wrapper is writeable. + */ +define ('STREAM_WRAPPERS_WRITE', 0x0008); + +/** + * Stream wrapper bit flag -- exposed in the UI and potentially web accessible. + */ +define ('STREAM_WRAPPERS_VISIBLE', 0x0010); + +/** + * Composite stream wrapper bit flags that are usually used as the types. + */ + +/** + * Stream wrapper type flag -- not visible in the UI or accessible via web, + * but readable and writable. E.g. the temporary directory for uploads. + */ +define ('STREAM_WRAPPERS_HIDDEN', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE); + +/** + * Stream wrapper type flag -- visible, readable and writeable. + */ +define ('STREAM_WRAPPERS_WRITE_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE | STREAM_WRAPPERS_VISIBLE); + +/** + * Stream wrapper type flag -- visible and read-only. + */ +define ('STREAM_WRAPPERS_READ_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_VISIBLE); + +/** + * Stream wrapper type flag -- visible, readable and writeable using local files. + */ +define ('STREAM_WRAPPERS_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_WRITE_VISIBLE); + /** * Generic PHP stream wrapper interface. * diff --git a/modules/file/file.field.inc b/modules/file/file.field.inc index 5a85bc0c7cc0eb25389d31e72993f0bb2e4ccbd5..97002f5ad9edcf0083f9c85b0872f5e518c57558 100644 --- a/modules/file/file.field.inc +++ b/modules/file/file.field.inc @@ -86,10 +86,8 @@ function file_field_settings_form($field, $instance, $has_data) { ); $scheme_options = array(); - foreach (file_get_stream_wrappers() as $scheme => $stream_wrapper) { - if ($scheme != 'temporary') { - $scheme_options[$scheme] = $stream_wrapper['name']; - } + foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) { + $scheme_options[$scheme] = $stream_wrapper['name']; } $form['uri_scheme'] = array( '#type' => 'radios', diff --git a/modules/image/image.field.inc b/modules/image/image.field.inc index 1b4a968527e5a32144d3df44bb75e98c8dbc9b38..39fcf2c1047c75ab050397e5cd7cde6339a2d896 100644 --- a/modules/image/image.field.inc +++ b/modules/image/image.field.inc @@ -72,10 +72,8 @@ function image_field_settings_form($field, $instance) { $settings = array_merge($defaults, $field['settings']); $scheme_options = array(); - foreach (file_get_stream_wrappers() as $scheme => $stream_wrapper) { - if ($scheme != 'temporary') { - $scheme_options[$scheme] = $stream_wrapper['name']; - } + foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) { + $scheme_options[$scheme] = $stream_wrapper['name']; } $form['uri_scheme'] = array( '#type' => 'radios', diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index be9597fdf62d4d27bd120d0bacfcdd7f88598810..284d8a55f6c2d14579169d0df5ff84e757d3bb95 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1743,11 +1743,11 @@ function system_file_system_settings() { '#description' => t('A local file system path where temporary files will be stored. This directory should not be accessible over the web.'), '#after_build' => array('system_check_directory'), ); - $wrappers = file_get_stream_wrappers(); - $options = array( - 'public' => $wrappers['public']['description'], - 'private' => $wrappers['private']['description'] - ); + // Any visible, writeable wrapper can potentially be used for the files + // directory, including a remote file system that integrates with a CDN. + foreach(file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $info) { + $options[$scheme] = $info['description']; + } $form['file_default_scheme'] = array( '#type' => 'radios', '#title' => t('Default download method'), diff --git a/modules/system/system.module b/modules/system/system.module index 3e3702746de539d18fdc1951278478ce5bbbc8f7..cae7a1bb4e32aa66cb169f233e2e93945e3a496f 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -1458,6 +1458,7 @@ function system_stream_wrappers() { 'name' => t('Temporary files'), 'class' => 'DrupalTemporaryStreamWrapper', 'description' => t('Temporary local files for upload and previews.'), + 'type' => STREAM_WRAPPERS_HIDDEN, ) ); }