Runner   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 0
Metric Value
wmc 25
lcom 3
cbo 3
dl 0
loc 225
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 3
A addWatcher() 0 6 1
A addExcluder() 0 6 1
A setHandler() 0 6 1
A setAttributeName() 0 6 1
A getAttributeName() 0 4 1
B getScheduledTimes() 0 23 6
A __invoke() 0 14 3
A getActiveWatcher() 0 8 3
A isExcluded() 0 10 3
A getHandler() 0 8 2
1
<?php
2
3
/*
4
 * janitor (http://juliangut.com/janitor).
5
 * Effortless maintenance management.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/janitor
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Janitor;
13
14
use Janitor\Excluder\ExcluderInterface;
15
use Janitor\Handler\Render as RenderHandler;
16
use Janitor\Watcher\ScheduledWatcherInterface;
17
use Janitor\Watcher\WatcherInterface;
18
use Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
21
/**
22
 * Janitor runner.
23
 */
24
class Runner
25
{
26
    /**
27
     * List of watchers.
28
     *
29
     * @var array
30
     */
31
    protected $watchers = [];
32
33
    /**
34
     * List of excluders.
35
     *
36
     * @var array
37
     */
38
    protected $excluders = [];
39
40
    /**
41
     * Resolve handler.
42
     *
43
     * @var callable
44
     */
45
    protected $handler;
46
47
    /**
48
     * Request attribute name to store currently active watcher.
49
     *
50
     * @var string
51
     */
52
    protected $attributeName;
53
54
    /**
55
     * Runner constructor.
56
     *
57
     * @param array    $watchers
58
     * @param array    $excluders
59
     * @param callable $handler
0 ignored issues
show
Documentation introduced by
Should the type for parameter $handler not be null|callable? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
60
     * @param string   $attributeName
61
     */
62
    public function __construct(
63
        array $watchers = [],
64
        array $excluders = [],
65
        callable $handler = null,
66
        $attributeName = 'active_watcher'
67
    ) {
68
        foreach ($watchers as $watcher) {
69
            $this->addWatcher($watcher);
70
        }
71
72
        foreach ($excluders as $excluder) {
73
            $this->addExcluder($excluder);
74
        }
75
76
        $this->handler = $handler;
77
        $this->attributeName = $attributeName;
78
    }
79
80
    /**
81
     * Add maintenance watcher.
82
     *
83
     * @param WatcherInterface $watcher
84
     *
85
     * @return $this
86
     */
87
    public function addWatcher(WatcherInterface $watcher)
88
    {
89
        $this->watchers[] = $watcher;
90
91
        return $this;
92
    }
93
94
    /**
95
     * Add excluder condition.
96
     *
97
     * @param ExcluderInterface $excluder
98
     *
99
     * @return $this
100
     */
101
    public function addExcluder(ExcluderInterface $excluder)
102
    {
103
        $this->excluders[] = $excluder;
104
105
        return $this;
106
    }
107
108
    /**
109
     * Set handler.
110
     *
111
     * @param callable $handler
112
     *
113
     * @return $this
114
     */
115
    public function setHandler(callable $handler)
116
    {
117
        $this->handler = $handler;
118
119
        return $this;
120
    }
121
122
    /**
123
     * Set request attribute name to store active watcher.
124
     *
125
     * @param string $attributeName
126
     *
127
     * @return $this
128
     */
129
    public function setAttributeName($attributeName)
130
    {
131
        $this->attributeName = $attributeName;
132
133
        return $this;
134
    }
135
136
    /**
137
     * Retrieve request attribute name storing active watcher.
138
     *
139
     * @return string
140
     */
141
    public function getAttributeName()
142
    {
143
        return $this->attributeName;
144
    }
145
146
    /**
147
     * Get next scheduled time spans.
148
     *
149
     * Returns an array of ['start' => \DateTime, 'end' => \DateTime]
150
     *
151
     * @param int $count
152
     *
153
     * @return array
154
     */
155
    public function getScheduledTimes($count = 5)
156
    {
157
        $scheduledTimes = [];
158
159
        foreach ($this->watchers as $watcher) {
160
            if ($watcher instanceof ScheduledWatcherInterface && $watcher->isScheduled()) {
161
                $scheduledTimes = array_merge($scheduledTimes, $watcher->getScheduledTimes($count));
162
            }
163
        }
164
165
        usort(
166
            $scheduledTimes,
167
            function ($time1, $time2) {
168
                if ($time1['start'] === $time2['start']) {
169
                    return 0;
170
                }
171
172
                return $time1['start'] < $time2['start'] ? -1 : 1;
173
            }
174
        );
175
176
        return array_slice($scheduledTimes, 0, $count);
177
    }
178
179
    /**
180
     * Run middleware.
181
     *
182
     * @param ServerRequestInterface $request
183
     * @param ResponseInterface      $response
184
     * @param callable               $next
185
     *
186
     * @return ResponseInterface
187
     */
188
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
189
    {
190
        $activeWatcher = $this->getActiveWatcher();
191
192
        if ($activeWatcher !== null) {
193
            if (!$this->isExcluded($request)) {
194
                return call_user_func($this->getHandler(), $request, $response, $activeWatcher);
195
            }
196
197
            $request = $request->withAttribute($this->getAttributeName(), $activeWatcher);
198
        }
199
200
        return $next($request, $response);
201
    }
202
203
    /**
204
     * Get currently active watcher.
205
     *
206
     * @return WatcherInterface
207
     */
208
    protected function getActiveWatcher()
209
    {
210
        foreach ($this->watchers as $watcher) {
211
            if ($watcher->isActive()) {
212
                return $watcher;
213
            }
214
        }
215
    }
216
217
    /**
218
     * Whether excluding conditions are met.
219
     *
220
     * @param ServerRequestInterface $request
221
     *
222
     * @return bool
223
     */
224
    protected function isExcluded(ServerRequestInterface $request)
225
    {
226
        foreach ($this->excluders as $excluder) {
227
            if ($excluder->isExcluded($request)) {
228
                return true;
229
            }
230
        }
231
232
        return false;
233
    }
234
235
    /**
236
     * Retrieve handler.
237
     *
238
     * @return callable
239
     */
240
    protected function getHandler()
241
    {
242
        if (!is_callable($this->handler)) {
243
            $this->handler = new RenderHandler;
244
        }
245
246
        return $this->handler;
247
    }
248
}
249