diff --git a/DependencyInjection/KnpGaufretteExtension.php b/DependencyInjection/KnpGaufretteExtension.php index 39e9d47..d920810 100644 --- a/DependencyInjection/KnpGaufretteExtension.php +++ b/DependencyInjection/KnpGaufretteExtension.php @@ -52,6 +52,11 @@ class KnpGaufretteExtension extends Extension $container->getDefinition('knp_gaufrette.filesystem_map') ->replaceArgument(0, $map); + + if (isset($config['stream_wrapper'])) { + $container->setParameter('knp_gaufrette.stream_wrapper.protocol', $config['stream_wrapper']['protocol']); + $container->setParameter('knp_gaufrette.stream_wrapper.filesystems', $config['stream_wrapper']['filesystems']); + } } private function createAdapter($name, array $config, ContainerBuilder $container, array $factories) diff --git a/DependencyInjection/MainConfiguration.php b/DependencyInjection/MainConfiguration.php index 381efbc..25af62c 100644 --- a/DependencyInjection/MainConfiguration.php +++ b/DependencyInjection/MainConfiguration.php @@ -37,6 +37,7 @@ class MainConfiguration implements ConfigurationInterface $this->addAdaptersSection($rootNode, $this->factories); $this->addFilesystemsSection($rootNode); + $this->addStreamWrapperSection($rootNode); $rootNode // add a faux-entry for factories, so that no validation error is thrown @@ -84,4 +85,30 @@ class MainConfiguration implements ConfigurationInterface ->end() ; } + + private function addStreamWrapperSection(ArrayNodeDefinition $node) + { + $node + ->children() + ->arrayNode('stream_wrapper') + ->children() + ->scalarNode('protocol')->defaultValue('gaufrette')->end() + ->arrayNode('filesystems') + ->beforeNormalization() + ->ifTrue(function ($array) { + return !(bool)count(array_filter(array_keys($array), 'is_string')); + }) + ->then(function ($array) { + return array_combine($array, $array); + }) + ->end() + ->useAttributeAsKey('key') + ->prototype('scalar') + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } } diff --git a/KnpGaufretteBundle.php b/KnpGaufretteBundle.php index 5f0c687..37baba3 100644 --- a/KnpGaufretteBundle.php +++ b/KnpGaufretteBundle.php @@ -4,6 +4,7 @@ namespace Knp\Bundle\GaufretteBundle; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; +use Gaufrette\StreamWrapper; /** * The Gaufrette Bundle @@ -12,4 +13,26 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; */ class KnpGaufretteBundle extends Bundle { + public function boot() + { + parent::boot(); + + if (!$this->container->hasParameter('knp_gaufrette.stream_wrapper.protocol') + || !$this->container->hasParameter('knp_gaufrette.stream_wrapper.filesystems')) { + return; + } + + StreamWrapper::register($this->container->getParameter('knp_gaufrette.stream_wrapper.protocol')); + $wrapperFsMap = StreamWrapper::getFilesystemMap(); + + $fileSystems = $this->container->getParameter('knp_gaufrette.stream_wrapper.filesystems'); + + if (empty($fileSystems)) { + $fileSystems = $this->container->get('knp_gaufrette.filesystem_map'); + } + + foreach ($fileSystems as $domain => $fileSystem) { + $wrapperFsMap->set($domain, $this->container->get('knp_gaufrette.filesystem_map')->get($fileSystem)); + } + } } diff --git a/README.markdown b/README.markdown index 1abf484..9530db1 100644 --- a/README.markdown +++ b/README.markdown @@ -432,3 +432,95 @@ knp_gaufrette: media: adapter: media_cache ``` + +## Stream Wrapper + +You can register filesystems with a specified domain. +And use as a stream wrapper anywhere in your code like : +`gaufrette://domain/file.txt` + +### Parameters + + * `protocol` The protocol name like `gaufrette://…` *(default gaufrette)* + * `filesystem` An array that contains files systems that you want to register with the possibility to set the key of the array + as the domain like `gaufrette://mydomain/…` *(default all filesystems)* + +### Example 1 +The protocol is gaufrette and all filesystems will be saved +``` yaml +# app/config/config.yml +knp_gaufrette: + adapters: + backup: #... + amazon: #... + + filesystems: + backup1: + adapter: backup + amazonS3: + adapter: amazon + + stream_wrapper: ~ +``` + +``` +gaufrette://backup1/file +gaufrette://amazonS3/file +``` + +### Example 2 +We define the protocl as data and all filesystem will be saved +``` yaml +# app/config/config.yml +knp_gaufrette: + filesystems: + #... + + stream_wrapper: + protocol: business +``` + +``` +data:///backup1/... +data://amazonS3/... +``` + +### Example 3 +We define the protocol as data and define which filesystem will be used +``` yaml +# app/config/config.yml +knp_gaufrette: + filesystems: + #... + + stream_wrapper: + protocol: data + filesystems: + - backup1 + - amazonS3 +``` + +``` +data://backup1/... +data://amazonS3/... +``` +### Example 4 +We define the protocol as data and define which filesystem will be used with the domain + +``` yaml +# app/config/config.yml +knp_gaufrette: + filesystems: + #... + + stream_wrapper: + protocol: gaufrette + filesystems: + backup: backup1 + pictures: amazonS3 +``` + +``` +data://backup/... +data://pictures/... +``` \ No newline at end of file diff --git a/Tests/Functional/ConfigurationTest.php b/Tests/Functional/ConfigurationTest.php index 61456cf..e2f628d 100644 --- a/Tests/Functional/ConfigurationTest.php +++ b/Tests/Functional/ConfigurationTest.php @@ -3,6 +3,7 @@ namespace Knp\Bundle\GaufretteBundle\Tests\Functional; use Symfony\Component\Filesystem\Filesystem; +use Gaufrette\StreamWrapper; class ConfigurationTest extends \PHPUnit_Framework_TestCase { @@ -90,4 +91,85 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase { $this->assertInstanceOf('Gaufrette\Adapter\Ftp', $this->kernel->getContainer()->get('ftp_filesystem')->getAdapter()); } + + /** + * @test + */ + public function shouldAllowToNotConfigureStreamWrapper() + { + $this->assertFalse($this->kernel->getContainer()->hasParameter('knp_gaufrette.stream_wrapper.protocol')); + } + + /** + * @test + */ + public function shouldConfigureStreamWrapperWithDefaultValues() + { + $kernel = new TestKernel('wrapper_1', false); + $kernel->boot(); + $container = $kernel->getContainer(); + + $this->assertTrue($container->hasParameter('knp_gaufrette.stream_wrapper.protocol')); + $this->assertEquals('gaufrette', $container->getParameter('knp_gaufrette.stream_wrapper.protocol')); + + $wrapperFsMap = StreamWrapper::getFilesystemMap(); + $fileSystems = $this->kernel->getContainer()->get('knp_gaufrette.filesystem_map'); + + foreach($fileSystems as $fs) { + $this->assertTrue($wrapperFsMap->has($fs)); + } + } + + /** + * @test + */ + public function shouldAllowToDefineProtocolOfStreamWrapper() + { + $kernel = new TestKernel('wrapper_2', false); + $kernel->boot(); + $container = $kernel->getContainer(); + + $this->assertTrue($container->hasParameter('knp_gaufrette.stream_wrapper.protocol')); + $this->assertEquals('tada', $container->getParameter('knp_gaufrette.stream_wrapper.protocol')); + } + + /** + * @test + */ + public function shouldAllowToDefineWhichFileSystemsShouldBeAddToStreamWrapper() + { + $kernel = new TestKernel('wrapper_2', false); + $kernel->boot(); + $container = $kernel->getContainer(); + $fileSystems = $container->getParameter('knp_gaufrette.stream_wrapper.filesystems'); + + $this->assertEquals(array('pictures' => 'cache', 'text' => 'ftp'), $fileSystems); + + $wrapperFsMap = StreamWrapper::getFilesystemMap(); + + foreach($fileSystems as $key => $fs) { + $this->assertTrue($wrapperFsMap->has($key)); + } + } + + /** + * @test + */ + public function shouldAllowToDefineFileSystemsWithoutDomain() + { + $kernel = new TestKernel('wrapper_3', false); + $kernel->boot(); + $container = $kernel->getContainer(); + $fileSystems = $container->getParameter('knp_gaufrette.stream_wrapper.filesystems'); + + $this->assertTrue($container->hasParameter('knp_gaufrette.stream_wrapper.protocol')); + $this->assertEquals('tada', $container->getParameter('knp_gaufrette.stream_wrapper.protocol')); + $this->assertEquals(array('cache' => 'cache', 'ftp' => 'ftp'), $fileSystems); + + $wrapperFsMap = StreamWrapper::getFilesystemMap(); + + foreach($fileSystems as $key => $fs) { + $this->assertTrue($wrapperFsMap->has($key)); + } + } } diff --git a/Tests/Functional/Resources/config/config_wrapper_1.yml b/Tests/Functional/Resources/config/config_wrapper_1.yml new file mode 100644 index 0000000..bf0e79e --- /dev/null +++ b/Tests/Functional/Resources/config/config_wrapper_1.yml @@ -0,0 +1,5 @@ +imports: + - { resource: config.yml } + +knp_gaufrette: + stream_wrapper: ~ diff --git a/Tests/Functional/Resources/config/config_wrapper_2.yml b/Tests/Functional/Resources/config/config_wrapper_2.yml new file mode 100644 index 0000000..23f07d0 --- /dev/null +++ b/Tests/Functional/Resources/config/config_wrapper_2.yml @@ -0,0 +1,9 @@ +imports: + - { resource: config.yml } + +knp_gaufrette: + stream_wrapper: + protocol: tada + filesystems: + pictures: cache + text: ftp diff --git a/Tests/Functional/Resources/config/config_wrapper_3.yml b/Tests/Functional/Resources/config/config_wrapper_3.yml new file mode 100644 index 0000000..4192089 --- /dev/null +++ b/Tests/Functional/Resources/config/config_wrapper_3.yml @@ -0,0 +1,9 @@ +imports: + - { resource: config.yml } + +knp_gaufrette: + stream_wrapper: + protocol: tada + filesystems: + - cache + - ftp