8000 [Filesystem] Added few new behaviors: · symfony/symfony@24eb396 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 24eb396

Browse files
committed
[Filesystem] Added few new behaviors:
- add a IOException and a main filesystem exception interface - whenever an action fails, an IOException is thrown - add access to the second and third arguments of touch() function - add a recursive option for chmod() - add a chown() method - add a chgrp() method - Switch the 'unlink' global function in Filesystem::symlink to Filesystem::remove. BC break: mkdir() function now throws exception in case of failure instead of returning Boolean value.
1 parent 0b8b76b commit 24eb396

File tree

5 files changed

+402
-61
lines changed

5 files changed

+402
-61
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Filesystem\Exception;
13+
14+
/**
15+
* Exception interface for all exceptions thrown by the component.
16+
*
17+
* @author Romain Neutron <imprec@gmail.com>
18+
*
19+
* @api
20+
*/
21+
interface ExceptionInterface
22+
{
23+
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Filesystem\Exception;
13+
14+
/**
15+
* Exception class thrown when a filesystem operation failure happens
16+
*
17+
* @author Romain Neutron <imprec@gmail.com>
18+
*
19+
* @api
20+
*/
21+
class IOException extends \RuntimeException implements ExceptionInterface
22+
{
23+
24+
}

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 114 additions & 27 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class Filesystem
2828
* @param string $originFile The original filename
2929
* @param string $targetFile The target filename
3030
* @param array $override Whether to override an existing file or not
31+
*
32+
* @throws Exception\IOException When copy fails
3133
*/
3234
public function copy($originFile, $targetFile, $override = false)
3335
{
@@ -40,30 +42,31 @@ public function copy($originFile, $targetFile, $override = false)
4042
}
4143

4244
if ($doCopy) {
43-
copy($originFile, $targetFile);
45+
if (true !== @copy($originFile, $targetFile)) {
46+
throw new Exception\IOException(sprintf('Failed to copy %s to %s', $originFile, $targetFile));
47+
}
4448
}
4549
}
4650

4751
/**
4852
* Creates a directory recursively.
4953
*
5054
* @param string|array|\Traversable $dirs The directory path
51-
* @param int $mode The directory mode
55+
* @param integer $mode The directory mode
5256
*
53-
* @return Boolean true if the directory has been created, false otherwise
57+
* @throws Exception\IOException On any directory creation failure
5458
*/
5559
public function mkdir($dirs, $mode = 0777)
5660
{
57-
$ret = true;
5861
foreach ($this->toIterator($dirs) as $dir) {
5962
if (is_dir($dir)) {
6063
continue;
6164
}
6265

63-
$ret = @mkdir($dir, $mode, true) && $ret;
66+
if (true !== @mkdir($dir, $mode, true)) {
67+
throw new Exception\IOException(sprintf('Failed to create %s', $dir));
68+
}
6469
}
65-
66-
return $ret;
6770
}
6871

6972
/**
@@ -85,21 +88,33 @@ public function exists($files)
8588
}
8689

8790
/**
88-
* Creates empty files.
91+
* Sets access and modification time of file.
8992
*
9093
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to create
94+
* @param integer $time The touch time as a unix timestamp
95+
* @param integer $atime The access time as a unix timestamp
96+
*
97+
* @throws Exception\IOException When touch fails
9198
*/
92-
public function touch($files)
99+
public function touch($files, $time = null, $atime = null)
93100
{
101+
if (null === $time) {
102+
$time = time();
103+
}
104+
94105
foreach ($this->toIterator($files) as $file) {
95-
touch($file);
106+
if (true !== @touch($file, $time, $atime)) {
107+
throw new Exception\IOException(sprintf('Failed to touch %s', $file));
108+
}
96109
}
97110
}
98111

99112
/**
100113
* Removes files or directories.
101114
*
102115
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
116+
*
117+
* @throws Exception\IOException When removal fails
103118
*/
104119
public function remove($files)
105120
{
@@ -113,13 +128,19 @@ public function remove($files)
113128
if (is_dir($file) && !is_link($file)) {
114129
$this->remove(new \FilesystemIterator($file));
115130

116-
rmdir($file);
131+
if (true !== @rmdir($file)) {
132+
throw new Exception\IOException(sprintf('Failed to remove directory %s', $file));
133+
}
117134
} else {
118135
// https://bugs.php.net/bug.php?id=52176
119136
if (defined('PHP_WINDOWS_VERSION_MAJOR') && is_dir($file)) {
120-
rmdir($file);
137+
if (true !== @rmdir($file)) {
138+
throw new Exception\IOException(sprintf('Failed to remove file %s', $file));
139+
}
121140
} else {
122-
unlink($file);
141+
if (true !== @unlink($file)) {
142+
throw new Exception\IOException(sprintf('Failed to remove file %s', $file));
143+
}
123144
}
124145
}
125146
}
@@ -128,14 +149,76 @@ public function remove($files)
128149
/**
129150
* Change mode for an array of files or directories.
130151
*
131-
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change mode
132-
* @param integer $mode The new mode (octal)
133-
* @param integer $umask The mode mask (octal)
152+
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change mode
153+
* @param integer $mode The new mode (octal)
154+
* @param integer $umask The mode mask (octal)
155+
* @param Boolean $recursive Whether change the mod recursively or not
156+
*
157+
* @throws Exception\IOException When the change fail
134158
*/
135-
public function chmod($files, $mode, $umask = 0000)
159+
public function chmod($files, $mode, $umask = 0000, $recursive = false)
136160
{
137161
foreach ($this->toIterator($files) as $file) {
138-
@chmod($file, $mode & ~$umask);
162+
if ($recursive && is_dir($file) && !is_link($file)) {
163+
$this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
164+
}
165+
if (true !== @chmod($file, $mode & ~$umask)) {
166+
throw new Exception\IOException(sprintf('Failed to chmod file %s', $file));
167+
}
168+
}
169+
}
170+
171+
/**
172+
* Change the owner of an array of files or directories
173+
*
174+
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change owner
175+
* @param string $user The new owner user name
176+
* @param Boolean $recursive Whether change the owner recursively or not
177+
*
178+
* @throws Exception\IOException When the change fail
179+
*/
180+
public function chown($files, $user, $recursive = false)
181+
{
182+
foreach ($this->toIterator($files) as $file) {
183+
if ($recursive && is_dir($file) && !is_link($file)) {
184+
$this->chown(new \FilesystemIterator($file), $user, true);
185+
}
186+
if (is_link($file) && function_exists('lchown')) {
187+
if (true !== @lchown($file, $user)) {
188+
throw new Exception\IOException(sprintf('Failed to chown file %s', $file));
189+
}
190+
} else {
191+
if (true !== @chown($file, $user)) {
192+
throw new Exception\IOException(sprintf('Failed to chown file %s', $file));
193+
}
194+
}
195+
}
196+
}
197+
198+
/**
199+
* Change the group of an array of files or directories
200+
*
201+
* @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change group
202+
* @param string $group The group name
203+
* @param Boolean $recursive Whether change the group recursively or not
204+
*
205+
* @throws Exception\IOException When the change fail
206+
*/
207+
public function chgrp($files, $group, $recursive = false)
208+
{
209+
foreach ($this->toIterator($files) as $file) {
210+
if ($recursive && is_dir($file) && !is_link($file)) {
211+
$this->chgrp(new \FilesystemIterator($file), $group, true);
212+
}
213+
if (is_link($file) && function_exists('lchgrp')) {
214+
if (true !== @lchgrp($file, $group)) {
215+
throw new Exception\IOException(sprintf('Failed to chgrp file %s', $file));
216+
}
217+
} else {
218+
if (true !== @chgrp($file, $group)) {
219+
throw new Exception\IOException(sprintf('Failed to chgrp file %s', $file));
220+
}
221+
}
139222
}
140223
}
141224

@@ -145,18 +228,18 @@ public function chmod($files, $mode, $umask = 0000)
145228
* @param string $origin The origin filename
146229
* @param string $target The new filename
147230
*
148-
* @throws \RuntimeException When target file already exists
149-
* @throws \RuntimeException When origin cannot be renamed
231+
* @throws Exception\IOException When target file already exists
232+
* @throws Exception\IOException When origin cannot be renamed
150233
*/
151234
public function rename($origin, $target)
152235
{
153236
// we check that target does not exist
154237
if (is_readable($target)) {
155-
throw new \RuntimeException(sprintf('Cannot rename because the target "%s" already exist.', $target));
238+
throw new Exception\IOException(sprintf('Cannot rename because the target "%s" already exist.', $target));
156239
}
157240

158-
if (false === @rename($origin, $target)) {
159-
throw new \RuntimeException(sprintf('Cannot rename "%s" to "%s".', $origin, $target));
241+
if (true !== @rename($origin, $target)) {
242+
throw new Exception\IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target));
160243
}
161244
}
162245

@@ -166,6 +249,8 @@ public function rename($origin, $target)
166249
* @param string $originDir The origin directory path
167250
* @param string $targetDir The symbolic link name
168251
* @param Boolean $copyOnWindows Whether to copy files if on Windows
252+
*
253+
* @throws Exception\IOException When symlink fails
169254
*/
170255
public function symlink($originDir, $targetDir, $copyOnWindows = false)
171256
{
@@ -180,14 +265,16 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false)
180265
$ok = false;
181266
if (is_link($targetDir)) {
182267
if (readlink($targetDir) != $originDir) {
183-
unlink($targetDir);
268+
$this->remove($targetDir);
184269
} else {
185270
$ok = true;
186271
}
187272
}
188273

189274
if (!$ok) {
190-
symlink($originDir, $targetDir);
275+
if (true !== @symlink($originDir, $targetDir)) {
276+
throw new Exception\IOException(sprintf('Failed to create symbolic link from %s to %s', $originDir, $targetDir));
277+
}
191278
}
192279
}
193280

@@ -235,7 +322,7 @@ public function makePathRelative($endPath, $startPath)
235322
* - $options['override'] Whether to override an existing file on copy or not (see copy())
236323
* - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink())
237324
*
238-
* @throws \RuntimeException When file type is unknown
325+
* @throws Exception\IOException When file type is unknown
239326
*/
240327
public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
241328
{
@@ -262,7 +349,7 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
262349
} elseif (is_file($file) || ($copyOnWindows && is_link($file))) {
263350
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
264351
} else {
265-
throw new \RuntimeException(sprintf('Unable to guess "%s" file type.', $file));
352+
throw new Exception\IOException(sprintf('Unable to guess "%s" file type.', $file));
266353
}
267354
}
268355
}

src/Symfony/Component/Filesystem/README.md

10000 Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,37 @@ Filesystem Component
33

44
Filesystem provides basic utility to manipulate the file system:
55

6-
use Symfony\Component\Filesystem\Filesystem;
6+
```php
7+
<?php
78

8-
$filesystem = new Filesystem();
9+
use Symfony\Component\Filesystem\Filesystem;
910

10-
$filesystem->copy($originFile, $targetFile, $override = false);
11+
$filesystem = new Filesystem();
1112

12-
$filesystem->mkdir($dirs, $mode = 0777);
13+
$filesystem->copy($originFile, $targetFile, $override = false);
1314

14-
$filesystem->touch($files);
15+
$filesystem->mkdir($dirs, $mode = 0777);
1516

16-
$filesystem->remove($files);
17+
$filesystem->touch($files, $time = null, $atime = null);
1718

18-
$filesystem->chmod($files, $mode, $umask = 0000);
19+
$filesystem->remove($files);
1920

20-
$filesystem->rename($origin, $target);
21+
$filesystem->chmod($files, $mode, $umask = 0000, $recursive = false);
2122

22-
$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false);
23+
$filesystem->chown($files, $user, $recursive = false);
2324

24-
$filesystem->makePathRelative($endPath, $startPath);
25+
$filesystem->chgrp($files, $group, $recursive = false);
2526

26-
$filesystem-& 57AE gt;mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array());
27+
$filesystem->rename($origin, $target);
2728

28-
$filesystem->isAbsolutePath($file);
29+
$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false);
30+
31+
$filesystem->makePathRelative($endPath, $startPath);
32+
33+
$filesystem->mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array());
34+
35+
$filesystem->isAbsolutePath($file);
36+
```
2937

3038
Resources
3139
---------

0 commit comments

Comments
 (0)
0