AbstractParser::attributes()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php namespace Arcanedev\EmbedVideo\Parsers;
2
3
use Arcanedev\EmbedVideo\Contracts\Parser;
4
use Arcanedev\EmbedVideo\Entities\Iframe;
5
use Illuminate\Support\Arr;
6
7
/**
8
 * Class     AbstractParser
9
 *
10
 * @package  Arcanedev\EmbedVideo\Parsers
11
 * @author   ARCANEDEV <[email protected]>
12
 */
13
abstract class AbstractParser implements Parser
14
{
15
    /* -----------------------------------------------------------------
16
     |  Properties
17
     | -----------------------------------------------------------------
18
     */
19
    /**
20
     * The given URL to be parsed.
21
     *
22
     * @var string|null
23
     */
24
    protected $url;
25
26
    /**
27
     * The parser's URL patterns.
28
     *
29
     * @var array
30
     */
31
    protected $patterns   = [];
32
33
    /**
34
     * The iframe attribute.
35
     *
36
     * @var array
37
     */
38
    protected $attributes = [];
39
40
    /**
41
     * @var array
42
     */
43
    protected $cachedMatches;
44
45
    /**
46
     * Use a secure HTTP Protocol.
47
     *
48
     * @var bool
49
     */
50
    protected $useSecure = true;
51
52
    /**
53
     * The HTTP Protocol.
54
     *
55
     * @var string
56
     */
57
    protected $protocol = 'https';
58
59
    /**
60
     * Timestamp pattern and param.
61
     *
62
     * @var array
63
     */
64
    protected $timestamp = [
65
        'pattern' => null,
66
        'param'   => null,
67
    ];
68
69
    /**
70
     * The URL Queries.
71
     *
72
     * @var array
73
     */
74
    protected $queries = [];
75
76
    /* -----------------------------------------------------------------
77
     |  Constructor
78
     | -----------------------------------------------------------------
79
     */
80
    /**
81
     * AbstractParser constructor.
82
     *
83
     * @param  array  $options
84
     */
85 81
    public function __construct(array $options)
86
    {
87 81
        $this->queries  = $this->defaultQueries();
88 81
        $this->patterns = Arr::get($options, 'patterns', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Illuminate\Support\Arr:...s, 'patterns', array()) of type * is incompatible with the declared type array of property $patterns.

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...
89 81
        $this->setAttributes(Arr::get($options, 'attributes', []));
90 81
    }
91
92
    /* -----------------------------------------------------------------
93
     |  Getters & Setters
94
     | -----------------------------------------------------------------
95
     */
96
    /**
97
     * Get the URL.
98
     *
99
     * @return string|null
100
     */
101 21
    public function url()
102
    {
103 21
        return $this->url;
104
    }
105
106
    /**
107
     * Set the URL.
108
     *
109
     * @param  string  $url
110
     *
111
     * @return self
112
     */
113 69
    public function setUrl($url)
114
    {
115 69
        $this->url = $url;
116 69
        $this->reset();
117
118 69
        return $this;
119
    }
120
121
    /**
122
     * Get the attributes.
123
     *
124
     * @return array
125
     */
126 57
    public function attributes()
127
    {
128 57
        return $this->attributes;
129
    }
130
131
    /**
132
     * Set a attribute.
133
     *
134
     * @param  string  $key
135
     * @param  mixed   $value
136
     *
137
     * @return self
138
     */
139 9
    public function setAttribute($key, $value)
140
    {
141 9
        Arr::set($this->attributes, $key, $value);
142
143 9
        return $this;
144
    }
145
146
    /**
147
     * Set the attributes.
148
     *
149
     * @param  array  $attributes
150
     *
151
     * @return self
152
     */
153 81
    public function setAttributes(array $attributes)
154
    {
155 81
        $this->attributes = $attributes;
156
157 81
        return $this;
158
    }
159
160
    /**
161
     * Get the URL queries.
162
     *
163
     * @return array
164
     */
165 42
    public function queries()
166
    {
167 42
        return $this->queries;
168
    }
169
170
    /**
171
     * Set a query parameter.
172
     *
173
     * @param  string  $key
174
     * @param  mixed   $value
175
     *
176
     * @return self
177
     */
178 3
    public function setQuery($key, $value = null)
179
    {
180 3
        $this->queries = Arr::set($this->queries, $key, $value);
181
182 3
        return $this;
183
    }
184
185
    /**
186
     * Prepend a query parameter.
187
     *
188
     * @param  string  $key
189
     * @param  mixed   $value
190
     *
191
     * @return self
192
     */
193 3
    protected function prependQuery($key, $value)
194
    {
195 3
        $this->queries = Arr::prepend($this->queries, $value, $key);
196
197 3
        return $this;
198
    }
199
200
    /**
201
     * Get the default URL queries.
202
     *
203
     * @return array
204
     */
205
    abstract protected function defaultQueries();
206
207
    /**
208
     * Get value from cached matches.
209
     *
210
     * @param  int         $key
211
     * @param  mixed|null  $default
212
     *
213
     * @return mixed
214
     */
215 48
    public function getCached($key, $default = null)
216
    {
217 48
        return Arr::get($this->cachedMatches, $key, $default);
218
    }
219
220
    /**
221
     * Get the iframe pattern.
222
     *
223
     * @return string
224
     */
225
    abstract protected function getIframePattern();
226
227
    /**
228
     * Get the iframe replace.
229
     *
230
     * @return array
231
     */
232
    abstract protected function getIframeReplacer();
233
234
    /* -----------------------------------------------------------------
235
     |  Main method
236
     | -----------------------------------------------------------------
237
     */
238
    /**
239
     * Parse the given url.
240
     *
241
     * @param  string  $url
242
     *
243
     * @return bool
244
     */
245 66
    public function parse($url = null)
246
    {
247 66
        if ( ! is_null($url)) $this->setUrl($url);
248
249 66
        foreach ($this->patterns as $pattern) {
250 66
            if (preg_match('~'.$pattern.'~imu', $this->url, $matches)) {
251 66
                $this->cachedMatches = $matches;
252 66
                $this->parseProtocol();
253 66
                $this->parseTimestamp();
254 66
                $this->parseCustomParsing();
255
256 66
                return true;
257
            }
258 5
        }
259
260 9
        return false;
261
    }
262
263
    /**
264
     * Create an iframe entity.
265
     *
266
     * @return \Arcanedev\EmbedVideo\Entities\Iframe
267
     */
268 30
    public function iframe()
269
    {
270 30
        return new Iframe(
271 30
            $this->getIframePattern(),
272 30
            $this->getIframeReplacer(),
273 30
            $this->queries(),
274 30
            $this->attributes()
275 10
        );
276
    }
277
278
    /* -----------------------------------------------------------------
279
     |  Other Methods
280
     | -----------------------------------------------------------------
281
     */
282
    /**
283
     * Parse the HTTP protocol.
284
     *
285
     * @throws \Exception
286
     */
287 66
    private function parseProtocol()
288
    {
289 66
        $protocol = $this->cachedMatches[1];
290
291 66
        if ( ! in_array($protocol, ['http://', 'https://']))
292 22
            $protocol = 'http://';
293
294 66
        if (is_null($this->url))
295 22
            throw new \Exception('Cannot detect protocol if URL or provider were not set.');
296
297 66
        $this->protocol = ($this->useSecure || $protocol === 'https://') ? 'https' : 'http';
298 66
    }
299
300
    /**
301
     * Parse the timestamp.
302
     */
303 66
    protected function parseTimestamp()
304
    {
305 66
        if ( ! $this->hasTimestampOption()) return;
306
307 36
        if (preg_match('~'.$this->timestamp['pattern'].'~imu', $this->url, $matches)) {
308 21
            unset($matches[0]);
309 21
            $multipliers = [3600, 60, 1];
310 21
            $timestamp   = 0;
311 21
            foreach (array_values($matches) as $key => $match) {
312 21
                $timestamp += (int) $match * $multipliers[$key];
313 7
            }
314 21
            $this->queries[$this->timestamp['param']] = $timestamp;
315 7
        }
316 36
    }
317
318
    /**
319
     * Check if the parser has a defined timestamp parsing.
320
     *
321
     * @return bool
322
     */
323 66
    protected function hasTimestampOption()
324
    {
325 66
        return is_string(Arr::get($this->timestamp, 'pattern'))
326 66
            && is_string(Arr::get($this->timestamp, 'param'));
327
    }
328
329
    /**
330
     * Enable to perform custom parsing.
331
     */
332 66
    protected function parseCustomParsing()
333
    {
334
        //
335 66
    }
336
337
    /**
338
     * Reset the parser.
339
     */
340 69
    private function reset()
341
    {
342 69
        $this->cachedMatches = [];
343 69
        $this->queries       = $this->defaultQueries();
344 69
    }
345
}
346