getRecursiveListForRemoval()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
c 0
b 0
f 0
rs 9.2
cc 4
eloc 12
nc 3
nop 3
1
<?php
2
namespace Genkgo\Srvcleaner\Tasks;
3
4
use DateTime;
5
use DateInterval;
6
use Psr\Log\LoggerAwareInterface;
7
use Psr\Log\LoggerInterface;
8
use SplFileInfo;
9
use DirectoryIterator;
10
use CallbackFilterIterator;
11
use Genkgo\Srvcleaner\Exceptions\ConfigurationException;
12
use Genkgo\Srvcleaner\Util\ProcessAwareInterface;
13
use Genkgo\Srvcleaner\Util\Processor;
14
15
/**
16
 * Class CleanUpDirectoriesTask
17
 * @package Genkgo\Srvcleaner\Tasks
18
 */
19
abstract class AbstractFilesystemCleanUp extends AbstractTask implements ProcessAwareInterface, LoggerAwareInterface
20
{
21
    /**
22
     * @var Processor
23
     */
24
    private $processor;
25
    /**
26
     * @var LoggerInterface
27
     */
28
    private $logger;
29
30
    /**
31
     * @param Processor $processor
32
     * @return void
33
     */
34
    public function setProcessor(Processor $processor)
35
    {
36
        $this->processor = $processor;
37
    }
38
39
    /**
40
     * @param LoggerInterface $logger
41
     * @return void
42
     */
43
    public function setLogger (LoggerInterface $logger) {
44
        $this->logger = $logger;
45
    }
46
47
    /**
48
     * @param bool $dryRun
49
     */
50
    public function execute($dryRun = false)
51
    {
52
        if ($this->logger === null) {
53
            throw new \RuntimeException('No logger defined');
54
        }
55
56
        $this->processor->setCurrentWorkingDirectory($this->getCurrentWorkingDirectory());
57
58
        if (!isset($this->getConfig()->path) || !isset($this->getConfig()->match)) {
59
            throw new ConfigurationException('Config `path` and `match` are required to cleanup directories');
60
        }
61
62
        $path = $this->getConfig()->path;
63
        $match = $this->getConfig()->match;
64
        if (isset($this->getConfig()->recursive) && $this->getConfig()->recursive === true) {
65
            $recursive = true;
66
        } else {
67
            $recursive = false;
68
        }
69
70
        $shouldBeRemoved = $this->getListForRemoval($path, $match, $recursive);
71
        foreach ($shouldBeRemoved as $item) {
72
            if (file_exists($item->getPathname())) {
73
                $date = date('Y-m-d H:i:s', $item->getMTime());
74
                $this->logger->info("[Removing] {$item->getPathname()} (Modified At: {$date})");
75
76
                if (!$dryRun) {
77
                    $this->processor->execute("rm -Rf {$item->getPathname()}");
78
                }
79
            }
80
        }
81
    }
82
83
    /**
84
     * @param string $match
85
     * @return CallbackFilterIterator
86
     */
87
    abstract protected function getList ($match);
88
89
    /**
90
     * @param $path
91
     * @param array $matches
92
     * @param bool $recursive
93
     * @return SplFileInfo[]
94
     */
95
    private function getListForRemoval ($path, array $matches, $recursive = false) {
96
        $scheduleForRemoval = $this->calculateMatches($path, $matches);
97
98
        if ($recursive) {
99
            $scheduleForRemoval += $this->getRecursiveListForRemoval($path, $matches, $recursive);
100
        }
101
102
        return $scheduleForRemoval;
103
    }
104
105
    /**
106
     * @param SplFileInfo $item
107
     * @return bool
108
     */
109
    private function filter(SplFileInfo $item)
110
    {
111
        $intervalBased = [
112
            'accessAt' => 'ATime',
113
            'modifiedAt' => 'MTime'
114
        ];
115
        foreach ($intervalBased as $property => $getter) {
116
            if (isset($this->getConfig()->{$property})) {
117
                $configValue = $this->getConfig()->{$property};
118
                $compareDate = new DateTime('now');
119
                $compareDate->sub(new DateInterval($configValue));
120
                $timeCleanup = $compareDate->format('U');
121
122
                $time = call_user_func([$item, 'get' . $getter]);
123
                if ($timeCleanup < $time) {
124
                    return false;
125
                }
126
            }
127
        }
128
        return true;
129
    }
130
131
    /**
132
     * @param $path
133
     * @param array $matches
134
     * @param boolean $recursive
135
     * @return array
136
     */
137
    private function getRecursiveListForRemoval($path, array $matches, $recursive)
138
    {
139
        $scheduleForRemoval = [];
140
141
        $dir = new DirectoryIterator($path);
142
        foreach ($dir as $file) {
143
            if ($file->isDir() && !$file->isDot()) {
144
                $scheduleForRemoval = array_merge(
145
                    $scheduleForRemoval,
146
                    $this->getListForRemoval(
147
                        $file->getPathname(),
148
                        $matches,
149
                        $recursive
150
                    )
151
                );
152
            }
153
        }
154
        return $scheduleForRemoval;
155
    }
156
157
    /**
158
     * @param $path
159
     * @param array $matches
160
     * @return array
161
     */
162
    private function calculateMatches($path, array $matches)
163
    {
164
        $scheduleForRemoval = [];
165
166
        foreach ($matches as $match) {
167
            $list = $this->getList($path . '/' . $match);
168
            foreach ($list as $item) {
169
                if ($this->filter($item)) {
170
                    $scheduleForRemoval[] = $item;
171
                }
172
            }
173
        }
174
        return $scheduleForRemoval;
175
    }
176
}
177