TargetBuilder::validateDefinition()   B
last analyzed

Complexity

Conditions 9
Paths 12

Size

Total Lines 55
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 28
nc 12
nop 1
dl 0
loc 55
rs 8.0555
c 0
b 0
f 0

How to fix   Long Method   

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 ReliqArts\Scavenger\Factory;
6
7
use ReliqArts\Scavenger\Exception\Exception;
8
use ReliqArts\Scavenger\Exception\InvalidTargetDefinition;
9
use ReliqArts\Scavenger\Helper\FormattedMessage;
10
use ReliqArts\Scavenger\Helper\TargetKey;
11
use ReliqArts\Scavenger\Model\Target;
12
use ReliqArts\Scavenger\Result;
13
use ReliqArts\Scavenger\Service\Scanner;
14
15
final class TargetBuilder
16
{
17
    /**
18
     * @var array
19
     */
20
    private array $globalKeywords;
21
22
    /**
23
     * TargetBuilder constructor.
24
     */
25
    public function __construct(array $globalKeywords = [])
26
    {
27
        $this->globalKeywords = $globalKeywords;
28
    }
29
30
    /**
31
     * @throws Exception
32
     */
33
    public function createFromDefinition(array $definition): Target
34
    {
35
        $validityResult = $this->validateDefinition($definition);
36
        if (!$validityResult->isSuccess()) {
37
            throw InvalidTargetDefinition::fromResult($validityResult);
38
        }
39
40
        // aggregate keywords
41
        if (!(empty($this->globalKeywords) || empty($definition[TargetKey::SEARCH]))) {
42
            $definition[TargetKey::SEARCH][TargetKey::SEARCH_KEYWORDS] = array_merge(
43
                $this->globalKeywords,
44
                $definition[TargetKey::SEARCH][TargetKey::SEARCH_KEYWORDS]
45
            );
46
        }
47
48
        return new Target(
49
            $definition[TargetKey::NAME],
50
            $definition[TargetKey::MODEL],
51
            $definition[TargetKey::SOURCE],
52
            $definition[TargetKey::MARKUP],
53
            $definition[TargetKey::PAGER] ?? [],
54
            $definition[TargetKey::PAGES] ?? 0,
55
            $definition[TargetKey::DISSECT] ?? [],
56
            $definition[TargetKey::PREPROCESS] ?? [],
57
            $definition[TargetKey::REMAP] ?? [],
58
            $definition[TargetKey::BAD_WORDS] ?? [],
59
            $definition[TargetKey::SEARCH] ?? [],
60
            $definition[TargetKey::SEARCH_ENGINE_REQUEST_PAGES] ?? false,
61
            $definition[TargetKey::EXAMPLE] ?? false
62
        );
63
    }
64
65
    private function validateDefinition(array $definition): Result
66
    {
67
        $result = new Result(true);
68
69
        if (empty($definition[TargetKey::NAME])) {
70
            return $result->setSuccess(false)->addError(
71
                FormattedMessage::get(
72
                    FormattedMessage::TARGET_NAME_MISSING,
73
                    sprintf('[%s]', TargetKey::NAME)
74
                )
75
            );
76
        }
77
78
        $targetName = $definition[TargetKey::NAME];
79
80
        if (!empty($definition['example']) && $definition['example']) {
81
            return $result->setSuccess(false)->addError(
82
                FormattedMessage::get(FormattedMessage::EXAMPLE_TARGET, $targetName)
83
            );
84
        }
85
86
        // ensure model can be resolved
87
        try {
88
            $definition[TargetKey::MODEL] = resolve($definition[TargetKey::MODEL]);
89
        } catch (Exception $e) {
90
            return $result->setSuccess(false)->addError(
91
                FormattedMessage::get(FormattedMessage::TARGET_MODEL_RESOLUTION_FAILED, $targetName, $e->getMessage())
92
            );
93
        }
94
95
        if (empty($definition[TargetKey::SOURCE])) {
96
            return $result->setSuccess(false)->addError(
97
                FormattedMessage::get(FormattedMessage::TARGET_SOURCE_MISSING, $targetName)
98
            );
99
        }
100
101
        // validate markup definition
102
        $markupValidityResult = $this->validateMarkupDefinition($definition[TargetKey::MARKUP], $targetName);
103
        if ($markupValidityResult->hasErrors()) {
104
            $result = $result->setSuccess(false)->addErrors($markupValidityResult->getErrors());
105
        }
106
107
        // validate pager definition
108
        $pagerValidityResult = $this->validatePagerDefinition($definition[TargetKey::PAGER]);
109
        if ($pagerValidityResult->hasErrors()) {
110
            $result = $result->setSuccess(false)->addErrors($pagerValidityResult->getErrors());
111
        }
112
113
        // validate search definition
114
        $searchValidityResult = $this->validateSearchDefinition($definition[TargetKey::SEARCH], $targetName);
115
        if ($searchValidityResult->hasErrors()) {
116
            $result = $result->setSuccess(false)->addErrors($searchValidityResult->getErrors());
117
        }
118
119
        return $result;
120
    }
121
122
    private function validateMarkupDefinition(?array $markupDefinition, string $targetName): Result
123
    {
124
        $result = new Result(true);
125
126
        if (empty($markupDefinition)) {
127
            return $result;
128
        }
129
130
        $titleOrLinkExists = !empty(
131
            Scanner::firstNonEmpty($markupDefinition, [TargetKey::MARKUP_TITLE, TargetKey::MARKUP_LINK])
132
        );
133
        if (!$titleOrLinkExists) {
134
            $result = $result->setSuccess(false)->addError(
135
                FormattedMessage::get(
136
                    FormattedMessage::TARGET_MISSING_TITLE_LINK,
137
                    $targetName
138
                )
139
            );
140
        }
141
142
        if (empty($markupDefinition[TargetKey::special(TargetKey::MARKUP_INSIDE)])
143
            && empty(
144
                Scanner::firstNonEmpty($markupDefinition, [
145
                    TargetKey::special(TargetKey::ITEM_WRAPPER),
146
                    TargetKey::special(TargetKey::RESULT),
147
                    TargetKey::special(TargetKey::ITEM),
148
                    TargetKey::special(TargetKey::WRAPPER),
149
                ])
150
            )
151
        ) {
152
            $result = $result->setSuccess(false)->addError(
153
                FormattedMessage::get(
154
                    FormattedMessage::TARGET_MISSING_ITEM_WRAPPER,
155
                    $targetName
156
                )
157
            );
158
        }
159
160
        return $result;
161
    }
162
163
    private function validatePagerDefinition(?array $pagerDefinition): Result
164
    {
165
        $result = new Result(true);
166
167
        if (empty($pagerDefinition)) {
168
            return $result;
169
        }
170
171
        if (empty($pagerDefinition[TargetKey::PAGER_SELECTOR])) {
172
            $result = $result->setSuccess(false);
173
        }
174
175
        return $result;
176
    }
177
178
    private function validateSearchDefinition(?array $searchDefinition, string $targetName): Result
179
    {
180
        $result = new Result(true);
181
182
        if (empty($searchDefinition)) {
183
            return $result->setSuccess(true);
184
        }
185
186
        // ensure form requirements are set
187
        if (empty($searchDefinition[TargetKey::SEARCH_FORM][TargetKey::SEARCH_FORM_SELECTOR])) {
188
            // form selector
189
            $result = $result->setSuccess(false)->addError(
190
                FormattedMessage::get(
191
                    FormattedMessage::MISSING_SEARCH_KEY,
192
                    'form selector config',
193
                    sprintf('[%s][%s][%s]', TargetKey::SEARCH, TargetKey::SEARCH_FORM, TargetKey::SEARCH_FORM_SELECTOR),
194
                    $targetName
195
                )
196
            );
197
        } elseif (empty($searchDefinition[TargetKey::SEARCH_FORM][TargetKey::SEARCH_FORM_INPUT])) {
198
            // form keyword input name
199
            $result = $result->setSuccess(false)->addError(
200
                FormattedMessage::get(
201
                    FormattedMessage::MISSING_SEARCH_KEY,
202
                    'keyword input name',
203
                    sprintf('[%s][%s][%s]', TargetKey::SEARCH, TargetKey::SEARCH_FORM, TargetKey::SEARCH_FORM_INPUT),
204
                    $targetName
205
                )
206
            );
207
        } elseif (empty($this->globalKeywords) && empty($searchDefinition[TargetKey::SEARCH_KEYWORDS])) {
208
            // search keyword list empty
209
            $result = $result->setSuccess(false)->addError(
210
                FormattedMessage::get(
211
                    FormattedMessage::MISSING_SEARCH_KEY,
212
                    'keywords',
213
                    sprintf('[%s][%s]', TargetKey::SEARCH, TargetKey::SEARCH_KEYWORDS),
214
                    $targetName
215
                )
216
            );
217
        }
218
219
        return $result;
220
    }
221
}
222