Completed
Push — master ( 30f4d3...51e609 )
by Jérémy
02:05
created

FeedReader::readItemNode()   D

Complexity

Conditions 10
Paths 18

Size

Total Lines 37
Code Lines 24

Duplication

Lines 8
Ratio 21.62 %

Importance

Changes 0
Metric Value
dl 8
loc 37
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 24
nc 18
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 View Code Duplication
                default:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
                default:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
                    try {
144
                        $this->accessor->setValue($item, $key, $value);
145
                    } catch (NoSuchPropertyException $e) {
146
                        if ($this->isErrorEnabled) {
147
                            throw InvalidFeedException::invalidItemProperty($key);
148
                        }
149
                    }
150
            }
151
        }
152
153
        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...
154
    }
155
156
    /**
157
     * Browse author node
158
     *
159
     * @param array $content
160
     * @return Author
161
     */
162
    private function readAuthorNode(array $content)
163
    {
164
        $name = (isset($content['name'])) ? $content['name'] : '';
165
166
        $author = new Author($name);
167
        foreach ($content as $key => $value) {
168
            if ('name' === $key) {
169
                continue;
170
            }
171
172
            try {
173
                $this->accessor->setValue($author, $key, $value);
174
            } catch (NoSuchPropertyException $e) {
175
                if ($this->isErrorEnabled) {
176
                    throw InvalidFeedException::invalidAuthorProperty($key);
177
                }
178
            }
179
        }
180
181
        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...
182
    }
183
184
    /**
185
     * Browse hub node
186
     *
187
     * @param array $content
188
     * @return Hub
189
     */
190
    private function readHubNode(array $content)
191
    {
192
        $type = isset($content['type']) ? $content['type'] : '';
193
        $url = isset($content['url']) ? $content['url'] : '';
194
195
        return new Hub($type, $url);
196
    }
197
198
    /**
199
     * Browse attachment node
200
     *
201
     * @param array $content
202
     * @return Attachment
203
     */
204
    private function readAttachmentNode(array $content)
205
    {
206
        $url = isset($content['url']) ? $content['url'] : '';
207
        $mimeType = isset($content['mime_type']) ? $content['mime_type'] : '';
208
209
        $attachment = new Attachment($url, $mimeType);
210
        foreach ($content as $key => $value) {
211
            switch ($key) {
212
                case 'size_in_bytes':
213
                    $attachment->setSize($value);
214
                    break;
215
216
                case 'duration_in_seconds':
217
                    $attachment->setDuration($value);
218
                    break;
219
            }
220
        }
221
222
        return $attachment;
223
    }
224
}
225