Completed
Push — master ( 815ef9...a2c400 )
by Nikola
02:29
created

FlysystemDestination::push()   C

Complexity

Conditions 10
Paths 86

Size

Total Lines 55
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 10.4197

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 55
ccs 26
cts 31
cp 0.8387
rs 6.8372
cc 10
eloc 27
nc 86
nop 1
crap 10.4197

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace RunOpenCode\Backup\Destination;
4
5
use League\Flysystem\FilesystemInterface;
6
use RunOpenCode\Backup\Backup\Backup;
7
use RunOpenCode\Backup\Backup\File;
8
use RunOpenCode\Backup\Contract\BackupInterface;
9
use RunOpenCode\Backup\Contract\DestinationInterface;
10
use RunOpenCode\Backup\Exception\DestinationException;
11
12
class FlysystemDestination implements DestinationInterface
13
{
14
    /**
15
     * @var FilesystemInterface
16
     */
17
    protected $flysystem;
18
19
    /**
20
     * @var array
21
     */
22
    protected $backups;
23
24 4
    public function __construct(FilesystemInterface $flysystem)
25
    {
26 4
        $this->flysystem = $flysystem;
27 4
    }
28
29
    /**
30
     * {@inheritdoc}
31
     */
32 4
    public function push(BackupInterface $backup)
33
    {
34 4
        if (!$this->flysystem->has($backup->getName())) {
35 4
            $this->flysystem->createDir($backup->getName());
36 4
        }
37
38 4
        $existingBackupFiles = $this->getFiles($backup->getName());
39
40 4
        foreach ($backup->getFiles() as $backupFile) {
41
42
            try {
43
44 4
                $resource = fopen($backupFile->getPath(), 'r');
45
46
                if (
47 4
                    isset($existingBackupFiles[$backupFile->getRelativePath()])
48 4
                    &&
49 2
                    $backupFile->getModifiedAt() > new \DateTime('@'.$this->flysystem->getTimestamp($backup->getName() . '/' . $backupFile->getRelativePath()))
50 4
                ) {
51
52 2
                    $this->flysystem->updateStream($backup->getName() . '/' . $backupFile->getRelativePath(),  $resource);
53
54
                } else {
55
56 4
                    $this->flysystem->putStream($backup->getName() . '/' . $backupFile->getRelativePath(),  $resource);
57
58
                }
59
60 4
                if (isset($existingBackupFiles[$backupFile->getRelativePath()])) {
61 2
                    unset($existingBackupFiles[$backupFile->getRelativePath()]);
62 2
                }
63
64 4
                fclose($resource);
65
66 4
            } catch (\Exception $e) {
67
                throw new DestinationException(sprintf('Unable to backup file "%s" to flysystem destination.', $backupFile->getPath()), 0, $e);
68
            }
69 4
        }
70
71
        try {
72
73 4
            foreach ($existingBackupFiles as $removedBackupFile) {
74 2
                $this->flysystem->delete($backup->getName() . '/' . $removedBackupFile->getRelativePath());
75 4
            }
76
77 4
            $this->removeEmptyDirectories($backup->getName());
78
79 4
        } catch (\Exception $e) {
80
            throw new DestinationException('Unable to backup cleanup flysystem destination after backup process.', 0, $e);
81
        }
82
83 4
        if (!empty($this->backups)) {
84
            $this->backups[] = $backup;
85
        }
86 4
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 4
    public function get($name)
92
    {
93 4
        if (is_null($this->backups)) {
94
            $this->load();
95
        }
96
97 4
        return $this->backups[$name];
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 4
    public function has($name)
104
    {
105 4
        if (is_null($this->backups)) {
106 4
            $this->load();
107 4
        }
108
109 4
        return array_key_exists($name, $this->backups);
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function delete($name)
116
    {
117
        try {
118
            $this->flysystem->deleteDir($name);
119
        } catch (\Exception $e) {
120
            throw new DestinationException(sprintf('Unable to remove backup "%s" from flysystem destination.', $name), 0, $e);
121
        }
122
123
        if (!is_null($this->backups)) {
124
            unset($this->backups[$name]);
125
        }
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function all()
132
    {
133
        if (is_null($this->backups)) {
134
            $this->load();
135
        }
136
137
        return $this->backups;
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 2
    public function getIterator()
144
    {
145 2
        if (is_null($this->backups)) {
146
            $this->load();
147
        }
148
149 2
        return new \ArrayIterator($this->backups);
150
    }
151
152
    /**
153
     * Load backups from destination.
154
     *
155
     * @return BackupInterface[]
156
     */
157 4
    protected function load()
158
    {
159 4
        $this->backups = array();
160
161
        /**
162
         * @var \SplFileInfo $content
163
         */
164 4
        foreach ($this->flysystem->listContents() as $content) {
165
166 4
            if ($content['type'] == 'dir') {
167
168 4
                $backup = new Backup($content['path'], array(), $content['timestamp'], $content['timestamp']);
169
170
                /**
171
                 * @var \SplFileInfo $backupFile
172
                 */
173 4
                foreach ($this->flysystem->listContents($content['path'], true) as $backupFile) {
174
175 4
                    if ($backupFile['type'] == 'file') {
176
177 4
                        $backup->addFile(new File(
178 4
                            $backupFile['basename'],
179 4
                            $backupFile['path'],
180 4
                            $content['path'],
181 4
                            $backupFile['size'],
182 4
                            $backupFile['timestamp'],
183 4
                            $backupFile['timestamp']
184 4
                        ));
185 4
                    }
186 4
                }
187
188 4
                $this->backups[$backup->getName()] = $backup;
189 4
            }
190 4
        }
191 4
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 2
    public function count()
197
    {
198 2
        return count($this->getIterator());
199
    }
200
201
    /**
202
     * Remove empty directories from destination.
203
     *
204
     * @param string $backupName
205
     */
206 4
    protected function removeEmptyDirectories($backupName)
207
    {
208
        /**
209
         * @var \SplFileInfo $dir
210
         */
211 4
        foreach ($this->flysystem->listContents($backupName) as $dir) {
212
213 4
            if ($dir['type'] != 'dir') {
214 4
                continue;
215
            }
216
217 2
            if (count($this->flysystem->listContents($dir['path'])) > 0) {
218 2
                $this->removeEmptyDirectories($dir['path']);
219 2
            } else {
220 2
                $this->flysystem->deleteDir($dir['path']);
221
            }
222 4
        }
223 4
    }
224
225
226
    /**
227
     * Get all files in path.
228
     *
229
     * @param string $path Path to
230
     * @return File[] List of files in given location
231
     */
232 4
    protected function getFiles($path)
233
    {
234 4
        $result = array();
235
236
        /**
237
         * @var \SplFileInfo $file
238
         */
239 4
        foreach ($this->flysystem->listContents($path, true) as $file) {
240
241 2
            if ($file['type'] == 'file') {
242 2
                $file = new File(
243 2
                    $file['basename'],
244 2
                    $file['path'],
245 2
                    $path,
246 2
                    $file['size'],
247 2
                    $file['timestamp'],
248 2
                    $file['timestamp']
249 2
                );
250 2
                $result[$file->getRelativePath()] = $file;
251 2
            }
252 4
        }
253
254 4
        return $result;
255
    }
256
}
257