Passed
Push — master ( 458ee2...f834dc )
by Ryan
17:46 queued 02:16
created

Feed::getAlias()   D

Complexity

Conditions 10
Paths 10

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 18
nc 10
nop 1
dl 0
loc 26
rs 4.8196
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
 * Copyright (c) 2017–2018 Ryan Parman <http://ryanparman.com>.
4
 * Copyright (c) 2017–2018 Contributors.
5
 *
6
 * http://opensource.org/licenses/Apache2.0
7
 */
8
9
declare(strict_types=1);
10
11
namespace SimplePie\Type;
12
13
use DateTime;
14
use DateTimeZone;
15
use Psr\Log\NullLogger;
16
use SimplePie\Configuration as C;
17
use SimplePie\Exception\SimplePieException;
18
use SimplePie\Mixin\LoggerTrait;
19
use SimplePie\Parser\Date as DateParser;
20
use stdClass;
21
22
/**
23
 * Represents the top-level of a feed.
24
 */
25
class Feed extends AbstractType implements TypeInterface, C\SetLoggerInterface
26
{
27
    use LoggerTrait;
28
29
    /**
30
     * The root-most node in the feed.
31
     *
32
     * @var stdClass
33
     */
34
    protected $root;
35
36
    /**
37
     * The preferred namespace alias for a given XML namespace URI. Should be
38
     * the result of a call to `SimplePie\Util\Ns`.
39
     *
40
     * @var string
41
     */
42
    protected $namespaceAlias;
43
44
    /**
45
     * The format that should be used when determining how to parse a date from a date string.
46
     *
47
     * @var string
48
     */
49
    protected $createFromFormat;
50
51
    /**
52
     * The preferred timezone to use for date output.
53
     *
54
     * @var string
55
     */
56
    protected $outputTimezone;
57
58
    /**
59
     * Constructs a new instance of this class.
60
     *
61
     * @param string $namespaceAlias [description]
62
     */
63
    public function __construct(string $namespaceAlias)
64
    {
65
        $this->root           = new stdClass();
66
        $this->logger         = new NullLogger();
67
        $this->namespaceAlias = $namespaceAlias;
68
    }
69
70
    /**
71
     * Allows the user to help the date parser by providing the format of the datestamp in the feed.
72
     *
73
     * This will be passed into `DateTime::createFromFormat()` at parse-time.
74
     *
75
     * @param string $createFromFormat The format of the datestamp in the feed.
76
     *
77
     * @return self
78
     *
79
     * @see http://php.net/manual/en/datetime.createfromformat.php
80
     */
81
    public function setDateFormat(string $createFromFormat): self
82
    {
83
        $this->createFromFormat = $createFromFormat;
84
85
        return $this;
86
    }
87
88
    /**
89
     * Set the preferred output timezone.
90
     *
91
     * This calculation is performed on a _best-effort_ basis and is not guaranteed. Factors which may affect the
92
     * calculation include:
93
     *
94
     * * the version of glibc/musl that your OS relies on
95
     * * the freshness of the timestamp data your OS relies on
96
     * * the format of the datestamp inside of the feed and PHP's ability to parse it
97
     *
98
     * @param string $timezone The timezone identifier to use. Must be compatible with `DateTimeZone`. The default
99
     *                         value is `UTC`.
100
     *
101
     * @return self
102
     */
103
    public function setOutputTimezone(string $timezone = 'UTC'): self
104
    {
105
        $this->outputTimezone = $timezone;
106
107
        return $this;
108
    }
109
110
    //--------------------------------------------------------------------------
111
    // INTERNAL
112
113
    /**
114
     * Retrieve the root-most node in the feed.
115
     *
116
     * @return stdClass
117
     */
118
    public function getRoot(): stdClass
119
    {
120
        return $this->root;
121
    }
122
123
    /**
124
     * Finds the common internal alias for a given method name.
125
     *
126
     * @param string $nodeName The name of the method being called.
127
     *
128
     * @return string
129
     *
130
     * phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
131
     */
132
    protected function getAlias(string $nodeName): string
133
    {
134
        switch ($nodeName) {
135
            case 'categories':
136
                return 'category';
137
138
            case 'contributors':
139
                return 'contributor';
140
141
            case 'entries':
142
            case 'items':
143
                return 'entry';
144
145
            case 'language':
146
                return 'lang';
147
148
            case 'links':
149
                return 'link';
150
151
            case 'pubDate':
152
            case 'publishDate':
153
            case 'publishedDate':
154
                return 'published';
155
156
            default:
157
                return $nodeName;
158
        }
159
    }
160
161
    // phpcs:enable
162
163
    /**
164
     * Get the correct handler for a whitelisted method name.
165
     *
166
     * @param string $nodeName The name of the method being called.
167
     * @param array  $args     Any arguments passed into that method.
168
     *
169
     * @throws SimplePieException
170
     *
171
     * @return mixed
172
     *
173
     * phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
174
     */
175
    protected function getHandler(string $nodeName, array $args)
176
    {
177
        switch ($nodeName) {
178
            case 'id':
179
            case 'lang':
180
            case 'rights':
181
            case 'subtitle':
182
            case 'summary':
183
            case 'title':
184
                return $this->getScalarSingleValue($nodeName, $args[0]);
185
186
            case 'published':
187
            case 'updated':
188
                return (new DateParser(
189
                    $this->getScalarSingleValue($nodeName, $args[0])->getValue(),
190
                    $this->outputTimezone,
191
                    $this->createFromFormat
192
                ))->getDateTime();
193
194
            case 'author':
195
                return $this->getComplexSingleValue($nodeName, Person::class, $args[0]);
196
197
            case 'generator':
198
                return $this->getComplexSingleValue($nodeName, Generator::class, $args[0]);
199
200
            case 'icon':
201
            case 'logo':
202
                return $this->getComplexSingleValue($nodeName, Image::class, $args[0]);
203
204
            case 'category':
205
            case 'contributor':
206
            case 'entry':
207
            case 'link':
208
                return $this->getComplexMultipleValues($nodeName, $args[0]);
209
210
            default:
211
                throw new SimplePieException(
212
                    $this->getUnresolvableMessage($nodeName)
213
                );
214
        }
215
    }
216
217
    // phpcs:enable
218
219
    /**
220
     * Retrieves nodes that are simple scalars, and there is only one allowed value.
221
     *
222
     * @param string      $nodeName       The name of the tree node to retrieve. Available tree nodes can be viewed by
223
     *                                    looking at the response from `getRoot()`.
224
     * @param string|null $namespaceAlias The XML namespace alias to apply.
225
     *
226
     * @return Node
227
     */
228
    protected function getScalarSingleValue(string $nodeName, ?string $namespaceAlias = null): Node
229
    {
230
        $alias = $namespaceAlias ?? $this->namespaceAlias;
231
232
        if (isset($this->getRoot()->{$nodeName}[$alias])) {
233
            return $this->getRoot()->{$nodeName}[$alias];
234
        }
235
236
        return new Node();
237
    }
238
239
    /**
240
     * Retrieves nodes that are complex types, and there is only one allowed value.
241
     *
242
     * @param string      $nodeName       The name of the tree node to retrieve. Available tree nodes can be viewed by
243
     *                                    looking at the response from `getRoot()`.
244
     * @param string      $className      The class name to instantiate when there is not a defined value.
245
     * @param string|null $namespaceAlias The XML namespace alias to apply.
246
     *
247
     * @return TypeInterface
248
     *
249
     * phpcs:disable Generic.Functions.OpeningFunctionBraceBsdAllman.BraceOnSameLine
250
     */
251
    protected function getComplexSingleValue(
252
        string $nodeName,
253
        string $className,
254
        ?string $namespaceAlias = null
255
    ): TypeInterface {
256
        // phpcs:enable
257
258
        $alias = $namespaceAlias ?? $this->namespaceAlias;
259
260
        if (isset($this->getRoot()->{$nodeName}[$alias])) {
261
            return new $className($this->getRoot()->{$nodeName}[$alias]->getNode());
262
        }
263
264
        return new $className();
265
    }
266
267
    /**
268
     * Retrieves nodes that are complex types, and there may be are more than one value.
269
     *
270
     * @param string      $nodeName       The name of the tree node to retrieve. Available tree nodes can be viewed by
271
     *                                    looking at the response from `getRoot()`.
272
     * @param string|null $namespaceAlias The XML namespace alias to apply.
273
     *
274
     * @return iterable
275
     */
276
    protected function getComplexMultipleValues(string $nodeName, ?string $namespaceAlias = null): iterable
277
    {
278
        $alias = $namespaceAlias ?? $this->namespaceAlias;
279
280
        if (isset($this->getRoot()->{$nodeName}[$alias])) {
281
            return $this->getRoot()->{$nodeName}[$alias];
282
        }
283
284
        return [];
285
    }
286
}
287