ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Local.php
Go to the documentation of this file.
1<?php
2
4
5use DirectoryIterator;
6use FilesystemIterator;
7use finfo as Finfo;
14use LogicException;
15use RecursiveDirectoryIterator;
16use RecursiveIteratorIterator;
17use SplFileInfo;
18
20{
24 const SKIP_LINKS = 0001;
25
29 const DISALLOW_LINKS = 0002;
30
34 protected static $permissions = [
35 'file' => [
36 'public' => 0644,
37 'private' => 0600,
38 ],
39 'dir' => [
40 'public' => 0755,
41 'private' => 0700,
42 ]
43 ];
44
48 protected $pathSeparator = DIRECTORY_SEPARATOR;
49
53 protected $permissionMap;
54
58 protected $writeFlags;
63
74 public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
75 {
76 $root = is_link($root) ? realpath($root) : $root;
77 $this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
78 $this->ensureDirectory($root);
79
80 if ( ! is_dir($root) || ! is_readable($root)) {
81 throw new LogicException('The root path ' . $root . ' is not readable.');
82 }
83
84 $this->setPathPrefix($root);
85 $this->writeFlags = $writeFlags;
86 $this->linkHandling = $linkHandling;
87 }
88
98 protected function ensureDirectory($root)
99 {
100 if ( ! is_dir($root)) {
101 $umask = umask(0);
102 @mkdir($root, $this->permissionMap['dir']['public'], true);
103 umask($umask);
104
105 if ( ! is_dir($root)) {
106 throw new Exception(sprintf('Impossible to create the root directory "%s".', $root));
107 }
108 }
109 }
110
114 public function has($path)
115 {
117
118 return file_exists($location);
119 }
120
124 public function write($path, $contents, Config $config)
125 {
127 $this->ensureDirectory(dirname($location));
128
129 if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
130 return false;
131 }
132
133 $type = 'file';
134 $result = compact('contents', 'type', 'size', 'path');
135
136 if ($visibility = $config->get('visibility')) {
137 $result['visibility'] = $visibility;
138 $this->setVisibility($path, $visibility);
139 }
140
141 return $result;
142 }
143
147 public function writeStream($path, $resource, Config $config)
148 {
150 $this->ensureDirectory(dirname($location));
151 $stream = fopen($location, 'w+b');
152
153 if ( ! $stream) {
154 return false;
155 }
156
157 stream_copy_to_stream($resource, $stream);
158
159 if ( ! fclose($stream)) {
160 return false;
161 }
162
163 if ($visibility = $config->get('visibility')) {
164 $this->setVisibility($path, $visibility);
165 }
166
167 $type = 'file';
168
169 return compact('type', 'path', 'visibility');
170 }
171
175 public function readStream($path)
176 {
178 $stream = fopen($location, 'rb');
179
180 return ['type' => 'file', 'path' => $path, 'stream' => $stream];
181 }
182
186 public function updateStream($path, $resource, Config $config)
187 {
188 return $this->writeStream($path, $resource, $config);
189 }
190
195 {
197 $mimetype = Util::guessMimeType($path, $contents);
198 $size = file_put_contents($location, $contents, $this->writeFlags);
199
200 if ($size === false) {
201 return false;
202 }
203
204 $type = 'file';
205
206 return compact('type', 'path', 'size', 'contents', 'mimetype');
207 }
208
212 public function read($path)
213 {
215 $contents = file_get_contents($location);
216
217 if ($contents === false) {
218 return false;
219 }
220
221 return ['type' => 'file', 'path' => $path, 'contents' => $contents];
222 }
223
227 public function rename($path, $newpath)
228 {
230 $destination = $this->applyPathPrefix($newpath);
231 $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
232 $this->ensureDirectory($parentDirectory);
233
235 }
236
240 public function copy($path, $newpath)
241 {
243 $destination = $this->applyPathPrefix($newpath);
244 $this->ensureDirectory(dirname($destination));
245
246 return copy($location, $destination);
247 }
248
252 public function delete($path)
253 {
255
256 return unlink($location);
257 }
258
262 public function listContents($directory = '', $recursive = false)
263 {
264 $result = [];
265 $location = $this->applyPathPrefix($directory);
266
267 if ( ! is_dir($location)) {
268 return [];
269 }
270
271 $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
272
273 foreach ($iterator as $file) {
274 $path = $this->getFilePath($file);
275
276 if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
277 continue;
278 }
279
280 $result[] = $this->normalizeFileInfo($file);
281 }
282
283 return array_filter($result);
284 }
285
289 public function getMetadata($path)
290 {
292 $info = new SplFileInfo($location);
293
294 return $this->normalizeFileInfo($info);
295 }
296
300 public function getSize($path)
301 {
302 return $this->getMetadata($path);
303 }
304
308 public function getMimetype($path)
309 {
311 $finfo = new Finfo(FILEINFO_MIME_TYPE);
312 $mimetype = $finfo->file($location);
313
314 if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty'])) {
316 }
317
318 return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype];
319 }
320
324 public function getTimestamp($path)
325 {
326 return $this->getMetadata($path);
327 }
328
332 public function getVisibility($path)
333 {
335 clearstatcache(false, $location);
336 $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
338
339 return compact('path', 'visibility');
340 }
341
345 public function setVisibility($path, $visibility)
346 {
348 $type = is_dir($location) ? 'dir' : 'file';
349 $success = chmod($location, $this->permissionMap[$type][$visibility]);
350
351 if ($success === false) {
352 return false;
353 }
354
355 return compact('path', 'visibility');
356 }
357
361 public function createDir($dirname, Config $config)
362 {
363 $location = $this->applyPathPrefix($dirname);
364 $umask = umask(0);
365 $visibility = $config->get('visibility', 'public');
366
367 if ( ! is_dir($location) && ! mkdir($location, $this->permissionMap['dir'][$visibility], true)) {
368 $return = false;
369 } else {
370 $return = ['path' => $dirname, 'type' => 'dir'];
371 }
372
373 umask($umask);
374
375 return $return;
376 }
377
381 public function deleteDir($dirname)
382 {
383 $location = $this->applyPathPrefix($dirname);
384
385 if ( ! is_dir($location)) {
386 return false;
387 }
388
389 $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
390
392 foreach ($contents as $file) {
393 $this->guardAgainstUnreadableFileInfo($file);
394 $this->deleteFileInfoObject($file);
395 }
396
397 return rmdir($location);
398 }
399
403 protected function deleteFileInfoObject(SplFileInfo $file)
404 {
405 switch ($file->getType()) {
406 case 'dir':
407 rmdir($file->getRealPath());
408 break;
409 case 'link':
410 unlink($file->getPathname());
411 break;
412 default:
413 unlink($file->getRealPath());
414 }
415 }
416
426 protected function normalizeFileInfo(SplFileInfo $file)
427 {
428 if ( ! $file->isLink()) {
429 return $this->mapFileInfo($file);
430 }
431
432 if ($this->linkHandling & self::DISALLOW_LINKS) {
434 }
435 }
436
444 protected function getFilePath(SplFileInfo $file)
445 {
446 $location = $file->getPathname();
448
449 return trim(str_replace('\\', '/', $path), '/');
450 }
451
458 protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
459 {
460 return new RecursiveIteratorIterator(
461 new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
462 $mode
463 );
464 }
465
471 protected function getDirectoryIterator($path)
472 {
473 $iterator = new DirectoryIterator($path);
474
475 return $iterator;
476 }
477
483 protected function mapFileInfo(SplFileInfo $file)
484 {
485 $normalized = [
486 'type' => $file->getType(),
487 'path' => $this->getFilePath($file),
488 ];
489
490 $normalized['timestamp'] = $file->getMTime();
491
492 if ($normalized['type'] === 'file') {
493 $normalized['size'] = $file->getSize();
494 }
495
496 return $normalized;
497 }
498
504 protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
505 {
506 if ( ! $file->isReadable()) {
508 }
509 }
510}
sprintf('%.4f', $callTime)
$result
$size
Definition: RandomTest.php:84
$success
Definition: Utf8Test.php:86
$location
Definition: buildRTE.php:44
An exception for terminatinating execution or to throw for unit testing.
removePathPrefix($path)
Remove a path prefix.
setPathPrefix($prefix)
Set the path prefix.
mapFileInfo(SplFileInfo $file)
Definition: Local.php:483
getVisibility($path)
Get the visibility of a file.array|false
Definition: Local.php:332
getRecursiveDirectoryIterator($path, $mode=RecursiveIteratorIterator::SELF_FIRST)
Definition: Local.php:458
__construct($root, $writeFlags=LOCK_EX, $linkHandling=self::DISALLOW_LINKS, array $permissions=[])
Constructor.
Definition: Local.php:74
deleteFileInfoObject(SplFileInfo $file)
Definition: Local.php:403
guardAgainstUnreadableFileInfo(SplFileInfo $file)
Definition: Local.php:504
normalizeFileInfo(SplFileInfo $file)
Normalize the file info.
Definition: Local.php:426
rename($path, $newpath)
Rename a file.bool
Definition: Local.php:227
setVisibility($path, $visibility)
Set the visibility for a file.array|false file meta data
Definition: Local.php:345
update($path, $contents, Config $config)
Update a file.array|false false on failure file meta data on success
Definition: Local.php:194
updateStream($path, $resource, Config $config)
Update a file using a stream.array|false false on failure file meta data on success
Definition: Local.php:186
write($path, $contents, Config $config)
Write a new file.array|false false on failure file meta data on success
Definition: Local.php:124
listContents($directory='', $recursive=false)
List contents of a directory.array
Definition: Local.php:262
has($path)
Check whether a file exists.array|bool|null
Definition: Local.php:114
readStream($path)
Read a file as a stream.array|false
Definition: Local.php:175
ensureDirectory($root)
Ensure the root directory exists.
Definition: Local.php:98
getFilePath(SplFileInfo $file)
Get the normalized path from a SplFileInfo object.
Definition: Local.php:444
getMetadata($path)
Get all the meta data of a file or directory.array|false
Definition: Local.php:289
createDir($dirname, Config $config)
Create a directory.array|false
Definition: Local.php:361
writeStream($path, $resource, Config $config)
Write a new file using a stream.array|false false on failure file meta data on success
Definition: Local.php:147
getSize($path)
Get the size of a file.array|false
Definition: Local.php:300
getTimestamp($path)
Get the timestamp of a file.array|false
Definition: Local.php:324
copy($path, $newpath)
Copy a file.bool
Definition: Local.php:240
getMimetype($path)
Get the mimetype of a file.array|false
Definition: Local.php:308
read($path)
Read a file.array|false
Definition: Local.php:212
static forLink(SplFileInfo $file)
Create a new exception for a link.
static detectByFilename($filename)
Definition: MimeType.php:61
static dirname($path)
Get a normalized dirname from a path.
Definition: Util.php:45
static guessMimeType($path, $content)
Guess MIME Type based on the path of the file and it's content.
Definition: Util.php:177
const VISIBILITY_PUBLIC
@const VISIBILITY_PUBLIC public visibility
const VISIBILITY_PRIVATE
@const VISIBILITY_PRIVATE private visibility
deleteDir($dirname)
Delete a directory.
$destination
$info
Definition: index.php:5
$stream
PHP stream implementation.
$type
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file