Completed
Pull Request — master (#384)
by Damian
04:46
created

CrawlerDetect::setCrawlers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of Crawler Detect - the web crawler detection library.
5
 *
6
 * (c) Mark Beech <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Jaybizzle\CrawlerDetect;
13
14
use Jaybizzle\CrawlerDetect\Fixtures\Crawlers;
15
use Jaybizzle\CrawlerDetect\Fixtures\Exclusions;
16
use Jaybizzle\CrawlerDetect\Fixtures\Headers;
17
18
class CrawlerDetect
19
{
20
    /**
21
     * The user agent.
22
     *
23
     * @var string
24
     */
25
    protected $userAgent = null;
26
27
    /**
28
     * Headers that contain a user agent.
29
     *
30
     * @var string[]
31
     */
32
    protected $httpHeaders = array();
33
34
    /**
35
     * Store regex matches.
36
     *
37
     * @var array
38
     */
39
    protected $matches = array();
40
41
    /**
42
     * Crawlers object.
43
     *
44
     * @var Crawlers
45
     */
46
    protected $crawlers;
47
48
    /**
49
     * Exclusions object.
50
     *
51
     * @var Exclusions
52
     */
53
    protected $exclusions;
54
55
    /**
56
     * Headers object.
57
     *
58
     * @var Headers
59
     */
60
    protected $uaHttpHeaders;
61
62
    /**
63
     * The compiled regex string.
64
     *
65
     * @var string
66
     */
67
    protected $compiledRegex;
68
69
    /**
70
     * The compiled exclusions regex string.
71
     *
72
     * @var string
73
     */
74
    protected $compiledExclusions;
75
76
    /**
77
     * Class constructor.
78
     *
79
     * @param string[] $headers   Map of HTTP header values
80
     * @param string   $userAgent Browser user agent to detect
81
     */
82
    public function __construct(array $headers = null, $userAgent = null)
83
    {
84
        $this->setCrawlers(new Crawlers());
85
        $this->setExclusions(new Exclusions());
86
        $this->setUaHttpHeaders(new Headers());
87
        $this->setHttpHeaders($headers);
88
        $this->setUserAgent($userAgent);
89
    }
90
91
    /**
92
     * Compile the regex patterns into one regex string.
93
     *
94
     * @param array
95
     *
96
     * @return string
97
     */
98
    public function compileRegex($patterns)
99
    {
100
        return '(' . implode('|', $patterns) . ')';
101
    }
102
103
    /**
104
     * Get HTTP Headers
105
     *
106
     * @return array
107
     */
108
    public function getHttpHeaders()
109
    {
110
        return $this->httpHeaders;
111
    }
112
113
    /**
114
     * Set HTTP headers.
115
     *
116
     * @param array|null $httpHeaders
117
     * @return $this
118
     */
119
    public function setHttpHeaders($httpHeaders)
120
    {
121
        // Use global _SERVER if $httpHeaders aren't defined.
122
        if (empty($httpHeaders)) {
123
            $httpHeaders = $_SERVER;
124
        }
125
126
        // Clear existing headers.
127
        $this->httpHeaders = [];
128
129
        // Only save HTTP headers. In PHP land, that means
130
        // only _SERVER vars that start with HTTP_.
131
        foreach ($httpHeaders as $key => $value) {
132
            if (strpos($key, 'HTTP_') === 0) {
133
                $this->httpHeaders[$key] = $value;
134
            }
135
        }
136
137
        return $this;
138
    }
139
140
    /**
141
     * Return user agent headers.
142
     *
143
     * @return string[]
144
     */
145
    public function getUaHttpHeaders()
146
    {
147
        return $this->uaHttpHeaders->getAll();
148
    }
149
150
    /**
151
     * Assign headers used to detect user agent
152
     *
153
     * @param Headers $headers
154
     * @return $this
155
     */
156
    public function setUaHttpHeaders(Headers $headers)
157
    {
158
        $this->uaHttpHeaders = $headers;
159
        return $this;
160
    }
161
162
    /**
163
     * Get, or detect, user agent string
164
     *
165
     * @return string
166
     */
167
    public function getUserAgent()
168
    {
169
        if ($this->userAgent) {
170
            return $this->userAgent;
171
        }
172
173
        // Detect from headers
174
        $userAgent = '';
175
        $headers = $this->getHttpHeaders();
176
        foreach ($this->getUaHttpHeaders() as $altHeader) {
177
            if (isset($headers[$altHeader])) {
178
                $userAgent .= $headers[$altHeader] . ' ';
179
            }
180
        }
181
        return $userAgent;
182
    }
183
184
    /**
185
     * Set the user agent.
186
     *
187
     * @param string $userAgent
188
     * @return $this
189
     */
190
    public function setUserAgent($userAgent)
191
    {
192
        $this->userAgent = $userAgent;
193
        return $this;
194
    }
195
196
    /**
197
     * Get crawlers list
198
     *
199
     * @return string[]
200
     */
201
    public function getCrawlers()
202
    {
203
        return $this->crawlers->getAll();
204
    }
205
206
    /**
207
     * @param Crawlers $crawlers
208
     * @return $this
209
     */
210
    public function setCrawlers(Crawlers $crawlers)
211
    {
212
        $this->crawlers = $crawlers;
213
        $this->compiledRegex = $this->compileRegex($this->getCrawlers());
214
        return $this;
215
    }
216
217
    /**
218
     * Get exclusions list
219
     *
220
     * @return string[]
221
     */
222
    public function getExclusions()
223
    {
224
        return $this->exclusions->getAll();
225
    }
226
227
    /**
228
     * @param Exclusions $exclusions
229
     * @return $this
230
     */
231
    public function setExclusions(Exclusions $exclusions)
232
    {
233
        $this->exclusions = $exclusions;
234
        $this->compiledExclusions = $this->compileRegex($this->getExclusions());
235
        return $this;
236
    }
237
238
    /**
239
     * Check user agent string against the regex.
240
     *
241
     * @param string|null $userAgent
242
     *
243
     * @return bool
244
     */
245
    public function isCrawler($userAgent = null)
246
    {
247
        $agent = trim(preg_replace(
248
            "/{$this->compiledExclusions}/i",
249
            '',
250
            $userAgent ?: $this->getUserAgent()
251
        ));
252
253
        if ($agent == '') {
254
            return false;
255
        }
256
257
        $result = preg_match("/{$this->compiledRegex}/i", $agent, $matches);
258
259
        if ($matches) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
260
            $this->matches = $matches;
261
        }
262
263
        return (bool)$result;
264
    }
265
266
    /**
267
     * Return the matches.
268
     *
269
     * @return string|null
270
     */
271
    public function getMatches()
272
    {
273
        return isset($this->matches[0]) ? $this->matches[0] : null;
274
    }
275
}
276