Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Filesystem;
4
 
5
use ErrorException;
6
use FilesystemIterator;
7
use Illuminate\Contracts\Filesystem\FileNotFoundException;
8
use Illuminate\Support\LazyCollection;
9
use Illuminate\Support\Traits\Conditionable;
10
use Illuminate\Support\Traits\Macroable;
11
use RuntimeException;
12
use SplFileObject;
13
use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Mime\MimeTypes;
16
 
17
class Filesystem
18
{
19
    use Conditionable;
20
    use Macroable;
21
 
22
    /**
23
     * Determine if a file or directory exists.
24
     *
25
     * @param  string  $path
26
     * @return bool
27
     */
28
    public function exists($path)
29
    {
30
        return file_exists($path);
31
    }
32
 
33
    /**
34
     * Determine if a file or directory is missing.
35
     *
36
     * @param  string  $path
37
     * @return bool
38
     */
39
    public function missing($path)
40
    {
41
        return ! $this->exists($path);
42
    }
43
 
44
    /**
45
     * Get the contents of a file.
46
     *
47
     * @param  string  $path
48
     * @param  bool  $lock
49
     * @return string
50
     *
51
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
52
     */
53
    public function get($path, $lock = false)
54
    {
55
        if ($this->isFile($path)) {
56
            return $lock ? $this->sharedGet($path) : file_get_contents($path);
57
        }
58
 
59
        throw new FileNotFoundException("File does not exist at path {$path}.");
60
    }
61
 
62
    /**
63
     * Get contents of a file with shared access.
64
     *
65
     * @param  string  $path
66
     * @return string
67
     */
68
    public function sharedGet($path)
69
    {
70
        $contents = '';
71
 
72
        $handle = fopen($path, 'rb');
73
 
74
        if ($handle) {
75
            try {
76
                if (flock($handle, LOCK_SH)) {
77
                    clearstatcache(true, $path);
78
 
79
                    $contents = fread($handle, $this->size($path) ?: 1);
80
 
81
                    flock($handle, LOCK_UN);
82
                }
83
            } finally {
84
                fclose($handle);
85
            }
86
        }
87
 
88
        return $contents;
89
    }
90
 
91
    /**
92
     * Get the returned value of a file.
93
     *
94
     * @param  string  $path
95
     * @param  array  $data
96
     * @return mixed
97
     *
98
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
99
     */
100
    public function getRequire($path, array $data = [])
101
    {
102
        if ($this->isFile($path)) {
103
            $__path = $path;
104
            $__data = $data;
105
 
106
            return (static function () use ($__path, $__data) {
107
                extract($__data, EXTR_SKIP);
108
 
109
                return require $__path;
110
            })();
111
        }
112
 
113
        throw new FileNotFoundException("File does not exist at path {$path}.");
114
    }
115
 
116
    /**
117
     * Require the given file once.
118
     *
119
     * @param  string  $path
120
     * @param  array  $data
121
     * @return mixed
122
     *
123
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
124
     */
125
    public function requireOnce($path, array $data = [])
126
    {
127
        if ($this->isFile($path)) {
128
            $__path = $path;
129
            $__data = $data;
130
 
131
            return (static function () use ($__path, $__data) {
132
                extract($__data, EXTR_SKIP);
133
 
134
                return require_once $__path;
135
            })();
136
        }
137
 
138
        throw new FileNotFoundException("File does not exist at path {$path}.");
139
    }
140
 
141
    /**
142
     * Get the contents of a file one line at a time.
143
     *
144
     * @param  string  $path
145
     * @return \Illuminate\Support\LazyCollection
146
     *
147
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
148
     */
149
    public function lines($path)
150
    {
151
        if (! $this->isFile($path)) {
152
            throw new FileNotFoundException(
153
                "File does not exist at path {$path}."
154
            );
155
        }
156
 
157
        return LazyCollection::make(function () use ($path) {
158
            $file = new SplFileObject($path);
159
 
160
            $file->setFlags(SplFileObject::DROP_NEW_LINE);
161
 
162
            while (! $file->eof()) {
163
                yield $file->fgets();
164
            }
165
        });
166
    }
167
 
168
    /**
169
     * Get the hash of the file at the given path.
170
     *
171
     * @param  string  $path
172
     * @param  string  $algorithm
173
     * @return string
174
     */
175
    public function hash($path, $algorithm = 'md5')
176
    {
177
        return hash_file($algorithm, $path);
178
    }
179
 
180
    /**
181
     * Write the contents of a file.
182
     *
183
     * @param  string  $path
184
     * @param  string  $contents
185
     * @param  bool  $lock
186
     * @return int|bool
187
     */
188
    public function put($path, $contents, $lock = false)
189
    {
190
        return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
191
    }
192
 
193
    /**
194
     * Write the contents of a file, replacing it atomically if it already exists.
195
     *
196
     * @param  string  $path
197
     * @param  string  $content
198
     * @return void
199
     */
200
    public function replace($path, $content)
201
    {
202
        // If the path already exists and is a symlink, get the real path...
203
        clearstatcache(true, $path);
204
 
205
        $path = realpath($path) ?: $path;
206
 
207
        $tempPath = tempnam(dirname($path), basename($path));
208
 
209
        // Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...
210
        chmod($tempPath, 0777 - umask());
211
 
212
        file_put_contents($tempPath, $content);
213
 
214
        rename($tempPath, $path);
215
    }
216
 
217
    /**
218
     * Replace a given string within a given file.
219
     *
220
     * @param  array|string  $search
221
     * @param  array|string  $replace
222
     * @param  string  $path
223
     * @return void
224
     */
225
    public function replaceInFile($search, $replace, $path)
226
    {
227
        file_put_contents($path, str_replace($search, $replace, file_get_contents($path)));
228
    }
229
 
230
    /**
231
     * Prepend to a file.
232
     *
233
     * @param  string  $path
234
     * @param  string  $data
235
     * @return int
236
     */
237
    public function prepend($path, $data)
238
    {
239
        if ($this->exists($path)) {
240
            return $this->put($path, $data.$this->get($path));
241
        }
242
 
243
        return $this->put($path, $data);
244
    }
245
 
246
    /**
247
     * Append to a file.
248
     *
249
     * @param  string  $path
250
     * @param  string  $data
251
     * @return int
252
     */
253
    public function append($path, $data)
254
    {
255
        return file_put_contents($path, $data, FILE_APPEND);
256
    }
257
 
258
    /**
259
     * Get or set UNIX mode of a file or directory.
260
     *
261
     * @param  string  $path
262
     * @param  int|null  $mode
263
     * @return mixed
264
     */
265
    public function chmod($path, $mode = null)
266
    {
267
        if ($mode) {
268
            return chmod($path, $mode);
269
        }
270
 
271
        return substr(sprintf('%o', fileperms($path)), -4);
272
    }
273
 
274
    /**
275
     * Delete the file at a given path.
276
     *
277
     * @param  string|array  $paths
278
     * @return bool
279
     */
280
    public function delete($paths)
281
    {
282
        $paths = is_array($paths) ? $paths : func_get_args();
283
 
284
        $success = true;
285
 
286
        foreach ($paths as $path) {
287
            try {
288
                if (@unlink($path)) {
289
                    clearstatcache(false, $path);
290
                } else {
291
                    $success = false;
292
                }
293
            } catch (ErrorException $e) {
294
                $success = false;
295
            }
296
        }
297
 
298
        return $success;
299
    }
300
 
301
    /**
302
     * Move a file to a new location.
303
     *
304
     * @param  string  $path
305
     * @param  string  $target
306
     * @return bool
307
     */
308
    public function move($path, $target)
309
    {
310
        return rename($path, $target);
311
    }
312
 
313
    /**
314
     * Copy a file to a new location.
315
     *
316
     * @param  string  $path
317
     * @param  string  $target
318
     * @return bool
319
     */
320
    public function copy($path, $target)
321
    {
322
        return copy($path, $target);
323
    }
324
 
325
    /**
326
     * Create a symlink to the target file or directory. On Windows, a hard link is created if the target is a file.
327
     *
328
     * @param  string  $target
329
     * @param  string  $link
330
     * @return void
331
     */
332
    public function link($target, $link)
333
    {
334
        if (! windows_os()) {
335
            return symlink($target, $link);
336
        }
337
 
338
        $mode = $this->isDirectory($target) ? 'J' : 'H';
339
 
340
        exec("mklink /{$mode} ".escapeshellarg($link).' '.escapeshellarg($target));
341
    }
342
 
343
    /**
344
     * Create a relative symlink to the target file or directory.
345
     *
346
     * @param  string  $target
347
     * @param  string  $link
348
     * @return void
349
     *
350
     * @throws \RuntimeException
351
     */
352
    public function relativeLink($target, $link)
353
    {
354
        if (! class_exists(SymfonyFilesystem::class)) {
355
            throw new RuntimeException(
356
                'To enable support for relative links, please install the symfony/filesystem package.'
357
            );
358
        }
359
 
360
        $relativeTarget = (new SymfonyFilesystem)->makePathRelative($target, dirname($link));
361
 
362
        $this->link($this->isFile($target) ? rtrim($relativeTarget, '/') : $relativeTarget, $link);
363
    }
364
 
365
    /**
366
     * Extract the file name from a file path.
367
     *
368
     * @param  string  $path
369
     * @return string
370
     */
371
    public function name($path)
372
    {
373
        return pathinfo($path, PATHINFO_FILENAME);
374
    }
375
 
376
    /**
377
     * Extract the trailing name component from a file path.
378
     *
379
     * @param  string  $path
380
     * @return string
381
     */
382
    public function basename($path)
383
    {
384
        return pathinfo($path, PATHINFO_BASENAME);
385
    }
386
 
387
    /**
388
     * Extract the parent directory from a file path.
389
     *
390
     * @param  string  $path
391
     * @return string
392
     */
393
    public function dirname($path)
394
    {
395
        return pathinfo($path, PATHINFO_DIRNAME);
396
    }
397
 
398
    /**
399
     * Extract the file extension from a file path.
400
     *
401
     * @param  string  $path
402
     * @return string
403
     */
404
    public function extension($path)
405
    {
406
        return pathinfo($path, PATHINFO_EXTENSION);
407
    }
408
 
409
    /**
410
     * Guess the file extension from the mime-type of a given file.
411
     *
412
     * @param  string  $path
413
     * @return string|null
414
     *
415
     * @throws \RuntimeException
416
     */
417
    public function guessExtension($path)
418
    {
419
        if (! class_exists(MimeTypes::class)) {
420
            throw new RuntimeException(
421
                'To enable support for guessing extensions, please install the symfony/mime package.'
422
            );
423
        }
424
 
425
        return (new MimeTypes)->getExtensions($this->mimeType($path))[0] ?? null;
426
    }
427
 
428
    /**
429
     * Get the file type of a given file.
430
     *
431
     * @param  string  $path
432
     * @return string
433
     */
434
    public function type($path)
435
    {
436
        return filetype($path);
437
    }
438
 
439
    /**
440
     * Get the mime-type of a given file.
441
     *
442
     * @param  string  $path
443
     * @return string|false
444
     */
445
    public function mimeType($path)
446
    {
447
        return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
448
    }
449
 
450
    /**
451
     * Get the file size of a given file.
452
     *
453
     * @param  string  $path
454
     * @return int
455
     */
456
    public function size($path)
457
    {
458
        return filesize($path);
459
    }
460
 
461
    /**
462
     * Get the file's last modification time.
463
     *
464
     * @param  string  $path
465
     * @return int
466
     */
467
    public function lastModified($path)
468
    {
469
        return filemtime($path);
470
    }
471
 
472
    /**
473
     * Determine if the given path is a directory.
474
     *
475
     * @param  string  $directory
476
     * @return bool
477
     */
478
    public function isDirectory($directory)
479
    {
480
        return is_dir($directory);
481
    }
482
 
483
    /**
484
     * Determine if the given path is a directory that does not contain any other files or directories.
485
     *
486
     * @param  string  $directory
487
     * @param  bool  $ignoreDotFiles
488
     * @return bool
489
     */
490
    public function isEmptyDirectory($directory, $ignoreDotFiles = false)
491
    {
492
        return ! Finder::create()->ignoreDotFiles($ignoreDotFiles)->in($directory)->depth(0)->hasResults();
493
    }
494
 
495
    /**
496
     * Determine if the given path is readable.
497
     *
498
     * @param  string  $path
499
     * @return bool
500
     */
501
    public function isReadable($path)
502
    {
503
        return is_readable($path);
504
    }
505
 
506
    /**
507
     * Determine if the given path is writable.
508
     *
509
     * @param  string  $path
510
     * @return bool
511
     */
512
    public function isWritable($path)
513
    {
514
        return is_writable($path);
515
    }
516
 
517
    /**
518
     * Determine if two files are the same by comparing their hashes.
519
     *
520
     * @param  string  $firstFile
521
     * @param  string  $secondFile
522
     * @return bool
523
     */
524
    public function hasSameHash($firstFile, $secondFile)
525
    {
526
        $hash = @md5_file($firstFile);
527
 
528
        return $hash && $hash === @md5_file($secondFile);
529
    }
530
 
531
    /**
532
     * Determine if the given path is a file.
533
     *
534
     * @param  string  $file
535
     * @return bool
536
     */
537
    public function isFile($file)
538
    {
539
        return is_file($file);
540
    }
541
 
542
    /**
543
     * Find path names matching a given pattern.
544
     *
545
     * @param  string  $pattern
546
     * @param  int  $flags
547
     * @return array
548
     */
549
    public function glob($pattern, $flags = 0)
550
    {
551
        return glob($pattern, $flags);
552
    }
553
 
554
    /**
555
     * Get an array of all files in a directory.
556
     *
557
     * @param  string  $directory
558
     * @param  bool  $hidden
559
     * @return \Symfony\Component\Finder\SplFileInfo[]
560
     */
561
    public function files($directory, $hidden = false)
562
    {
563
        return iterator_to_array(
564
            Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->depth(0)->sortByName(),
565
            false
566
        );
567
    }
568
 
569
    /**
570
     * Get all of the files from the given directory (recursive).
571
     *
572
     * @param  string  $directory
573
     * @param  bool  $hidden
574
     * @return \Symfony\Component\Finder\SplFileInfo[]
575
     */
576
    public function allFiles($directory, $hidden = false)
577
    {
578
        return iterator_to_array(
579
            Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->sortByName(),
580
            false
581
        );
582
    }
583
 
584
    /**
585
     * Get all of the directories within a given directory.
586
     *
587
     * @param  string  $directory
588
     * @return array
589
     */
590
    public function directories($directory)
591
    {
592
        $directories = [];
593
 
594
        foreach (Finder::create()->in($directory)->directories()->depth(0)->sortByName() as $dir) {
595
            $directories[] = $dir->getPathname();
596
        }
597
 
598
        return $directories;
599
    }
600
 
601
    /**
602
     * Ensure a directory exists.
603
     *
604
     * @param  string  $path
605
     * @param  int  $mode
606
     * @param  bool  $recursive
607
     * @return void
608
     */
609
    public function ensureDirectoryExists($path, $mode = 0755, $recursive = true)
610
    {
611
        if (! $this->isDirectory($path)) {
612
            $this->makeDirectory($path, $mode, $recursive);
613
        }
614
    }
615
 
616
    /**
617
     * Create a directory.
618
     *
619
     * @param  string  $path
620
     * @param  int  $mode
621
     * @param  bool  $recursive
622
     * @param  bool  $force
623
     * @return bool
624
     */
625
    public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false)
626
    {
627
        if ($force) {
628
            return @mkdir($path, $mode, $recursive);
629
        }
630
 
631
        return mkdir($path, $mode, $recursive);
632
    }
633
 
634
    /**
635
     * Move a directory.
636
     *
637
     * @param  string  $from
638
     * @param  string  $to
639
     * @param  bool  $overwrite
640
     * @return bool
641
     */
642
    public function moveDirectory($from, $to, $overwrite = false)
643
    {
644
        if ($overwrite && $this->isDirectory($to) && ! $this->deleteDirectory($to)) {
645
            return false;
646
        }
647
 
648
        return @rename($from, $to) === true;
649
    }
650
 
651
    /**
652
     * Copy a directory from one location to another.
653
     *
654
     * @param  string  $directory
655
     * @param  string  $destination
656
     * @param  int|null  $options
657
     * @return bool
658
     */
659
    public function copyDirectory($directory, $destination, $options = null)
660
    {
661
        if (! $this->isDirectory($directory)) {
662
            return false;
663
        }
664
 
665
        $options = $options ?: FilesystemIterator::SKIP_DOTS;
666
 
667
        // If the destination directory does not actually exist, we will go ahead and
668
        // create it recursively, which just gets the destination prepared to copy
669
        // the files over. Once we make the directory we'll proceed the copying.
670
        $this->ensureDirectoryExists($destination, 0777);
671
 
672
        $items = new FilesystemIterator($directory, $options);
673
 
674
        foreach ($items as $item) {
675
            // As we spin through items, we will check to see if the current file is actually
676
            // a directory or a file. When it is actually a directory we will need to call
677
            // back into this function recursively to keep copying these nested folders.
678
            $target = $destination.'/'.$item->getBasename();
679
 
680
            if ($item->isDir()) {
681
                $path = $item->getPathname();
682
 
683
                if (! $this->copyDirectory($path, $target, $options)) {
684
                    return false;
685
                }
686
            }
687
 
688
            // If the current items is just a regular file, we will just copy this to the new
689
            // location and keep looping. If for some reason the copy fails we'll bail out
690
            // and return false, so the developer is aware that the copy process failed.
691
            elseif (! $this->copy($item->getPathname(), $target)) {
692
                return false;
693
            }
694
        }
695
 
696
        return true;
697
    }
698
 
699
    /**
700
     * Recursively delete a directory.
701
     *
702
     * The directory itself may be optionally preserved.
703
     *
704
     * @param  string  $directory
705
     * @param  bool  $preserve
706
     * @return bool
707
     */
708
    public function deleteDirectory($directory, $preserve = false)
709
    {
710
        if (! $this->isDirectory($directory)) {
711
            return false;
712
        }
713
 
714
        $items = new FilesystemIterator($directory);
715
 
716
        foreach ($items as $item) {
717
            // If the item is a directory, we can just recurse into the function and
718
            // delete that sub-directory otherwise we'll just delete the file and
719
            // keep iterating through each file until the directory is cleaned.
720
            if ($item->isDir() && ! $item->isLink()) {
721
                $this->deleteDirectory($item->getPathname());
722
            }
723
 
724
            // If the item is just a file, we can go ahead and delete it since we're
725
            // just looping through and waxing all of the files in this directory
726
            // and calling directories recursively, so we delete the real path.
727
            else {
728
                $this->delete($item->getPathname());
729
            }
730
        }
731
 
732
        if (! $preserve) {
733
            @rmdir($directory);
734
        }
735
 
736
        return true;
737
    }
738
 
739
    /**
740
     * Remove all of the directories within a given directory.
741
     *
742
     * @param  string  $directory
743
     * @return bool
744
     */
745
    public function deleteDirectories($directory)
746
    {
747
        $allDirectories = $this->directories($directory);
748
 
749
        if (! empty($allDirectories)) {
750
            foreach ($allDirectories as $directoryName) {
751
                $this->deleteDirectory($directoryName);
752
            }
753
 
754
            return true;
755
        }
756
 
757
        return false;
758
    }
759
 
760
    /**
761
     * Empty the specified directory of all files and folders.
762
     *
763
     * @param  string  $directory
764
     * @return bool
765
     */
766
    public function cleanDirectory($directory)
767
    {
768
        return $this->deleteDirectory($directory, true);
769
    }
770
}