Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | 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
399 lars 198
     * @param  int|null  $mode
148 lars 199
     * @return void
200
     */
399 lars 201
    public function replace($path, $content, $mode = null)
148 lars 202
    {
203
        // If the path already exists and is a symlink, get the real path...
204
        clearstatcache(true, $path);
205
 
206
        $path = realpath($path) ?: $path;
207
 
208
        $tempPath = tempnam(dirname($path), basename($path));
209
 
210
        // Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...
399 lars 211
        if (! is_null($mode)) {
212
            chmod($tempPath, $mode);
213
        } else {
214
            chmod($tempPath, 0777 - umask());
215
        }
148 lars 216
 
217
        file_put_contents($tempPath, $content);
218
 
219
        rename($tempPath, $path);
220
    }
221
 
222
    /**
223
     * Replace a given string within a given file.
224
     *
225
     * @param  array|string  $search
226
     * @param  array|string  $replace
227
     * @param  string  $path
228
     * @return void
229
     */
230
    public function replaceInFile($search, $replace, $path)
231
    {
232
        file_put_contents($path, str_replace($search, $replace, file_get_contents($path)));
233
    }
234
 
235
    /**
236
     * Prepend to a file.
237
     *
238
     * @param  string  $path
239
     * @param  string  $data
240
     * @return int
241
     */
242
    public function prepend($path, $data)
243
    {
244
        if ($this->exists($path)) {
245
            return $this->put($path, $data.$this->get($path));
246
        }
247
 
248
        return $this->put($path, $data);
249
    }
250
 
251
    /**
252
     * Append to a file.
253
     *
254
     * @param  string  $path
255
     * @param  string  $data
256
     * @return int
257
     */
258
    public function append($path, $data)
259
    {
260
        return file_put_contents($path, $data, FILE_APPEND);
261
    }
262
 
263
    /**
264
     * Get or set UNIX mode of a file or directory.
265
     *
266
     * @param  string  $path
267
     * @param  int|null  $mode
268
     * @return mixed
269
     */
270
    public function chmod($path, $mode = null)
271
    {
272
        if ($mode) {
273
            return chmod($path, $mode);
274
        }
275
 
276
        return substr(sprintf('%o', fileperms($path)), -4);
277
    }
278
 
279
    /**
280
     * Delete the file at a given path.
281
     *
282
     * @param  string|array  $paths
283
     * @return bool
284
     */
285
    public function delete($paths)
286
    {
287
        $paths = is_array($paths) ? $paths : func_get_args();
288
 
289
        $success = true;
290
 
291
        foreach ($paths as $path) {
292
            try {
293
                if (@unlink($path)) {
294
                    clearstatcache(false, $path);
295
                } else {
296
                    $success = false;
297
                }
298
            } catch (ErrorException $e) {
299
                $success = false;
300
            }
301
        }
302
 
303
        return $success;
304
    }
305
 
306
    /**
307
     * Move a file to a new location.
308
     *
309
     * @param  string  $path
310
     * @param  string  $target
311
     * @return bool
312
     */
313
    public function move($path, $target)
314
    {
315
        return rename($path, $target);
316
    }
317
 
318
    /**
319
     * Copy a file to a new location.
320
     *
321
     * @param  string  $path
322
     * @param  string  $target
323
     * @return bool
324
     */
325
    public function copy($path, $target)
326
    {
327
        return copy($path, $target);
328
    }
329
 
330
    /**
331
     * Create a symlink to the target file or directory. On Windows, a hard link is created if the target is a file.
332
     *
333
     * @param  string  $target
334
     * @param  string  $link
335
     * @return void
336
     */
337
    public function link($target, $link)
338
    {
339
        if (! windows_os()) {
340
            return symlink($target, $link);
341
        }
342
 
343
        $mode = $this->isDirectory($target) ? 'J' : 'H';
344
 
345
        exec("mklink /{$mode} ".escapeshellarg($link).' '.escapeshellarg($target));
346
    }
347
 
348
    /**
349
     * Create a relative symlink to the target file or directory.
350
     *
351
     * @param  string  $target
352
     * @param  string  $link
353
     * @return void
354
     *
355
     * @throws \RuntimeException
356
     */
357
    public function relativeLink($target, $link)
358
    {
359
        if (! class_exists(SymfonyFilesystem::class)) {
360
            throw new RuntimeException(
361
                'To enable support for relative links, please install the symfony/filesystem package.'
362
            );
363
        }
364
 
365
        $relativeTarget = (new SymfonyFilesystem)->makePathRelative($target, dirname($link));
366
 
367
        $this->link($this->isFile($target) ? rtrim($relativeTarget, '/') : $relativeTarget, $link);
368
    }
369
 
370
    /**
371
     * Extract the file name from a file path.
372
     *
373
     * @param  string  $path
374
     * @return string
375
     */
376
    public function name($path)
377
    {
378
        return pathinfo($path, PATHINFO_FILENAME);
379
    }
380
 
381
    /**
382
     * Extract the trailing name component from a file path.
383
     *
384
     * @param  string  $path
385
     * @return string
386
     */
387
    public function basename($path)
388
    {
389
        return pathinfo($path, PATHINFO_BASENAME);
390
    }
391
 
392
    /**
393
     * Extract the parent directory from a file path.
394
     *
395
     * @param  string  $path
396
     * @return string
397
     */
398
    public function dirname($path)
399
    {
400
        return pathinfo($path, PATHINFO_DIRNAME);
401
    }
402
 
403
    /**
404
     * Extract the file extension from a file path.
405
     *
406
     * @param  string  $path
407
     * @return string
408
     */
409
    public function extension($path)
410
    {
411
        return pathinfo($path, PATHINFO_EXTENSION);
412
    }
413
 
414
    /**
415
     * Guess the file extension from the mime-type of a given file.
416
     *
417
     * @param  string  $path
418
     * @return string|null
419
     *
420
     * @throws \RuntimeException
421
     */
422
    public function guessExtension($path)
423
    {
424
        if (! class_exists(MimeTypes::class)) {
425
            throw new RuntimeException(
426
                'To enable support for guessing extensions, please install the symfony/mime package.'
427
            );
428
        }
429
 
430
        return (new MimeTypes)->getExtensions($this->mimeType($path))[0] ?? null;
431
    }
432
 
433
    /**
434
     * Get the file type of a given file.
435
     *
436
     * @param  string  $path
437
     * @return string
438
     */
439
    public function type($path)
440
    {
441
        return filetype($path);
442
    }
443
 
444
    /**
445
     * Get the mime-type of a given file.
446
     *
447
     * @param  string  $path
448
     * @return string|false
449
     */
450
    public function mimeType($path)
451
    {
452
        return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
453
    }
454
 
455
    /**
456
     * Get the file size of a given file.
457
     *
458
     * @param  string  $path
459
     * @return int
460
     */
461
    public function size($path)
462
    {
463
        return filesize($path);
464
    }
465
 
466
    /**
467
     * Get the file's last modification time.
468
     *
469
     * @param  string  $path
470
     * @return int
471
     */
472
    public function lastModified($path)
473
    {
474
        return filemtime($path);
475
    }
476
 
477
    /**
478
     * Determine if the given path is a directory.
479
     *
480
     * @param  string  $directory
481
     * @return bool
482
     */
483
    public function isDirectory($directory)
484
    {
485
        return is_dir($directory);
486
    }
487
 
488
    /**
489
     * Determine if the given path is a directory that does not contain any other files or directories.
490
     *
491
     * @param  string  $directory
492
     * @param  bool  $ignoreDotFiles
493
     * @return bool
494
     */
495
    public function isEmptyDirectory($directory, $ignoreDotFiles = false)
496
    {
497
        return ! Finder::create()->ignoreDotFiles($ignoreDotFiles)->in($directory)->depth(0)->hasResults();
498
    }
499
 
500
    /**
501
     * Determine if the given path is readable.
502
     *
503
     * @param  string  $path
504
     * @return bool
505
     */
506
    public function isReadable($path)
507
    {
508
        return is_readable($path);
509
    }
510
 
511
    /**
512
     * Determine if the given path is writable.
513
     *
514
     * @param  string  $path
515
     * @return bool
516
     */
517
    public function isWritable($path)
518
    {
519
        return is_writable($path);
520
    }
521
 
522
    /**
523
     * Determine if two files are the same by comparing their hashes.
524
     *
525
     * @param  string  $firstFile
526
     * @param  string  $secondFile
527
     * @return bool
528
     */
529
    public function hasSameHash($firstFile, $secondFile)
530
    {
531
        $hash = @md5_file($firstFile);
532
 
533
        return $hash && $hash === @md5_file($secondFile);
534
    }
535
 
536
    /**
537
     * Determine if the given path is a file.
538
     *
539
     * @param  string  $file
540
     * @return bool
541
     */
542
    public function isFile($file)
543
    {
544
        return is_file($file);
545
    }
546
 
547
    /**
548
     * Find path names matching a given pattern.
549
     *
550
     * @param  string  $pattern
551
     * @param  int  $flags
552
     * @return array
553
     */
554
    public function glob($pattern, $flags = 0)
555
    {
556
        return glob($pattern, $flags);
557
    }
558
 
559
    /**
560
     * Get an array of all files in a directory.
561
     *
562
     * @param  string  $directory
563
     * @param  bool  $hidden
564
     * @return \Symfony\Component\Finder\SplFileInfo[]
565
     */
566
    public function files($directory, $hidden = false)
567
    {
568
        return iterator_to_array(
569
            Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->depth(0)->sortByName(),
570
            false
571
        );
572
    }
573
 
574
    /**
575
     * Get all of the files from the given directory (recursive).
576
     *
577
     * @param  string  $directory
578
     * @param  bool  $hidden
579
     * @return \Symfony\Component\Finder\SplFileInfo[]
580
     */
581
    public function allFiles($directory, $hidden = false)
582
    {
583
        return iterator_to_array(
584
            Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->sortByName(),
585
            false
586
        );
587
    }
588
 
589
    /**
590
     * Get all of the directories within a given directory.
591
     *
592
     * @param  string  $directory
593
     * @return array
594
     */
595
    public function directories($directory)
596
    {
597
        $directories = [];
598
 
599
        foreach (Finder::create()->in($directory)->directories()->depth(0)->sortByName() as $dir) {
600
            $directories[] = $dir->getPathname();
601
        }
602
 
603
        return $directories;
604
    }
605
 
606
    /**
607
     * Ensure a directory exists.
608
     *
609
     * @param  string  $path
610
     * @param  int  $mode
611
     * @param  bool  $recursive
612
     * @return void
613
     */
614
    public function ensureDirectoryExists($path, $mode = 0755, $recursive = true)
615
    {
616
        if (! $this->isDirectory($path)) {
617
            $this->makeDirectory($path, $mode, $recursive);
618
        }
619
    }
620
 
621
    /**
622
     * Create a directory.
623
     *
624
     * @param  string  $path
625
     * @param  int  $mode
626
     * @param  bool  $recursive
627
     * @param  bool  $force
628
     * @return bool
629
     */
630
    public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false)
631
    {
632
        if ($force) {
633
            return @mkdir($path, $mode, $recursive);
634
        }
635
 
636
        return mkdir($path, $mode, $recursive);
637
    }
638
 
639
    /**
640
     * Move a directory.
641
     *
642
     * @param  string  $from
643
     * @param  string  $to
644
     * @param  bool  $overwrite
645
     * @return bool
646
     */
647
    public function moveDirectory($from, $to, $overwrite = false)
648
    {
649
        if ($overwrite && $this->isDirectory($to) && ! $this->deleteDirectory($to)) {
650
            return false;
651
        }
652
 
653
        return @rename($from, $to) === true;
654
    }
655
 
656
    /**
657
     * Copy a directory from one location to another.
658
     *
659
     * @param  string  $directory
660
     * @param  string  $destination
661
     * @param  int|null  $options
662
     * @return bool
663
     */
664
    public function copyDirectory($directory, $destination, $options = null)
665
    {
666
        if (! $this->isDirectory($directory)) {
667
            return false;
668
        }
669
 
670
        $options = $options ?: FilesystemIterator::SKIP_DOTS;
671
 
672
        // If the destination directory does not actually exist, we will go ahead and
673
        // create it recursively, which just gets the destination prepared to copy
674
        // the files over. Once we make the directory we'll proceed the copying.
675
        $this->ensureDirectoryExists($destination, 0777);
676
 
677
        $items = new FilesystemIterator($directory, $options);
678
 
679
        foreach ($items as $item) {
680
            // As we spin through items, we will check to see if the current file is actually
681
            // a directory or a file. When it is actually a directory we will need to call
682
            // back into this function recursively to keep copying these nested folders.
683
            $target = $destination.'/'.$item->getBasename();
684
 
685
            if ($item->isDir()) {
686
                $path = $item->getPathname();
687
 
688
                if (! $this->copyDirectory($path, $target, $options)) {
689
                    return false;
690
                }
691
            }
692
 
693
            // If the current items is just a regular file, we will just copy this to the new
694
            // location and keep looping. If for some reason the copy fails we'll bail out
695
            // and return false, so the developer is aware that the copy process failed.
696
            elseif (! $this->copy($item->getPathname(), $target)) {
697
                return false;
698
            }
699
        }
700
 
701
        return true;
702
    }
703
 
704
    /**
705
     * Recursively delete a directory.
706
     *
707
     * The directory itself may be optionally preserved.
708
     *
709
     * @param  string  $directory
710
     * @param  bool  $preserve
711
     * @return bool
712
     */
713
    public function deleteDirectory($directory, $preserve = false)
714
    {
715
        if (! $this->isDirectory($directory)) {
716
            return false;
717
        }
718
 
719
        $items = new FilesystemIterator($directory);
720
 
721
        foreach ($items as $item) {
722
            // If the item is a directory, we can just recurse into the function and
723
            // delete that sub-directory otherwise we'll just delete the file and
724
            // keep iterating through each file until the directory is cleaned.
725
            if ($item->isDir() && ! $item->isLink()) {
726
                $this->deleteDirectory($item->getPathname());
727
            }
728
 
729
            // If the item is just a file, we can go ahead and delete it since we're
730
            // just looping through and waxing all of the files in this directory
731
            // and calling directories recursively, so we delete the real path.
732
            else {
733
                $this->delete($item->getPathname());
734
            }
735
        }
736
 
737
        if (! $preserve) {
738
            @rmdir($directory);
739
        }
740
 
741
        return true;
742
    }
743
 
744
    /**
745
     * Remove all of the directories within a given directory.
746
     *
747
     * @param  string  $directory
748
     * @return bool
749
     */
750
    public function deleteDirectories($directory)
751
    {
752
        $allDirectories = $this->directories($directory);
753
 
754
        if (! empty($allDirectories)) {
755
            foreach ($allDirectories as $directoryName) {
756
                $this->deleteDirectory($directoryName);
757
            }
758
 
759
            return true;
760
        }
761
 
762
        return false;
763
    }
764
 
765
    /**
766
     * Empty the specified directory of all files and folders.
767
     *
768
     * @param  string  $directory
769
     * @return bool
770
     */
771
    public function cleanDirectory($directory)
772
    {
773
        return $this->deleteDirectory($directory, true);
774
    }
775
}