Passed
Pull Request — master (#21)
by kenny
04:31
created

FormatMapping::photoRatio()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 1
dl 0
loc 14
rs 9.2222
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
                $title = $this->filterString($this->getValue('title', $dataArticle)),
66
67
                $body = $this->filterString($this->getValue('body', $dataArticle)),
68
69
                $source = $this->filterString($this->getValue('source', $dataArticle)),
70
71
                $uniqueId = $this->getValue('unique_id', $dataArticle),
72
73
                $typeId = $this->filterInteger($this->getValue('type_id', $dataArticle['type'])),
74
75
                $categoryId = $this->filterInteger($this->getValue(
76
                    'category_id',
77
                    $dataArticle['category']
78
                )),
79
80
                $reporter = $this->getValue('reporter', $dataArticle),
81
82
                $lead = $this->filterString($this->getValue('lead', $dataArticle)),
83
84
                $tags = $this->getValue('tag_name', $dataArticle['tags']),
85
86
                $publishedAt = $this->filterString($this->getValue('published_at', $dataArticle)),
87
88
                $identifier = $this->filterInteger($this->getValue('id', $dataArticle))
89
90
            );
91
92
            $attachmentConstants = array(
93
                Article::ATTACHMENT_FIELD_PHOTO, Article::ATTACHMENT_FIELD_PAGE,
94
                Article::ATTACHMENT_FIELD_GALLERY, Article::ATTACHMENT_FIELD_VIDEO,
95
            );
96
97
            $attachmentTypes = array(
98
                self::JSON_PHOTO_FIELD, self::JSON_PAGE_FIELD, self::JSON_GALLERY_FIELD,
99
                self::JSON_VIDEO_FIELD,
100
            );
101
102
            $attachmentAttributes = $this->lookUp($attachmentConstants);
103
104
            $this->generalAttachment($article, $attachmentConstants, $attachmentTypes, $attachmentAttributes, $dataArticle);
105
106
            return $article;
107
        }
108
109
        throw new \Exception("Empty or invalid JSON Response", 1);
110
    }
111
112
    /**
113
     * Create list attributes based on Article attachment type
114
     * @param  array $articleConstant
115
     * @return array
116
     */
117
    private function lookUp($articleConstant)
118
    {
119
        $num = count($articleConstant);
120
121
        $lists = array();
122
123
        for ($i = 0; $i < $num; $i++) {
124
            $res = $this->listAttributes[$articleConstant[$i]];
125
126
            $jumlah = count($res);
127
128
            for ($j = 0; $j < $jumlah; $j++) {
129
                $res[$j] = $articleConstant[$i] . $res[$j];
130
            }
131
132
            array_push($lists, $res);
133
        }
134
135
        return $lists;
136
    }
137
138
    /**
139
     * Attach attachments to article
140
     * @param  Article &$article
141
     * @param  array $attachmentConst
142
     * @param  array $attachmentype
143
     * @param  array $attributes
144
     * @param  array $dataArticle
145
     * @return void
146
     */
147
    private function generalAttachment(
148
        &$article,
149
        $attachmentConst,
150
        $attachmentype,
151
        $attributes,
152
        $dataArticle
153
    ) {
154
        $numOfAttachments = count($attachmentConst);
155
156
        for ($i = 0; $i < $numOfAttachments; $i++) {
157
            $attachments = $this->attachment($attachmentype[$i], $attributes[$i], $dataArticle);
158
159
            for ($j = 0; $j < $attachments['numberOfItems']; $j++) {
160
                $attachment = $attachments['attachments'][$j];
161
162
                $article->attach($attachmentConst[$i], $attachment);
163
            }
164
        }
165
    }
166
167
    /**
168
     * Attachment(s) of a single article
169
     * @param  string $attachmentType
170
     * @param  array $attributes
171
     * @param  assoc array $dataArticle
172
     * @return array attachments
173
     */
174
    private function attachment($attachmentType, $attributes, $dataArticle)
175
    {
176
        $data = $dataArticle[$attachmentType];
177
178
        $encoded = json_encode($data);
179
180
        $attachments = array();
181
182
        if ($this->filterArray($data)) {
183
            $decodedData = json_decode($encoded, true);
184
185
            $numberOfItems = count($decodedData);
186
187
            for ($i = 0; $i < $numberOfItems; $i++) {
188
                $item = $decodedData[$i];
189
190
                $attachment = $this->makeAttachmentObject($attachmentType, $attributes, $item);
191
192
                array_push($attachments, $attachment);
193
            }
194
        }
195
196
        $structure = array(
197
            'numberOfItems' => count($attachments),
198
            'attachments' => $attachments,
199
        );
200
201
        return $structure;
202
    }
203
204
    /**
205
     * Make attachment object
206
     * @param  string $attachmentType json field of attachment
207
     * @param  array  $attributes     attributes of attachment
208
     * @param  assoc array $item
209
     * @return object
210
     */
211
    private function makeAttachmentObject($attachmentType, $attributes, $item)
212
    {
213
        $numOfAttributes = count($attributes);
214
215
        $values = array();
216
217
        $object = null;
218
219
        for ($i = 0; $i < $numOfAttributes; $i++) {
220
            $val = $this->getValue($attributes[$i], $item);
221
            $values[$attributes[$i]] = $val;
222
        }
223
224
        extract($values);
225
226
        if ($attachmentType == 'photos') {
227
            $object = $this->createPhoto($photo_url, $photo_ratio, '', '');
228
        } elseif ($attachmentType == 'pages') {
229
            $object = $this->createPage($page_title, $page_body, $page_source, $page_order, $page_cover, $page_lead);
230
        } elseif ($attachmentType == 'galleries') {
231
            $object = $this->createGallery($gallery_body, $gallery_order, $gallery_photo, $gallery_source, $gallery_lead);
232
        } elseif ($attachmentType == 'videos') {
233
            $object = $this->createVideo($video_body, $video_source, $video_order, $video_cover, $video_lead);
234
        }
235
236
        return $this->filterAttachmentObject($object);
237
    }
238
239
    /**
240
     * Create photo object
241
     * @param  array $values
242
     * @return Photo
243
     */
244
    private function createPhoto($url, $ratio, $desc, $info)
245
    {
246
        return new Photo(
247
            $url,
248
            $this->photoRatio($ratio),
249
            $desc,
250
            $info
251
        );
252
    }
253
254
    /**
255
     * Create page object
256
     * @param  array $values
257
     * @return Page
258
     */
259
    private function createPage($title, $body, $source, $order, $cover, $lead)
260
    {
261
        return new Page(
262
            $title,
263
            $body,
264
            $source,
265
            $order,
266
            $cover,
267
            $lead
268
        );
269
    }
270
271
    /**
272
     * Create Gallery object
273
     * @param  array $values
274
     * @return Gallery
275
     */
276
    private function createGallery($body, $order, $photo, $source, $lead)
277
    {
278
        return new Gallery(
279
            $body,
280
            $order,
281
            $photo,
282
            $source,
283
            $lead
284
        );
285
    }
286
287
    /**
288
     * Create Video object
289
     * @param  array $values
290
     * @return Video
291
     */
292
    private function createVideo($body, $source, $order, $cover, $lead)
293
    {
294
        return new Video(
295
296
            $body,
297
            $source,
298
            $order,
299
            $cover,
300
            $lead
301
        );
302
    }
303
304
    /**
305
     * Map ratio to photo ratio constants
306
     * @param   string $ratio
307
     * @return   string
308
     * @throws Exception
309
     */
310
    private function photoRatio($ratio)
311
    {
312
        if ($ratio == "1:1") {
313
            return Photo::RATIO_SQUARE;
314
        } elseif ($ratio == "2:1") {
315
            return Photo::RATIO_RECTANGLE;
316
        } elseif ($ratio == "3:2") {
317
            return Photo::RATIO_HEADLINE;
318
        } elseif ($ratio == "9:16") {
319
            return Photo::RATIO_VERTICAL;
320
        } elseif ($ratio == 'cover') {
321
            return Photo::RATIO_COVER;
322
        } else {
323
            throw new \Exception("Unknown ratio", 1);
324
        }
325
    }
326
327
    /**
328
     * Make sure value is integer
329
     * @param  mixed $int
330
     * @return int
331
     * @throws Exception
332
     */
333
    private function filterInteger($int)
334
    {
335
        if (is_int($int)) {
336
            return $int;
337
        }
338
        throw new \Exception("Invalid Integer", 1);
339
    }
340
341
    /**
342
     * Make sure string is not null or empty
343
     * @param   mixed $str
344
     * @return string if it is valid or exception
345
     * @throws Exception
346
     */
347
    private function filterString($str)
348
    {
349
        if (is_string($str) && strlen($str) > 0 && !is_null($str)) {
350
            return $str;
351
        }
352
        throw new \Exception("String required", 1);
353
    }
354
355
    /**
356
     * Make sure variable is type of array
357
     * @param  mixed $array
358
     * @return array
359
     * @throws Exception
360
     */
361
    private function filterArray($array)
362
    {
363
        if (is_array($array)) {
364
            return $array;
365
        }
366
        throw new \Exception("Array required", 1);
367
    }
368
369
    /**
370
     * Make sure attachment object not null
371
     * @param  mixed $object
372
     * @return object
373
     * @throws Exception
374
     */
375
    private function filterAttachmentObject($object)
376
    {
377
        if (!is_null($object)) {
378
            return $object;
379
        }
380
        throw new \Exception("Attachment object required", 1);
381
    }
382
383
    /**
384
     * Get value of array based on attributes(keys)
385
     * @param  mixed $attribute
386
     * @param  array $data
387
     * @return mixed
388
     */
389
    private function getValue($attribute, $data)
390
    {
391
        return isset($data[$attribute]) ? $data[$attribute] : null;
392
    }
393
}
394