UrlRegexFinder   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 29
dl 0
loc 88
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A loadRules() 0 5 1
A __construct() 0 7 1
A find() 0 19 5
A checkRules() 0 13 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebThumbnailer\Finder;
6
7
use WebThumbnailer\Exception\BadRulesException;
8
use WebThumbnailer\Utils\FinderUtils;
9
10
/**
11
 * Generic Finder using regex rules. It will use regex rules to resolve a thumbnail from the provided URL.
12
 * Example:
13
 *   - url_regex: \.com/image/([\w\d]+),
14
 *   - thumbnail_url: "https://domain.com/thumb/${1}"
15
 *   URL: https://domain.com/image/abcdef
16
 *   Will be resolved in  https://domain.com/thumb/abcdef
17
 */
18
class UrlRegexFinder extends FinderCommon
19
{
20
    /** @var string thumbnail_url rule. */
21
    protected $thumbnailUrlFormat;
22
23
    /** @var string Final thumbnail. */
24
    protected $thumbnailUrl;
25
26
    /** @var string Regex to apply on provided URL. */
27
    protected $urlRegex;
28
29
    /**
30
     * @inheritdoc
31
     * @param mixed[]|null $rules   All existing rules loaded from JSON files.
32
     * @param mixed[]|null $options Options provided by the user to retrieve a thumbnail.
33
     */
34
    public function __construct(string $domain, string $url, ?array $rules, ?array $options)
35
    {
36
        $this->url = $url;
37
        $this->domain = $domain;
38
39
        $this->loadRules($rules);
40
        $this->finderOptions = $options;
41
    }
42
43
    /**
44
     * Will replace ${number} in URL format to regex match.
45
     * Also replace eventual URL options.
46
     *
47
     * {@inheritdoc}
48
     *
49
     * @throws BadRulesException
50
     */
51
    public function find()
52
    {
53
        $this->thumbnailUrl = $this->thumbnailUrlFormat;
54
        if (preg_match($this->urlRegex, $this->url, $matches) !== 0) {
55
            $total = count($matches);
56
            for ($i = 1; $i < $total; $i++) {
57
                $this->thumbnailUrl = str_replace('${' . $i . '}', $matches[$i], $this->thumbnailUrl);
58
            }
59
60
            // Match only options (not ${number})
61
            if (preg_match_all('/\${((?!\d)\w+?)}/', $this->thumbnailUrl, $optionsMatch, PREG_PATTERN_ORDER)) {
62
                foreach ($optionsMatch[1] as $value) {
63
                    $this->thumbnailUrl = $this->replaceOption($this->thumbnailUrl, $value);
64
                }
65
            }
66
67
            return $this->thumbnailUrl;
68
        }
69
        return false;
70
    }
71
72
    /**
73
     * Mandatory rules:
74
     *   - url_regex
75
     *   - thumbnail_url
76
     *
77
     * {@inheritdoc}
78
     */
79
    public function checkRules(?array $rules): bool
80
    {
81
        $mandatoryRules = [
82
            'url_regex',
83
            'thumbnail_url',
84
        ];
85
        foreach ($mandatoryRules as $mandatoryRule) {
86
            if (empty($rules[$mandatoryRule])) {
87
                throw new BadRulesException();
88
            }
89
        }
90
91
        return true;
92
    }
93
94
    /** @inheritdoc */
95
    public function loadRules(?array $rules): void
96
    {
97
        $this->checkRules($rules);
98
        $this->urlRegex = FinderUtils::buildRegex($rules['url_regex'], 'i');
99
        $this->thumbnailUrlFormat = $rules['thumbnail_url'];
100
    }
101
102
    /** @inheritdoc */
103
    public function getName(): string
104
    {
105
        return 'URL regex';
106
    }
107
}
108