Completed
Push — master ( aade01...c63820 )
by Freek
02:38
created

FileSelection::shouldFollowLinks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 9.4285
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 array */
12
    protected $includeFilesAndDirectories = [];
13
14
    /** @var array */
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
        if (!is_array($includeFilesAndDirectories)) {
36
            $includeFilesAndDirectories = [$includeFilesAndDirectories];
37
        }
38
39
        $this->includeFilesAndDirectories = $includeFilesAndDirectories;
40
    }
41
42
    /**
43
     * Do not included the given files and directories.
44
     *
45
     * @param array|string $excludeFilesAndDirectories
46
     *
47
     * @return \Spatie\Backup\Tasks\Backup\FileSelection
48
     */
49
    public function excludeFilesFrom($excludeFilesAndDirectories)
50
    {
51
        if (!is_array($excludeFilesAndDirectories)) {
52
            $excludeFilesAndDirectories = [$excludeFilesAndDirectories];
53
        }
54
55
        $this->excludeFilesAndDirectories = $excludeFilesAndDirectories;
56
57
        return $this;
58
    }
59
60
    /**
61
     * Enable or disable the following of symlinks.
62
     *
63
     * @param bool $shouldFollowLinks
64
     *
65
     * @return \Spatie\Backup\Tasks\Backup\FileSelection
66
     */
67
    public function shouldFollowLinks($shouldFollowLinks)
68
    {
69
        $this->shouldFollowLinks = $shouldFollowLinks;
70
71
        return $this;
72
    }
73
74
    /**
75
     * @return array
76
     */
77
    public function getSelectedFiles()
78
    {
79
        if (count($this->includeFilesAndDirectories) === 0) {
80
            return [];
81
        }
82
83
        $filesToBeIncluded = $this->getAllFilesFromPaths($this->includeFilesAndDirectories);
84
85
        if (count($this->excludeFilesAndDirectories) === 0) {
86
            return $filesToBeIncluded;
87
        }
88
89
        $filesToBeExcluded = $this->getAllFilesFromPaths($this->excludeFilesAndDirectories);
90
91
        $selectedFiles = collect($filesToBeIncluded)
92
            ->filter(function ($file) use ($filesToBeExcluded) {
93
                return !in_array($file, $filesToBeExcluded);
94
            })
95
            ->toArray();
96
97
        $selectedFiles = array_values($selectedFiles);
98
99
        return $selectedFiles;
100
    }
101
102
    /**
103
     * Make a unique array of all files from a given array of files and directories.
104
     *
105
     * @param array $paths
106
     *
107
     * @return array
108
     */
109
    protected function getAllFilesFromPaths(array $paths)
110
    {
111
        $paths = $this->expandWildCardPaths($paths);
112
113
        $allFiles = collect($paths)
114
            ->filter(function ($path) {
115
                return file_exists($path);
116
            })
117
            ->map(function ($file) {
118
                return realpath($file);
119
            })
120
            ->reduce(function (Collection $filePaths, $path) {
121
                if (is_dir($path)) {
122
                    return $filePaths->merge($this->getAllFilesFromDirectory($path));
123
                }
124
125
                return $filePaths->push($path);
126
            }, collect())
127
            ->unique()
128
            ->toArray();
129
130
        return $allFiles;
131
    }
132
133
    /**
134
     * Recursively get all the files within a given directory.
135
     *
136
     * @param string $directory
137
     *
138
     * @return array
139
     */
140
    protected function getAllFilesFromDirectory($directory)
141
    {
142
        $finder = (new Finder())
143
            ->ignoreDotFiles(false)
144
            ->ignoreVCS(false)
145
            ->files()
146
            ->in($directory);
147
148
        if ($this->shouldFollowLinks) {
149
            $finder->followLinks();
150
        }
151
152
        $filePaths = array_map(function (SplFileInfo $fileInfo) {
153
            return $fileInfo->getPathname();
154
        }, iterator_to_array($finder));
155
156
        $filePaths = array_values($filePaths);
157
158
        return $filePaths;
159
    }
160
161
    /**
162
     * Check all paths in array for a wildcard (*) and build a new array from the results.
163
     *
164
     * @param array $paths
165
     *
166
     * @return array
167
     */
168
    protected function expandWildCardPaths(array $paths)
169
    {
170
        return collect($paths)
171
            ->map(function ($path) {
172
                return glob($path);
173
            })
174
            ->flatten()
175
            ->toArray();
176
    }
177
}
178