├── .phpunit-watcher.yml
├── .styleci.yml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── composer.json
├── config
└── common.php
├── infection.json.dist
├── psalm.xml
├── rector.php
└── src
├── FileStorageConfigs.php
├── Filesystem.php
└── FilesystemInterface.php
/.phpunit-watcher.yml:
--------------------------------------------------------------------------------
1 | watch:
2 | directories:
3 | - src
4 | - tests
5 | fileMask: '*.php'
6 | notifications:
7 | passingTests: false
8 | failingTests: false
9 | phpunit:
10 | binaryPath: vendor/bin/phpunit
11 | timeout: 180
12 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: psr12
2 | risky: true
3 |
4 | version: 8
5 |
6 | finder:
7 | exclude:
8 | - docs
9 | - vendor
10 | - resources
11 | - views
12 | - public
13 | - templates
14 | not-name:
15 | - UnionCar.php
16 | - TimerUnionTypes.php
17 | - schema1.php
18 |
19 | enabled:
20 | - alpha_ordered_traits
21 | - array_indentation
22 | - array_push
23 | - combine_consecutive_issets
24 | - combine_consecutive_unsets
25 | - combine_nested_dirname
26 | - declare_strict_types
27 | - dir_constant
28 | - fully_qualified_strict_types
29 | - function_to_constant
30 | - hash_to_slash_comment
31 | - is_null
32 | - logical_operators
33 | - magic_constant_casing
34 | - magic_method_casing
35 | - method_separation
36 | - modernize_types_casting
37 | - native_function_casing
38 | - native_function_type_declaration_casing
39 | - no_alias_functions
40 | - no_empty_comment
41 | - no_empty_phpdoc
42 | - no_empty_statement
43 | - no_extra_block_blank_lines
44 | - no_short_bool_cast
45 | - no_superfluous_elseif
46 | - no_unneeded_control_parentheses
47 | - no_unneeded_curly_braces
48 | - no_unneeded_final_method
49 | - no_unset_cast
50 | - no_unused_imports
51 | - no_unused_lambda_imports
52 | - no_useless_else
53 | - no_useless_return
54 | - normalize_index_brace
55 | - php_unit_dedicate_assert
56 | - php_unit_dedicate_assert_internal_type
57 | - php_unit_expectation
58 | - php_unit_mock
59 | - php_unit_mock_short_will_return
60 | - php_unit_namespaced
61 | - php_unit_no_expectation_annotation
62 | - phpdoc_no_empty_return
63 | - phpdoc_no_useless_inheritdoc
64 | - phpdoc_order
65 | - phpdoc_property
66 | - phpdoc_scalar
67 | - phpdoc_separation
68 | - phpdoc_singular_inheritdoc
69 | - phpdoc_trim
70 | - phpdoc_trim_consecutive_blank_line_separation
71 | - phpdoc_type_to_var
72 | - phpdoc_types
73 | - phpdoc_types_order
74 | - print_to_echo
75 | - regular_callable_call
76 | - return_assignment
77 | - self_accessor
78 | - self_static_accessor
79 | - set_type_to_cast
80 | - short_array_syntax
81 | - short_list_syntax
82 | - simplified_if_return
83 | - single_quote
84 | - standardize_not_equals
85 | - ternary_to_null_coalescing
86 | - trailing_comma_in_multiline_array
87 | - unalign_double_arrow
88 | - unalign_equals
89 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Yii filesystem Change Log
2 |
3 | ## 1.0.0 under development
4 |
5 | - Initial release.
6 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2008 by Yii Software (https://www.yiiframework.com/)
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of Yii Software nor the names of its
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | This package is deprecated. Use https://flysystem.thephpleague.com/ directly.
4 |
5 |
6 |
7 | ❌
8 |
9 |
10 | ---
11 |
12 |
13 |
14 |
15 |
16 |
Yii filesystem
17 |
18 |
19 |
20 | An abstract filesystem that allows to swap underlying file system without rewriting application code.
21 | Based on [Flysystem](https://flysystem.thephpleague.com/v2/docs/).
22 |
23 | [](https://packagist.org/packages/yiisoft/yii-filesystem)
24 | [](https://packagist.org/packages/yiisoft/yii-filesystem)
25 | [](https://github.com/yiisoft/yii-filesystem/actions?query=workflow%3Abuild)
26 | [](https://scrutinizer-ci.com/g/yiisoft/yii-filesystem/?branch=master)
27 | [](https://scrutinizer-ci.com/g/yiisoft/yii-filesystem/?branch=master)
28 | [](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/yii-filesystem/master)
29 | [](https://github.com/yiisoft/yii-filesystem/actions?query=workflow%3A%22static+analysis%22)
30 | [](https://shepherd.dev/github/yiisoft/yii-filesystem)
31 |
32 | ## Requirements
33 |
34 | The package requires PHP 8.0 and is meant to be used with Yii3.
35 |
36 | ## Installation
37 |
38 | ```
39 | composer require yiisoft/yii-filesystem
40 | ```
41 |
42 | After installation, the `Yiisoft\Yii\Filesystem\FilesystemInterface` will be automatically registered
43 | in the main application container. This interface provides a local filesystem with root, as defined in the `@root` alias
44 | of the `aliases` parameter.
45 |
46 | ## Getting started
47 |
48 | The service could be obtained via DI container autowiring:
49 |
50 | ```php
51 | public function view(\Yiisoft\Yii\Filesystem\FilesystemInterface $filesystem)
52 | {
53 | $someFileContent = $filesystem->read('/runtime/somefile.txt');
54 | //...
55 | }
56 | ```
57 |
58 | Also you can use aliases
59 |
60 | ```php
61 | $someFileContent = $filesystem->write('@views/site/testfile.txt', 'Test content');
62 | ```
63 |
64 | ## Configuration
65 |
66 | Additional filesystems could be configured in `config/params.php` as described below:
67 |
68 | ```php
69 | 'file.storage' => [
70 | 'runtimeStorage' => [
71 | 'adapter' => [
72 | 'class' => \League\Flysystem\Local\LocalFilesystemAdapter::class,
73 | '__construct()' => [
74 | dirname(__DIR__) . '/runtime',
75 | \League\Flysystem\UnixVisibility\PortableVisibilityConverter::fromArray([
76 | 'file' => [
77 | 'public' => 0644,
78 | 'private' => 0600,
79 | ],
80 | 'dir' => [
81 | 'public' => 0755,
82 | 'private' => 0700,
83 | ],
84 | ]),
85 | LOCK_EX,
86 | \League\Flysystem\Local\LocalFilesystemAdapter::DISALLOW_LINKS
87 | ]
88 | ],
89 | 'aliases' => [
90 | '@cache' => '@root/cache',
91 | ]
92 | ],
93 | 'documentStorage' => [
94 | 'adapter' => [
95 | 'class' => \League\Flysystem\Local\LocalFilesystemAdapter::class,
96 | '__construct()' => [
97 | dirname(__DIR__) . '/docs',
98 | \League\Flysystem\UnixVisibility\PortableVisibilityConverter::fromArray([
99 | 'file' => [
100 | 'public' => 0644,
101 | 'private' => 0600,
102 | ],
103 | 'dir' => [
104 | 'public' => 0755,
105 | 'private' => 0700,
106 | ],
107 | ]),
108 | LOCK_EX,
109 | \League\Flysystem\Local\LocalFilesystemAdapter::DISALLOW_LINKS
110 | ]
111 | ],
112 | 'aliases' => [
113 | '@invoices' => '@root/export/invoices',
114 | '@orders' => '@root/export/orders',
115 | ],
116 | ],
117 | ],
118 | ```
119 |
120 | Aliases `runtimeStorage` and `documentStorage` will be automatically registered in the main application container.
121 | So, you can get it from the container:
122 |
123 | ```php
124 | public function index(ContainerInterface $container)
125 | {
126 | $documentStorage = $container->get('documentStorage');
127 | }
128 | ```
129 |
130 | If you prefer to use autowiring, you can create own interface for your filesystem.
131 |
132 | ```php
133 | interface ImageStorageInterface extends \Yiisoft\Yii\Filesystem\FilesystemInterface
134 | {
135 | }
136 | ```
137 |
138 | And then register it in the `params`:
139 |
140 | ```php
141 | 'file.storage' => [
142 | ImageStorageInterface::class => [
143 | 'adapter' => [
144 | 'class' => \League\Flysystem\Local\LocalFilesystemAdapter::class,
145 | '__construct()' => [
146 | dirname(__DIR__) . '/storage/images',
147 | \League\Flysystem\UnixVisibility\PortableVisibilityConverter::fromArray([
148 | 'file' => [
149 | 'public' => 0644,
150 | 'private' => 0600,
151 | ],
152 | 'dir' => [
153 | 'public' => 0755,
154 | 'private' => 0700,
155 | ],
156 | ]),
157 | LOCK_EX,
158 | \League\Flysystem\Local\LocalFilesystemAdapter::DISALLOW_LINKS
159 | ]
160 | ],
161 | ],
162 | ]
163 | ```
164 |
165 | Now you can use it like this:
166 |
167 | ```php
168 | //controller action
169 | public function addImage(ImageStorageInterface $imageStorage)
170 | {
171 | //get image stream...
172 |
173 | $imageStorage->writeStream('/path/to/image/myimage.jpeg', $myImageStream);
174 | }
175 | ```
176 |
177 | You can find documentation on `FilesystemInterface` methods in the [Flysystem Docs](https://flysystem.thephpleague.com/v2/docs/).
178 |
179 | ### Unit testing
180 |
181 | The package is tested with [PHPUnit](https://phpunit.de/). To run tests:
182 |
183 | ```shell
184 | ./vendor/bin/phpunit
185 | ```
186 |
187 | ### Mutation testing
188 |
189 | The package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it:
190 |
191 | ```shell
192 | ./vendor/bin/infection
193 | ```
194 |
195 | ### Static analysis
196 |
197 | The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis:
198 |
199 | ```shell
200 | ./vendor/bin/psalm
201 | ```
202 |
203 | ### Support the project
204 |
205 | [](https://opencollective.com/yiisoft)
206 |
207 | ### Follow updates
208 |
209 | [](https://www.yiiframework.com/)
210 | [](https://twitter.com/yiiframework)
211 | [](https://t.me/yii3en)
212 | [](https://www.facebook.com/groups/yiitalk)
213 | [](https://yiiframework.com/go/slack)
214 |
215 | ## License
216 |
217 | The Yii filesystem is free software. It is released under the terms of the BSD License.
218 | Please see [`LICENSE`](./LICENSE.md) for more information.
219 |
220 | Maintained by [Yii Software](https://www.yiiframework.com/).
221 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yiisoft/yii-filesystem",
3 | "type": "library",
4 | "description": "yii-filesystem",
5 | "keywords": [
6 | "filesystem",
7 | "file",
8 | "system"
9 | ],
10 | "homepage": "https://www.yiiframework.com/",
11 | "license": "BSD-3-Clause",
12 | "support": {
13 | "issues": "https://github.com/yiisoft/yii-filesystem/issues?state=open",
14 | "forum": "https://www.yiiframework.com/forum/",
15 | "wiki": "https://www.yiiframework.com/wiki/",
16 | "irc": "irc://irc.freenode.net/yii",
17 | "chat": "https://t.me/yii3en",
18 | "source": "https://github.com/yiisoft/yii-filesystem"
19 | },
20 | "minimum-stability": "dev",
21 | "prefer-stable": true,
22 | "require": {
23 | "php": "^8.0",
24 | "league/flysystem": "^2.0",
25 | "yiisoft/aliases": "^1.1|^2.0",
26 | "yiisoft/di": "^1.0"
27 | },
28 | "require-dev": {
29 | "phpunit/phpunit": "^9.5",
30 | "rector/rector": "^0.15.1",
31 | "roave/infection-static-analysis-plugin": "^1.16",
32 | "spatie/phpunit-watcher": "^1.23",
33 | "vimeo/psalm": "^4.18"
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "Yiisoft\\Yii\\Filesystem\\": "src"
38 | }
39 | },
40 | "autoload-dev": {
41 | "psr-4": {
42 | "Yiisoft\\Yii\\Filesystem\\Tests\\": "tests"
43 | }
44 | },
45 | "extra": {
46 | "branch-alias": {
47 | "dev-master": "3.0.x-dev"
48 | },
49 | "config-plugin-options": {
50 | "source-directory": "config"
51 | },
52 | "config-plugin": {
53 | "common": "common.php"
54 | }
55 | },
56 | "scripts": {
57 | "phan": "phan --progress-bar -o analysis.txt",
58 | "test": "phpunit --testdox --no-interaction",
59 | "test-watch": "phpunit-watcher watch"
60 | },
61 | "config": {
62 | "sort-packages": true,
63 | "allow-plugins": {
64 | "infection/extension-installer": true,
65 | "composer/package-versions-deprecated": true
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/config/common.php:
--------------------------------------------------------------------------------
1 | static function () use ($params) {
17 | $aliases = $params['yiisoft/aliases']['aliases'] ?? [];
18 | if (!isset($aliases['@root'])) {
19 | throw new \RuntimeException('Alias of the root directory is not defined.');
20 | }
21 |
22 | $adapter = new LocalFilesystemAdapter(
23 | $aliases['@root'],
24 | PortableVisibilityConverter::fromArray([
25 | 'file' => [
26 | 'public' => 0644,
27 | 'private' => 0600,
28 | ],
29 | 'dir' => [
30 | 'public' => 0755,
31 | 'private' => 0700,
32 | ],
33 | ]),
34 | LOCK_EX,
35 | LocalFilesystemAdapter::DISALLOW_LINKS
36 | );
37 |
38 | return new Filesystem($adapter, $aliases);
39 | },
40 | FileStorageConfigs::class => static fn () => new FileStorageConfigs($params['file.storage'] ?? []),
41 | ];
42 |
--------------------------------------------------------------------------------
/infection.json.dist:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "directories": [
4 | "src"
5 | ]
6 | },
7 | "logs": {
8 | "text": "php:\/\/stderr",
9 | "stryker": {
10 | "report": "master"
11 | }
12 | },
13 | "mutators": {
14 | "@default": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | paths([
11 | __DIR__ . '/src',
12 | __DIR__ . '/tests',
13 | ]);
14 |
15 | // register a single rule
16 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
17 |
18 | // define sets of rules
19 | $rectorConfig->sets([
20 | LevelSetList::UP_TO_PHP_80,
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/src/FileStorageConfigs.php:
--------------------------------------------------------------------------------
1 | storageConfigs;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Filesystem.php:
--------------------------------------------------------------------------------
1 | prepareAliases($aliases);
24 |
25 | parent::__construct($adapter, $config, $pathNormalizer);
26 | }
27 |
28 | public function fileExists(string $location): bool
29 | {
30 | $location = $this->aliases->get($location);
31 | return parent::fileExists($location);
32 | }
33 |
34 | public function write(string $location, string $contents, array $config = []): void
35 | {
36 | $location = $this->aliases->get($location);
37 | parent::write($location, $contents, $config);
38 | }
39 |
40 | public function writeStream(string $location, $contents, array $config = []): void
41 | {
42 | $location = $this->aliases->get($location);
43 | parent::writeStream($location, $contents, $config);
44 | }
45 |
46 | public function read(string $location): string
47 | {
48 | $location = $this->aliases->get($location);
49 | return parent::read($location);
50 | }
51 |
52 | public function readStream(string $location)
53 | {
54 | $location = $this->aliases->get($location);
55 | return parent::readStream($location);
56 | }
57 |
58 | public function delete(string $location): void
59 | {
60 | $location = $this->aliases->get($location);
61 | parent::delete($location);
62 | }
63 |
64 | public function createDirectory(string $location, array $config = []): void
65 | {
66 | $location = $this->aliases->get($location);
67 | parent::createDirectory($location, $config);
68 | }
69 |
70 | public function deleteDirectory(string $location): void
71 | {
72 | $location = $this->aliases->get($location);
73 | parent::deleteDirectory($location);
74 | }
75 |
76 | public function copy(string $source, string $destination, array $config = []): void
77 | {
78 | $source = $this->aliases->get($source);
79 | $destination = $this->aliases->get($destination);
80 | parent::copy($source, $destination, $config);
81 | }
82 |
83 | public function move(string $source, string $destination, array $config = []): void
84 | {
85 | $source = $this->aliases->get($source);
86 | $destination = $this->aliases->get($destination);
87 | parent::move($source, $destination, $config);
88 | }
89 |
90 | public function setVisibility(string $path, string $visibility): void
91 | {
92 | $path = $this->aliases->get($path);
93 | parent::setVisibility($path, $visibility);
94 | }
95 |
96 | public function visibility(string $path): string
97 | {
98 | $path = $this->aliases->get($path);
99 | return parent::visibility($path);
100 | }
101 |
102 | public function mimeType(string $path): string
103 | {
104 | $path = $this->aliases->get($path);
105 | return parent::mimeType($path);
106 | }
107 |
108 | public function lastModified(string $path): int
109 | {
110 | $path = $this->aliases->get($path);
111 | return parent::lastModified($path);
112 | }
113 |
114 | public function listContents(string $location, bool $deep = LeagueFilesystem::LIST_SHALLOW): DirectoryListing
115 | {
116 | $location = $this->aliases->get($location);
117 | return parent::listContents($location, $deep);
118 | }
119 |
120 | public function fileSize(string $path): int
121 | {
122 | $path = $this->aliases->get($path);
123 | return parent::fileSize($path);
124 | }
125 |
126 | private function prepareAliases(array $aliases): void
127 | {
128 | if ($aliases !== []) {
129 | $aliases = array_merge(['@root' => ''], $aliases);
130 | $aliases['@root'] = '';
131 | }
132 | $this->aliases = new Aliases($aliases);
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/FilesystemInterface.php:
--------------------------------------------------------------------------------
1 |