Passed
Push — master ( 378b5c...dacda1 )
by Charis
08:41 queued 05:37
created

FormatMapping::lookUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace one;
4
5
use One\Model\Article;
6
use one\Model\Gallery;
7
use One\Model\Page;
8
use one\Model\Photo;
9
use One\Model\Video;
10
11
class FormatMapping
12
{
13
14
    /**
15
     * Possible attributes of JSON data
16
     * @var array
17
     */
18
    private $listAttributes;
19
20
    /**
21
     * JSON field constants
22
     */
23
    const JSON_PHOTO_FIELD = "photos";
24
25
    const JSON_PAGE_FIELD = "pages";
26
27
    const JSON_GALLERY_FIELD = "galleries";
28
29
    const JSON_VIDEO_FIELD = "videos";
30
31
    /**
32
     * Construct JSON attributes
33
     */
34
    public function __construct()
35
    {
36
        $this->listAttributes = array(
37
            Article::ATTACHMENT_FIELD_PHOTO   => array(
38
                '_id', '_url', '_ratio', '_description', '_information',
39
            ),
40
            Article::ATTACHMENT_FIELD_PAGE    => array(
41
                '_id', '_title', '_lead', '_body', '_source', '_order', '_cover',
42
            ),
43
            Article::ATTACHMENT_FIELD_GALLERY => array(
44
                '_id', '_lead', '_body', '_source', '_order', '_photo',
45
            ),
46
            Article::ATTACHMENT_FIELD_VIDEO   => array(
47
                '_id', '_lead', '_body', '_source', '_order', '_cover',
48
            ),
49
        );
50
    }
51
52
    /**
53
     * map a single article to main attributes in Article Class
54
     * @param  string $singleJsonArticle JSON response
55
     * @return Article
56
     * @throws Exception
57
     */
58
    public function article($singleJsonArticle)
59
    {
60
        if (json_decode($singleJsonArticle, true)) {
61
            $dataArticle = json_decode($singleJsonArticle, true)['data'];
62
63
            $article = new Article(
64
65
                $this->filterString(
66
                    $this->getValue('title', $dataArticle)
67
                ),
68
69
                $this->filterString(
70
                    $this->getValue('body', $dataArticle)
71
                ),
72
73
                $this->filterString(
74
                    $this->getValue('source', $dataArticle)
75
                ),
76
77
                $this->getValue('unique_id', $dataArticle),
78
79
                $this->filterInteger(
80
                    $this->getValue(
81
                        'type_id',
82
                        $dataArticle['type']
83
                    )
84
                ),
85
86
                $this->filterInteger(
87
                    $this->getValue(
88
                        'category_id',
89
                        $dataArticle['category']
90
                    )
91
                ),
92
93
                $this->getValue('reporter', $dataArticle),
94
95
                $this->filterString(
96
                    $this->getValue('lead', $dataArticle)
97
                ),
98
99
                $this->getValue('tag_name', $dataArticle['tags']),
100
101
                $this->filterString(
102
                    $this->getValue('published_at', $dataArticle)
103
                ),
104
105
                $this->filterInteger(
106
                    $this->getValue('id', $dataArticle)
107
                )
108
109
            );
110
111
            $attachmentConstants = array(
112
                Article::ATTACHMENT_FIELD_PHOTO,
113
                Article::ATTACHMENT_FIELD_PAGE,
114
                Article::ATTACHMENT_FIELD_GALLERY,
115
                Article::ATTACHMENT_FIELD_VIDEO,
116
            );
117
118
            $attachmentTypes = array(
119
                self::JSON_PHOTO_FIELD, self::JSON_PAGE_FIELD,
120
                self::JSON_GALLERY_FIELD, self::JSON_VIDEO_FIELD,
121
            );
122
123
            $attachmentAttributes = $this->lookUp($attachmentConstants);
124
125
            $article = $this->generalAttachment(
126
                $article,
127
                $attachmentConstants,
128
                $attachmentTypes,
129
                $attachmentAttributes,
130
                $dataArticle
131
            );
132
133
            return $article;
134
        }
135
136
        throw new \Exception("Empty or invalid JSON Response", 1);
137
    }
138
139
    /**
140
     * Create list attributes based on Article attachment type
141
     * @param  array $articleConstant
142
     * @return array
143
     */
144
    private function lookUp($articleConstant)
145
    {
146
        $copyListAttributes = $this->listAttributes;
147
148
        $lists = array_map(function ($singleConst) use ($copyListAttributes) {
149
            $res = $copyListAttributes[$singleConst];
150
            return array_map(function ($str) use ($singleConst) {
151
                return $singleConst . $str;
152
            }, $res);
153
        }, $articleConstant);
154
155
        return $lists;
156
    }
157
158
    /**
159
     * Attach attachments to article
160
     * @param  Article $article
161
     * @param  array $attachmentConst
162
     * @param  array $attachmentype
163
     * @param  array $attributes
164
     * @param  array $dataArticle
165
     * @return Article
166
     */
167
    private function generalAttachment(
168
        $article,
169
        $attachmentConst,
170
        $attachmentype,
171
        $attributes,
172
        $dataArticle
173
    ) {
174
        $numOfAttachments = count($attachmentConst);
175
176
        for ($i = 0; $i < $numOfAttachments; $i++) {
177
            $attachments = $this->attachment($attachmentype[$i], $attributes[$i], $dataArticle);
178
179
            for ($j = 0; $j < $attachments['numberOfItems']; $j++) {
180
                $attachment = $attachments['attachments'][$j];
181
182
                $article->attach($attachmentConst[$i], $attachment);
183
            }
184
        }
185
186
        return $article;
187
    }
188
189
    /**
190
     * Attachment(s) of a single article
191
     * @param  string $attachmentType
192
     * @param  array $attributes
193
     * @param  assoc array $dataArticle
194
     * @return array attachments
195
     */
196
    private function attachment($attachmentType, $attributes, $dataArticle)
197
    {
198
        $data = $dataArticle[$attachmentType];
199
200
        $encoded = json_encode($data);
201
202
        $attachments = array();
203
204
        if ($this->filterArray($data)) {
205
            $decodedData = json_decode($encoded, true);
206
207
            $numberOfItems = count($decodedData);
208
209
            for ($i = 0; $i < $numberOfItems; $i++) {
210
                $item = $decodedData[$i];
211
212
                $attachment = $this->filterAttachmentObject(
213
                    $this->makeAttachmentObject(
214
                        $attachmentType,
215
                        $attributes,
216
                        $item
217
                    )
218
                );
219
220
                array_push($attachments, $attachment);
221
            }
222
        }
223
224
        $structure = array(
225
            'numberOfItems' => count($attachments),
226
            'attachments'   => $attachments,
227
        );
228
229
        return $structure;
230
    }
231
232
    /**
233
     * Make attachment object
234
     * @param  string $attachmentType json field of attachment
235
     * @param  array  $attributes     attributes of attachment
236
     * @param  assoc array $item
237
     * @return object
238
     */
239
    private function makeAttachmentObject($attachmentType, $attrReferences, $item)
240
    {
241
        $attrValues = array();
242
243
        foreach ($attrReferences as $attrReference) {
244
            $attrValues[$attrReference] = $this->getValue($attrReference, $item);
245
        }
246
247
        switch ($attachmentType) {
248
            case self::JSON_PHOTO_FIELD:
249
                return $this->createPhoto(
250
                    $attrValues['photo_url'],
251
                    $attrValues['photo_ratio'],
252
                    '',
253
                    ''
254
                );
255
            case self::JSON_PAGE_FIELD:
256
                return $this->createPage(
257
                    $attrValues['page_title'],
258
                    $attrValues['page_body'],
259
                    $attrValues['page_source'],
260
                    $attrValues['page_order'],
261
                    $attrValues['page_cover'],
262
                    $attrValues['page_lead']
263
                );
264
            case self::JSON_GALLERY_FIELD:
265
                return $this->createGallery(
266
                    $attrValues['gallery_body'],
267
                    $attrValues['gallery_order'],
268
                    $attrValues['gallery_photo'],
269
                    $attrValues['gallery_source'],
270
                    $attrValues['gallery_lead']
271
                );
272
            case self::JSON_VIDEO_FIELD:
273
                return $this->createVideo(
274
                    $attrValues['video_body'],
275
                    $attrValues['video_source'],
276
                    $attrValues['video_order'],
277
                    $attrValues['video_cover'],
278
                    $attrValues['video_lead']
279
                );
280
            default:
281
                return null;
282
        }
283
    }
284
285
    /**
286
     * Create photo object
287
     * @param  array $values
288
     * @return Photo
289
     */
290
    private function createPhoto($url, $ratio, $desc, $info)
291
    {
292
        return new Photo(
293
            $url,
294
            $ratio,
295
            $this->handleString($desc),
296
            $this->handleString($info)
297
        );
298
    }
299
300
    /**
301
     * Create page object
302
     * @param  array $values
303
     * @return Page
304
     */
305
    private function createPage($title, $body, $source, $order, $cover, $lead)
306
    {
307
        return new Page(
308
            $title,
309
            $body,
310
            $source,
311
            $order,
312
            $cover,
313
            $lead
314
        );
315
    }
316
317
    /**
318
     * Create Gallery object
319
     * @param  array $values
320
     * @return Gallery
321
     */
322
    private function createGallery($body, $order, $photo, $source, $lead)
323
    {
324
        return new Gallery(
325
            $body,
326
            $order,
327
            $photo,
328
            $source,
329
            $lead
330
        );
331
    }
332
333
    /**
334
     * Create Video object
335
     * @param  array $values
336
     * @return Video
337
     */
338
    private function createVideo($body, $source, $order, $cover, $lead)
339
    {
340
        return new Video(
341
342
            $body,
343
            $source,
344
            $order,
345
            $cover,
346
            $lead
347
        );
348
    }
349
350
    /**
351
     * Make sure value is integer
352
     * @param  mixed $int
353
     * @return int
354
     * @throws Exception
355
     */
356
    private function filterInteger($int)
357
    {
358
        if (is_int($int)) {
359
            return $int;
360
        }
361
        throw new \Exception("Invalid Integer", 1);
362
    }
363
364
    /**
365
     * Make sure string is not null or empty
366
     * @param   mixed $str
367
     * @return string if it is valid or exception
368
     * @throws Exception
369
     */
370
    private function filterString($str)
371
    {
372
        if (is_string($str) && strlen($str) > 0 && !is_null($str)) {
373
            return $str;
374
        }
375
        throw new \Exception("String required", 1);
376
    }
377
378
    /**
379
     * Handle string when it will throw exception
380
     * @param  mixed $str
381
     * @return string
382
     */
383
    private function handleString($str)
384
    {
385
        return (is_string($str) &&
386
            strlen($str) > 0
387
            && !is_null($str)) ? $str : "";
388
    }
389
390
    /**
391
     * Make sure variable is type of array
392
     * @param  mixed $array
393
     * @return array
394
     * @throws Exception
395
     */
396
    private function filterArray($array)
397
    {
398
        if (is_array($array)) {
399
            return $array;
400
        }
401
        throw new \Exception("Array required", 1);
402
    }
403
404
    /**
405
     * Make sure attachment object not null
406
     * @param  mixed $object
407
     * @return object
408
     * @throws Exception
409
     */
410
    private function filterAttachmentObject($object)
411
    {
412
        if (!is_null($object)) {
413
            return $object;
414
        }
415
        throw new \Exception("Attachment object required", 1);
416
    }
417
418
    /**
419
     * Get value of array based on attributes(keys)
420
     * @param  mixed $attribute
421
     * @param  array $data
422
     * @return mixed
423
     */
424
    private function getValue($attribute, $data)
425
    {
426
        return isset($data[$attribute]) ? $data[$attribute] : null;
427
    }
428
}
429