Completed
Push — master ( afaf06...4e20f4 )
by Jérémy
01:21
created

FeedReader::readItemNode()   C

Complexity

Conditions 11
Paths 28

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 28
nc 28
nop 1

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
namespace JDecool\JsonFeed\Reader\Version1;
4
5
use DateTime;
6
use JDecool\JsonFeed\Attachment;
7
use JDecool\JsonFeed\Author;
8
use JDecool\JsonFeed\Exceptions\InvalidFeedException;
9
use JDecool\JsonFeed\Feed;
10
use JDecool\JsonFeed\Hub;
11
use JDecool\JsonFeed\Item;
12
use JDecool\JsonFeed\Reader\ReaderInterface;
13
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
14
use Symfony\Component\PropertyAccess\PropertyAccess;
15
16
class FeedReader implements ReaderInterface
17
{
18
    /** @var \Symfony\Component\PropertyAccess\PropertyAccessor */
19
    private $accessor;
20
21
    /** @var bool */
22
    private $isErrorEnabled;
23
24
    /**
25
     * Create reader instance
26
     *
27
     * @param bool $isErrorEnabled
28
     * @return FeedReader
29
     */
30
    public static function create($isErrorEnabled = true)
31
    {
32
        return new self($isErrorEnabled);
33
    }
34
35
    /**
36
     * Constructor
37
     */
38
    private function __construct($isErrorEnabled)
39
    {
40
        $this->accessor = PropertyAccess::createPropertyAccessor();
41
        $this->isErrorEnabled = $isErrorEnabled;
42
    }
43
44
    /**
45
     * Define if errors are enable on parsing feed data
46
     *
47
     * @param bool $enable
48
     * @return FeedReader
49
     */
50
    public function enableErrorOnParsing($enable)
51
    {
52
        $this->isErrorEnabled = $enable;
53
54
        return $this;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function readFromJson($json)
61
    {
62
        $content = json_decode($json, true);
63
        if (!is_array($content)) {
64
            throw InvalidFeedException::invalidJsonException();
65
        }
66
67
        return $this->readFeedNode($content);
68
    }
69
70
    /**
71
     * Browse feed node
72
     *
73
     * @param array $content
74
     * @return Feed
75
     */
76
    private function readFeedNode(array $content)
77
    {
78
        $feed = new Feed('');
79
80
        foreach ($content as $key => $value) {
81
            if ('version' === $key) {
82
                continue;
83
            }
84
85
            switch ($key) {
86
                case 'author':
87
                    $feed->setAuthor($this->readAuthorNode($value));
88
                    break;
89
90
                case 'hubs':
91
                    $feed->setHubs(array_map([$this, 'readHubNode'], $value));
92
                    break;
93
94
                case 'items':
95
                    $feed->setItems(array_map([$this, 'readItemNode'], $value));
96
                    break;
97
98
                default:
99
                    try {
100
                        $this->accessor->setValue($feed, $key, $value);
101
                    } catch (NoSuchPropertyException $e) {
102
                        if ($this->isErrorEnabled) {
103
                            throw InvalidFeedException::invalidFeedProperty($key);
104
                        }
105
                    }
106
            }
107
        }
108
109
        return $feed;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $feed; of type object|array is incompatible with the return type documented by JDecool\JsonFeed\Reader\...eedReader::readFeedNode of type JDecool\JsonFeed\Feed as it can also be of type array which is not included in this return type.
Loading history...
110
    }
111
112
    /**
113
     * Browse item node
114
     *
115
     * @param array $content
116
     * @return Item
117
     */
118
    private function readItemNode(array $content)
119
    {
120
        $id = isset($content['id']) ? $content['id'] : '';
121
122
        $item = new Item($id);
123
        foreach ($content as $key => $value) {
124
            if ('id' === $key) {
125
                continue;
126
            }
127
128
            switch ($key) {
129
                case 'attachments':
130
                    $item->setAttachments(array_map([$this, 'readAttachmentNode'], $value));
131
                    break;
132
133
                case 'author':
134
                    $item->setAuthor($this->readAuthorNode($value));
135
                    break;
136
137
                case 'date_published':
138
                case 'date_modified':
139
                    $this->accessor->setValue($item, $key, new DateTime($value));
140
                    break;
141
142
                default:
143
                    try {
144
                        if ('_' === $key[0]) {
145
                            $item->addExtension(substr($key, 1), $value);
146
                        } else {
147
                            $this->accessor->setValue($item, $key, $value);
148
                        }
149
                    } catch (NoSuchPropertyException $e) {
150
                        if ($this->isErrorEnabled) {
151
                            throw InvalidFeedException::invalidItemProperty($key);
152
                        }
153
                    }
154
                    break;
155
            }
156
        }
157
158
        return $item;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $item; of type object|array is incompatible with the return type documented by JDecool\JsonFeed\Reader\...eedReader::readItemNode of type JDecool\JsonFeed\Item as it can also be of type array which is not included in this return type.
Loading history...
159
    }
160
161
    /**
162
     * Browse author node
163
     *
164
     * @param array $content
165
     * @return Author
166
     */
167
    private function readAuthorNode(array $content)
168
    {
169
        $name = (isset($content['name'])) ? $content['name'] : '';
170
171
        $author = new Author($name);
172
        foreach ($content as $key => $value) {
173
            if ('name' === $key) {
174
                continue;
175
            }
176
177
            try {
178
                $this->accessor->setValue($author, $key, $value);
179
            } catch (NoSuchPropertyException $e) {
180
                if ($this->isErrorEnabled) {
181
                    throw InvalidFeedException::invalidAuthorProperty($key);
182
                }
183
            }
184
        }
185
186
        return $author;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $author; of type object|array is incompatible with the return type documented by JDecool\JsonFeed\Reader\...dReader::readAuthorNode of type JDecool\JsonFeed\Author as it can also be of type array which is not included in this return type.
Loading history...
187
    }
188
189
    /**
190
     * Browse hub node
191
     *
192
     * @param array $content
193
     * @return Hub
194
     */
195
    private function readHubNode(array $content)
196
    {
197
        $type = isset($content['type']) ? $content['type'] : '';
198
        $url = isset($content['url']) ? $content['url'] : '';
199
200
        return new Hub($type, $url);
201
    }
202
203
    /**
204
     * Browse attachment node
205
     *
206
     * @param array $content
207
     * @return Attachment
208
     */
209
    private function readAttachmentNode(array $content)
210
    {
211
        $url = isset($content['url']) ? $content['url'] : '';
212
        $mimeType = isset($content['mime_type']) ? $content['mime_type'] : '';
213
214
        $attachment = new Attachment($url, $mimeType);
215
        foreach ($content as $key => $value) {
216
            switch ($key) {
217
                case 'size_in_bytes':
218
                    $attachment->setSize($value);
219
                    break;
220
221
                case 'duration_in_seconds':
222
                    $attachment->setDuration($value);
223
                    break;
224
            }
225
        }
226
227
        return $attachment;
228
    }
229
}
230