Make File::create(.., $recursive = true) create missing nested directories

refs #8219
This commit is contained in:
Johannes Meyer 2015-01-30 15:42:22 +01:00
parent 0108d44d63
commit fdcec046e0
1 changed files with 66 additions and 6 deletions

View File

@ -23,6 +23,13 @@ class File extends SplFileObject
*/
protected $openMode;
/**
* The access mode to use when creating directories
*
* @var int
*/
public static $dirMode = 1528; // 2770
/**
* @see SplFileObject::__construct()
*/
@ -37,21 +44,74 @@ class File extends SplFileObject
}
/**
* Create a file with an access mode
* Create a file using the given access mode and return a instance of File open for writing
*
* @param string $path The path to the file
* @param int $accessMode The access mode to set
* @param bool $recursive Whether missing nested directories of the given path should be created
*
* @return File
*
* @throws RuntimeException In case the file cannot be created or the access mode cannot be set
* @throws NotWritableError In case the path's (existing) parent is not writable
*/
public static function create($path, $accessMode)
public static function create($path, $accessMode, $recursive = true)
{
if (!@touch($path)) {
throw new RuntimeException('Cannot create file "' . $path . '" with acces mode "' . $accessMode . '"');
$dirPath = dirname($path);
if ($recursive && !is_dir($dirPath)) {
static::createDirectories($dirPath);
} elseif (! is_writable($dirPath)) {
throw new NotWritableError(sprintf('Path "%s" is not writable', $dirPath));
}
if (!@chmod($path, $accessMode)) {
throw new RuntimeException('Cannot set access mode "' . $accessMode . '" on file "' . $path . '"');
$file = new static($path, 'x');
if (! @chmod($path, $accessMode)) {
$error = error_get_last();
throw new RuntimeException(sprintf(
'Cannot set access mode "%s" on file "%s" (%s)',
decoct($accessMode),
$path,
$error['message']
));
}
return $file;
}
/**
* Create missing directories
*
* @param string $path
*
* @throws RuntimeException In case a directory cannot be created or the access mode cannot be set
*/
protected static function createDirectories($path)
{
$part = strpos($path, DIRECTORY_SEPARATOR) === 0 ? DIRECTORY_SEPARATOR : '';
foreach (explode(DIRECTORY_SEPARATOR, ltrim($path, DIRECTORY_SEPARATOR)) as $dir) {
$part .= $dir . DIRECTORY_SEPARATOR;
if (! is_dir($part)) {
if (! @mkdir($part, static::$dirMode)) {
$error = error_get_last();
throw new RuntimeException(sprintf(
'Failed to create missing directory "%s" (%s)',
$part,
$error['message']
));
}
if (! @chmod($part, static::$dirMode)) {
$error = error_get_last();
throw new RuntimeException(sprintf(
'Failed to set access mode "%s" for directory "%s" (%s)',
decoct(static::$dirMode),
$part,
$error['message']
));
}
}
}
}