Completed
Branch middleware (801be0)
by Julián
03:06
created

Janitor::setHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/**
3
 * Effortless maintenance management (http://juliangut.com/janitor)
4
 *
5
 * @link https://github.com/juliangut/janitor for the canonical source repository
6
 *
7
 * @license https://github.com/juliangut/janitor/blob/master/LICENSE
8
 */
9
10
namespace Janitor;
11
12
use Janitor\Handler\Render as RenderHandler;
13
use Psr\Http\Message\ServerRequestInterface;
14
use Psr\Http\Message\ResponseInterface;
15
16
class Janitor
17
{
18
    /**
19
     * List of watchers.
20
     *
21
     * @var array
22
     */
23
    protected $watchers = [];
24
25
    /**
26
     * List of excluders.
27
     *
28
     * @var array
29
     */
30
    protected $excluders = [];
31
32
    /**
33
     * Resolve handler.
34
     *
35
     * @var callable
36
     */
37
    protected $handler;
38
39
    /**
40
     * Request attribute name to store currently active watcher.
41
     *
42
     * @var \Janitor\Watcher
43
     */
44
    protected $attributeName;
45
46
    /**
47
     * @param array                 $watchers
48
     * @param array                 $excluders
49
     * @param \Janitor\Handler|null $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...
50
     * @param string                $requestAttribute
0 ignored issues
show
Bug introduced by
There is no parameter named $requestAttribute. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
51
     */
52
    public function __construct(
53
        array $watchers = [],
54
        array $excluders = [],
55
        callable $handler = null,
56
        $attributeName = 'active_watcher'
57
    ) {
58
        foreach ($watchers as $watcher) {
59
            $this->addWatcher($watcher);
60
        }
61
62
        foreach ($excluders as $excluder) {
63
            $this->addExcluder($excluder);
64
        }
65
66
        $this->handler = $handler;
67
        $this->attributeName = $attributeName;
0 ignored issues
show
Documentation Bug introduced by
It seems like $attributeName of type string is incompatible with the declared type object<Janitor\Watcher> of property $attributeName.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
68
    }
69
70
    /**
71
     * Add maintenance watcher.
72
     *
73
     * @param \Janitor\Watcher $watcher
74
     */
75
    public function addWatcher(Watcher $watcher)
76
    {
77
        $this->watchers[] = $watcher;
78
79
        return $this;
80
    }
81
82
    /**
83
     * Add excluder condition.
84
     *
85
     * @param \Janitor\Excluder $excluder
86
     */
87
    public function addExcluder(Excluder $excluder)
88
    {
89
        $this->excluders[] = $excluder;
90
91
        return $this;
92
    }
93
94
    /**
95
     * Set handler.
96
     *
97
     * @param callable $handler
98
     */
99
    public function setHandler(callable $handler)
100
    {
101
        $this->handler = $handler;
102
103
        return $this;
104
    }
105
106
    /**
107
     * Set request attribute name to store active watcher.
108
     *
109
     * @param string $attributeName
110
     */
111
    public function setAttributeName($attributeName)
112
    {
113
        $this->attributeName = $attributeName;
0 ignored issues
show
Documentation Bug introduced by
It seems like $attributeName of type string is incompatible with the declared type object<Janitor\Watcher> of property $attributeName.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
114
115
        return $this;
116
    }
117
118
    /**
119
     * Get next scheduled time spans.
120
     *
121
     * Returns an array of ['start' => \DateTime, 'end' => \DateTime]
122
     *
123
     * @param int $count
124
     *
125
     * @return array
126
     */
127
    public function getScheduledTimes($count = 5)
128
    {
129
        $scheduledTimes = [];
130
131
        foreach ($this->watchers as $watcher) {
132
            if ($watcher instanceof ScheduledWatcher && $watcher->isScheduled()) {
133
                $scheduledTimes = array_merge($scheduledTimes, $watcher->getScheduledTimes($count));
134
            }
135
        }
136
137
        usort(
138
            $scheduledTimes,
139
            function ($time1, $time2) {
140
                if ($time1['start'] == $time2['start']) {
141
                    return 0;
142
                }
143
144
                return $time1['start'] < $time2['start'] ? -1 : 1;
145
            }
146
        );
147
148
        return array_slice($scheduledTimes, 0, $count);
149
    }
150
151
    /**
152
     * Run middleware.
153
     *
154
     * @param \Psr\Http\Message\ServerRequestInterface $request
155
     * @param \Psr\Http\Message\ResponseInterface      $response
156
     * @param \Janitor\Watcher                          $watcher
0 ignored issues
show
Bug introduced by
There is no parameter named $watcher. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
157
     *
158
     * @return \Psr\Http\Message\ResponseInterface
159
     */
160
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
161
    {
162
        $activeWatcher = $this->getActiveWatcher();
163
164
        if ($activeWatcher instanceof Watcher) {
165
            if (!$this->isExcluded($request)) {
166
                return call_user_func_array($this->getHandler(), [$request, $response, $activeWatcher]);
167
            }
168
169
            $request = $request->withAttribute($this->attributeName, $activeWatcher);
0 ignored issues
show
Documentation introduced by
$this->attributeName is of type object<Janitor\Watcher>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
170
        }
171
172
        return $next($request, $response);
173
    }
174
175
    /**
176
     * Get currenlty active watcher.
177
     *
178
     * @return \Janitor\Watcher|null
179
     */
180
    protected function getActiveWatcher()
181
    {
182
        foreach ($this->watchers as $watcher) {
183
            if ($watcher->isActive()) {
184
                return $watcher;
185
            }
186
        }
187
188
        return null;
189
    }
190
191
    /**
192
     * Whether excluding conditions are met.
193
     *
194
     * @param \Psr\Http\Message\ServerRequestInterface $request
195
     *
196
     * @return bool
197
     */
198
    protected function isExcluded(ServerRequestInterface $request)
199
    {
200
        foreach ($this->excluders as $excluder) {
201
            if ($excluder->isExcluded($request)) {
202
                return true;
203
            }
204
        }
205
206
        return false;
207
    }
208
209
    /**
210
     * Retrieve handler.
211
     *
212
     * @return callable
213
     */
214
    protected function getHandler()
215
    {
216
        if (!is_callable($this->handler)) {
217
            $this->handler = new RenderHandler;
218
        }
219
220
        return $this->handler;
221
    }
222
}
223