FinderFactory::getThumbnailMeta()   C
last analyzed

Complexity

Conditions 12
Paths 122

Size

Total Lines 46
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 26
nc 122
nop 2
dl 0
loc 46
rs 6.7833
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebThumbnailer\Finder;
6
7
use WebThumbnailer\Application\ConfigManager;
8
use WebThumbnailer\Exception\BadRulesException;
9
use WebThumbnailer\Exception\IOException;
10
use WebThumbnailer\Exception\UnsupportedDomainException;
11
use WebThumbnailer\Utils\DataUtils;
12
use WebThumbnailer\Utils\FileUtils;
13
use WebThumbnailer\Utils\FinderUtils;
14
use WebThumbnailer\Utils\UrlUtils;
15
16
/**
17
 * Find the appropriate Finder for a given URL, instantiate it and load its rules.
18
 */
19
class FinderFactory
20
{
21
    /**
22
     * Creates a finder object for a given URL.
23
     *
24
     * @param string $url given URL.
25
     *
26
     * @return Finder object.
27
     *
28
     * @throws BadRulesException
29
     * @throws IOException
30
     */
31
    public static function getFinder(string $url): Finder
32
    {
33
        $domain = UrlUtils::getDomain($url);
34
        try {
35
            list($domain, $finder, $rules, $options) = static::getThumbnailMeta($domain, $url);
36
37
            $className = '\\WebThumbnailer\\Finder\\' . $finder . 'Finder';
38
            if (!class_exists($className)) {
39
                throw new UnsupportedDomainException();
40
            }
41
        } catch (UnsupportedDomainException $e) {
42
            $className = '\\WebThumbnailer\\Finder\\DefaultFinder';
43
            $rules = [];
44
            $options = [];
45
        }
46
47
        return new $className($domain, $url, $rules, $options);
48
    }
49
50
    /**
51
     * Retrieve JSON metadata for the given domains.
52
     *
53
     * @param string $inputDomain Domain to search.
54
     * @param string $url         Complete URL.
55
     *
56
     * @return mixed[] [domains, finder name, rules, options].
57
     *
58
     * @throws UnsupportedDomainException No rules found for the domains.
59
     * @throws BadRulesException          Mandatory rules not found for the domains.
60
     * @throws IOException
61
     */
62
    public static function getThumbnailMeta(string $inputDomain, string $url): array
63
    {
64
        // Load JSON rule files.
65
        $jsonFiles = ConfigManager::get('settings.rules_filename', ['rules.json']);
66
        $allRules = [];
67
        foreach ($jsonFiles as $file) {
68
            $allRules = array_merge($allRules, DataUtils::loadJson(FileUtils::RESOURCES_PATH . $file));
69
        }
70
71
        $domain = null;
72
73
        foreach ($allRules as $value) {
74
            static::checkMetaFormat($value);
75
76
            $domainFound = false;
77
            foreach ($value['domains'] as $domain) {
78
                if (strpos($inputDomain, $domain) !== false) {
79
                    $domainFound = true;
80
                    break;
81
                }
82
            }
83
84
            if (!$domainFound) {
85
                continue;
86
            }
87
88
            if (!empty($value['url_exclude'])) {
89
                preg_match(FinderUtils::buildRegex($value['url_exclude'], 'i'), $url, $match);
90
                if (!empty($match)) {
91
                    continue;
92
                }
93
            }
94
95
            if (!empty($value['url_require'])) {
96
                preg_match(FinderUtils::buildRegex($value['url_require'], 'i'), $url, $match);
97
                if (empty($match)) {
98
                    continue;
99
                }
100
            }
101
102
            $value['rules'] = !empty($value['rules']) ? $value['rules'] : [];
103
            $value['options'] = !empty($value['options']) ? $value['options'] : [];
104
            return [$domain, $value['finder'], $value['rules'], $value['options']];
105
        }
106
107
        throw new UnsupportedDomainException();
108
    }
109
110
    /**
111
     * Make sure that mandatory directives are present in the metadata.
112
     *
113
     * @param mixed[] $rules JSON directives.
114
     *
115
     * @return bool True if the check is successful.
116
     *
117
     * @throws BadRulesException Mandatory rules not found for the domains.
118
     */
119
    public static function checkMetaFormat(array $rules): bool
120
    {
121
        $mandatoryDirectives = ['domains', 'finder'];
122
        foreach ($mandatoryDirectives as $mandatoryDirective) {
123
            if (empty($rules[$mandatoryDirective])) {
124
                throw new BadRulesException();
125
            }
126
        }
127
128
        return true;
129
    }
130
}
131