From 5468b47b91ee040b35d30f7d8a79c66fba51531d Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Mon, 27 Jul 2009 19:53:18 +0000 Subject: - Patch #227232 by dopry, c960657, jmstacey, pwolanin, aaron, drewish: added initial support for PHP file wrappers. --- modules/simpletest/tests/file.test | 77 +++++++++++++++++++++++++++++++ modules/simpletest/tests/file_test.module | 43 +++++++++++++++++ modules/system/system.api.php | 54 ++++++++++++++++++++++ modules/system/system.module | 23 +++++++++ 4 files changed, 197 insertions(+) (limited to 'modules') diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test index 54dfa0d61..754505b63 100644 --- a/modules/simpletest/tests/file.test +++ b/modules/simpletest/tests/file.test @@ -2077,3 +2077,80 @@ class FileMimeTypeTest extends DrupalWebTestCase { } } } + +/** + * Tests stream wrapper registry. + */ +class StreamWrapperRegistryTest extends DrupalWebTestCase { + + protected $scheme = 'dummy'; + protected $classname = 'DrupalDummyStreamWrapper'; + + public static function getInfo() { + return array( + 'name' => 'Stream Wrapper Registry', + 'description' => 'Tests stream wrapper registry.', + 'group' => 'File', + ); + } + + function setUp() { + drupal_static_reset('file_get_stream_wrappers'); + parent::setUp('file_test'); + } + + function tearDown() { + parent::tearDown(); + stream_wrapper_unregister($this->scheme); + } + + /** + * Test the getClassName() function. + */ + function testGetClassName() { + // Check the dummy scheme. + $this->assertEqual($this->classname, file_stream_wrapper_get_class($this->scheme), t('Got correct class name for dummy scheme.')); + // Check core's scheme. + $this->assertEqual('DrupalPublicStreamWrapper', file_stream_wrapper_get_class('public'), t('Got correct class name for public scheme.')); + } + + /** + * Test the file_stream_wrapper_get_instance_by_scheme() function. + */ + function testGetInstanceByScheme() { + $instance = file_stream_wrapper_get_instance_by_scheme($this->scheme); + $this->assertEqual($this->classname, get_class($instance), t('Got correct class type for dummy scheme.')); + + $instance = file_stream_wrapper_get_instance_by_scheme('public'); + $this->assertEqual('DrupalPublicStreamWrapper', get_class($instance), t('Got correct class type for public scheme.')); + } + + /** + * Test the URI and target functions. + */ + function testGetInstanceByUri() { + $instance = file_stream_wrapper_get_instance_by_uri($this->scheme . '://foo'); + $this->assertEqual($this->classname, get_class($instance), t('Got correct class type for dummy URI.')); + + $instance = file_stream_wrapper_get_instance_by_uri('public://foo'); + $this->assertEqual('DrupalPublicStreamWrapper', get_class($instance), t('Got correct class type for public URI.')); + + // Test file_stream_wrapper_uri_normalize. + $uri = 'public:///' . $this->originalFileDirectory . '/foo/bar/'; + $uri = file_stream_wrapper_uri_normalize($uri); + $this->assertEqual('public://foo/bar', $uri, t('Got a properly normalized URI')); + + // Test file_uri_taget(). + $this->assertEqual('foo/bar.txt', file_uri_target('public://foo/bar.txt'), t('Got a valid stream target from public://foo/bar.txt')); + $this->assertFalse(file_uri_target('foo/bar.txt'), t('foo/bar.txt is not a valid stream.')); + } + + /** + * Test the scheme functions. + */ + function testGetValidStreamScheme() { + $this->assertEqual('foo', file_uri_scheme('foo://pork//chops'), t('Got the correct scheme from foo://asdf')); + $this->assertTrue(file_stream_wrapper_valid_scheme(file_uri_scheme('public://asdf')), t('Got a valid stream scheme from public://asdf')); + $this->assertFalse(file_stream_wrapper_valid_scheme(file_uri_scheme('foo://asdf')), t('Did not get a valid stream scheme from foo://asdf')); + } +} diff --git a/modules/simpletest/tests/file_test.module b/modules/simpletest/tests/file_test.module index 3873c1ec9..dc6a56b4e 100644 --- a/modules/simpletest/tests/file_test.module +++ b/modules/simpletest/tests/file_test.module @@ -23,6 +23,19 @@ function file_test_menu() { return $items; } +/** + * Implement hook_stream_wrappers(). + */ +function file_test_stream_wrappers() { + return array( + 'dummy' => array( + 'name' => t('Dummy files'), + 'class' => 'DrupalDummyStreamWrapper', + 'description' => t('Dummy wrapper for simpletest.'), + ), + ); +} + /** * Form to test file uploads. */ @@ -238,3 +251,33 @@ function file_test_file_move($file, $source) { function file_test_file_delete($file) { _file_test_log_call('delete', array($file)); } + +/** + * Helper class for testing the stream wrapper registry. + * + * Dummy stream wrapper implementation (dummy://). + */ +class DrupalDummyStreamWrapper extends DrupalLocalStreamWrapper { + function getDirectoryPath() { + return variable_get('stream_public_path', 'sites/default/files'); + } + + /** + * Override getInternalUri(). + * + * Return a dummy path for testing. + */ + function getInternalUri() { + return '/dummy/example.txt'; + } + + /** + * Override getExternalUrl(). + * + * Return the HTML URI of a public file. + */ + function getExternalUrl() { + return '/dummy/example.txt'; + } +} + diff --git a/modules/system/system.api.php b/modules/system/system.api.php index 774370035..8c7a7d090 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -1159,6 +1159,60 @@ function custom_url_rewrite_inbound(&$result, $path, $path_language) { } } +/** + * Registers PHP stream wrapper implementations associated with a module. + * + * Provide a facility for managing and querying user-defined stream wrappers + * in PHP. PHP's internal stream_get_wrappers() doesn't return the class + * registered to handle a stream, which we need to be able to find the handler + * for class instantiation. + * + * If a module registers a scheme that is already registered with PHP, it will + * be unregistered and replaced with the specified class. + * + * @return + * A nested array, keyed first by scheme name ("public" for "public://"), + * then keyed by the following values: + * - 'name' A short string to name the wrapper. + * - 'class' A string specifying the PHP class that implements the + * DrupalStreamWrapperInterface interface. + * - 'description' A string with a short description of what the wrapper does. + * + * @see file_get_stream_wrappers() + * @see hook_stream_wrappers_alter() + * @see system_stream_wrappers() + */ +function hook_stream_wrappers() { + return array( + 'public' => array( + 'name' => t('Public files'), + 'class' => 'DrupalPublicStreamWrapper', + 'description' => t('Public local files served by the webserver.'), + ), + 'private' => array( + 'name' => t('Private files'), + 'class' => 'DrupalPrivateStreamWrapper', + 'description' => t('Private local files served by Drupal.'), + ), + 'temp' => array( + 'name' => t('Temporary files'), + 'class' => 'DrupalTempStreamWrapper', + 'description' => t('Temporary local files for upload and previews.'), + ) + ); +} + +/** + * Alters the list of PHP stream wrapper implementations. + * + * @see file_get_stream_wrappers() + * @see hook_stream_wrappers() + */ +function hook_stream_wrappers_alter(&$wrappers) { + // Change the name of private files to reflect the performance. + $wrappers['private']['name'] = t('Slow files'); +} + /** * Load additional information into file objects. * diff --git a/modules/system/system.module b/modules/system/system.module index 25ee5f1fb..bc35c9645 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -1157,6 +1157,29 @@ function system_library() { return $libraries; } +/** + * Implement hook_stream_wrappers(). + */ +function system_stream_wrappers() { + return array( + 'public' => array( + 'name' => t('Public files'), + 'class' => 'DrupalPublicStreamWrapper', + 'description' => t('Public local files served by the webserver.'), + ), + 'private' => array( + 'name' => t('Private files'), + 'class' => 'DrupalPrivateStreamWrapper', + 'description' => t('Private local files served by Drupal.'), + ), + 'temporary' => array( + 'name' => t('Temporary files'), + 'class' => 'DrupalTemporaryStreamWrapper', + 'description' => t('Temporary local files for upload and previews.'), + ) + ); +} + /** * Retrieve a blocked IP address from the database. * -- cgit v1.2.3