Completed
Pull Request — master (#139)
by Sebastian
02:17
created

FileSelection   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 8
Bugs 0 Features 1
Metric Value
c 8
b 0
f 1
dl 0
loc 156
rs 10
wmc 12
lcom 1
cbo 3

8 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 4 1
A __construct() 0 5 1
A excludeFilesFrom() 0 6 1
A shouldFollowLinks() 0 6 1
A getSelectedFiles() 0 21 3
A getAllFilesFromPaths() 0 18 2
A getAllFilesFromDirectory() 0 18 2
A createPathCollection() 0 13 1
1
<?php
2
3
namespace Spatie\Backup\Tasks\Backup;
4
5
use Illuminate\Support\Collection;
6
use Symfony\Component\Finder\Finder;
7
use Symfony\Component\Finder\SplFileInfo;
8
9
class FileSelection
10
{
11
    /** @var \Illuminate\Support\Collection */
12
    protected $includeFilesAndDirectories;
13
14
    /** @var \Illuminate\Support\Collection */
15
    protected $excludeFilesAndDirectories;
16
17
    /** @var bool */
18
    protected $shouldFollowLinks = false;
19
20
    /**
21
     * @param array|string $includeFilesAndDirectories
22
     *
23
     * @return \Spatie\Backup\Tasks\Backup\FileSelection
24
     */
25
    public static function create($includeFilesAndDirectories = [])
26
    {
27
        return new static($includeFilesAndDirectories);
28
    }
29
30
    /**
31
     * @param array|string $includeFilesAndDirectories
32
     */
33
    public function __construct($includeFilesAndDirectories)
34
    {
35
        $this->includeFilesAndDirectories = $this->createPathCollection($includeFilesAndDirectories);
36
        $this->excludeFilesAndDirectories = collect();
37
    }
38
39
    /**
40
     * Do not included the given files and directories.
41
     *
42
     * @param array|string $excludeFilesAndDirectories
43
     *
44
     * @return \Spatie\Backup\Tasks\Backup\FileSelection
45
     */
46
    public function excludeFilesFrom($excludeFilesAndDirectories)
47
    {
48
        $this->excludeFilesAndDirectories = $this->createPathCollection($excludeFilesAndDirectories);
49
50
        return $this;
51
    }
52
53
    /**
54
     * Enable or disable the following of symlinks.
55
     *
56
     * @param bool $shouldFollowLinks
57
     *
58
     * @return \Spatie\Backup\Tasks\Backup\FileSelection
59
     */
60
    public function shouldFollowLinks($shouldFollowLinks)
61
    {
62
        $this->shouldFollowLinks = $shouldFollowLinks;
63
64
        return $this;
65
    }
66
67
    /**
68
     * @return \Illuminate\Support\Collection
69
     */
70
    public function getSelectedFiles()
71
    {
72
        if ($this->includeFilesAndDirectories->isEmpty()) {
73
            return collect();
74
        }
75
76
        $filesToBeIncluded = $this->getAllFilesFromPaths($this->includeFilesAndDirectories);
77
78
        if ($this->excludeFilesAndDirectories->isEmpty()) {
79
            return $filesToBeIncluded;
80
        }
81
82
        return $filesToBeIncluded
83
            ->reject(function ($path) {
84
                return $this->excludeFilesAndDirectories
85
                    ->contains(function ($key, $excludedPath) use ($path) {
86
                        return starts_with($path, $excludedPath);
87
                    });
88
            })
89
            ->values();
90
    }
91
92
    /**
93
     * Make a unique array of all files from a given array of files and directories.
94
     *
95
     * @param \Illuminate\Support\Collection $paths
96
     *
97
     * @return \Illuminate\Support\Collection
98
     */
99
    protected function getAllFilesFromPaths(Collection $paths)
100
    {
101
        return $paths
102
            ->filter(function ($path) {
103
                return file_exists($path);
104
            })
105
            ->map(function ($file) {
106
                return realpath($file);
107
            })
108
            ->reduce(function (Collection $filePaths, $path) {
109
                if (is_dir($path)) {
110
                    return $filePaths->merge($this->getAllFilesFromDirectory($path));
111
                }
112
113
                return $filePaths->push($path);
114
            }, collect())
115
            ->unique();
116
    }
117
118
    /**
119
     * Recursively get all the files within a given directory.
120
     *
121
     * @param string $directory
122
     *
123
     * @return \Illuminate\Support\Collection
124
     */
125
    protected function getAllFilesFromDirectory($directory)
126
    {
127
        $finder = (new Finder())
128
            ->ignoreDotFiles(false)
129
            ->ignoreVCS(false)
130
            ->files()
131
            ->in($directory);
132
133
        if ($this->shouldFollowLinks) {
134
            $finder->followLinks();
135
        }
136
137
        return collect(iterator_to_array($finder))
138
            ->map(function (SplFileInfo $fileInfo) {
139
                return $fileInfo->getPathname();
140
            })
141
            ->values();
142
    }
143
144
    /**
145
     * Fully expand paths, and reject non-existing paths.
146
     *
147
     * @param $paths
148
     *
149
     * @return \Illuminate\Support\Collection
150
     */
151
    protected function createPathCollection($paths)
152
    {
153
        return collect($paths)
154
            ->flatMap(function ($path) {
155
                return glob($path);
156
            })
157
            ->map(function ($path) {
158
                return realpath($path);
159
            })
160
            ->reject(function ($path) {
161
                return $path === false;
162
            });
163
    }
164
}
165