Passed
Push — master ( 71368b...ee9f04 )
by axel
02:15
created

InfoModel::getVideo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace MalScraper\Model\General;
4
5
use MalScraper\Helper\Helper;
6
use MalScraper\Model\MainModel;
7
8
/**
9
 * InfoModel class.
10
 */
11
class InfoModel extends MainModel
12
{
13
    /**
14
     * Type of info. Either anime or manga.
15
     *
16
     * @var string
17
     */
18
    private $_type;
19
20
    /**
21
     * Id of the anime or manga.
22
     *
23
     * @var string|int
24
     */
25
    private $_id;
26
27
    /**
28
     * Default constructor.
29
     *
30
     * @param string     $type
31
     * @param string|int $id
32
     * @param string     $parserArea
33
     *
34
     * @return void
35
     */
36
    public function __construct($type, $id, $parserArea = '#content')
37
    {
38
        $this->_type = $type;
39
        $this->_id = $id;
40
        $this->_url = $this->_myAnimeListUrl.'/'.$type.'/'.$id;
41
        $this->_parserArea = $parserArea;
42
43
        parent::errorCheck($this);
44
    }
45
46
    /**
47
     * Default call.
48
     *
49
     * @param string $method
50
     * @param array  $arguments
51
     *
52
     * @return array|string|int
53
     */
54
    public function __call($method, $arguments)
55
    {
56
        if ($this->_error) {
57
            return $this->_error;
58
        }
59
60
        return call_user_func_array([$this, $method], $arguments);
61
    }
62
63
    /**
64
     * Get anime/manga id.
65
     *
66
     * @return string
67
     */
68
    private function getId()
69
    {
70
        return $this->_id;
71
    }
72
73
    /**
74
     * Get anime/manga cover.
75
     *
76
     * @return string|bool
77
     */
78
    private function getCover()
79
    {
80
        $anime_cover = $this->_parser->find('img.ac', 0);
81
82
        return $anime_cover ? $anime_cover->src : '';
83
    }
84
85
    /**
86
     * Get anime/manga title.
87
     *
88
     * @return string|bool
89
     */
90
    private function getTitle()
91
    {
92
        $anime_cover = $this->_parser->find('img.ac', 0);
93
94
        return $anime_cover ? $anime_cover->alt : '';
95
    }
96
97
    /**
98
     * Get anime/manga alternative title.
99
     *
100
     * @return array
101
     */
102
    private function getTitle2()
103
    {
104
        $title2 = [];
105
106
        $anime_info = $this->_parser->find('.js-scrollfix-bottom', 0);
107
108
        preg_match('/(English:<\/span>)([^<]*)/', $anime_info->innertext, $english);
109
        $title2['english'] = trim($english ? $english[2] : '');
110
111
        preg_match('/(Synonyms:<\/span>)([^<]*)/', $anime_info->innertext, $synonym);
112
        $title2['synonym'] = trim($synonym ? $synonym[2] : '');
113
114
        preg_match('/(Japanese:<\/span>)([^<]*)/', $anime_info->innertext, $japanese);
115
        $title2['japanese'] = trim($japanese ? $japanese[2] : '');
116
117
        return $title2;
118
    }
119
120
    /**
121
     * Get anime/manga promotional video.
122
     *
123
     * @return string
124
     */
125
    private function getVideo()
126
    {
127
        $video_area = $this->_parser->find('.video-promotion', 0);
128
        if ($video_area) {
129
            $video = $video_area->find('a', 0)->href;
130
131
            return Helper::videoUrlCleaner($video);
132
        }
133
134
        return '';
135
    }
136
137
    /**
138
     * Get anime/manga synopsis.
139
     *
140
     * @return string
141
     */
142
    private function getSynopsis()
143
    {
144
        $synopsis = $this->_parser->find('span[itemprop=description]', 0);
145
        if ($synopsis) {
146
            $synopsis = $synopsis->plaintext;
147
148
            return trim(preg_replace('/\n[^\S\n]*/', "\n", $synopsis));
149
        } else {
150
            return;
151
        }
152
    }
153
154
    /**
155
     * Get anime/manga score.
156
     *
157
     * @return string
158
     */
159
    private function getScore()
160
    {
161
        $score = $this->_parser->find('div[class="fl-l score"]', 0)->plaintext;
162
        $score = trim($score);
163
164
        return $score != 'N/A' ? $score : null;
165
    }
166
167
    /**
168
     * Get number of user who give score.
169
     *
170
     * @return string
171
     */
172
    private function getVoter()
173
    {
174
        $voter = $this->_parser->find('div[class="fl-l score"]', 0)->getAttribute('data-user');
175
176
        return trim(str_replace(['users', 'user', ','], '', $voter));
177
    }
178
179
    /**
180
     * Get anime/manga rank.
181
     *
182
     * @return string
183
     */
184
    private function getRank()
185
    {
186
        $rank = $this->_parser->find('span[class="numbers ranked"] strong', 0)->plaintext;
187
        $rank = $rank != 'N/A' ? $rank : '';
188
189
        return str_replace('#', '', $rank);
190
    }
191
192
    /**
193
     * Get anime/manga popularity.
194
     *
195
     * @return string
196
     */
197
    private function getPopularity()
198
    {
199
        $popularity = $this->_parser->find('span[class="numbers popularity"] strong', 0)->plaintext;
200
201
        return str_replace('#', '', $popularity);
202
    }
203
204
    /**
205
     * Get number of user who watch/read the anime/manga.
206
     *
207
     * @return string
208
     */
209
    private function getMembers()
210
    {
211
        $member = $this->_parser->find('span[class="numbers members"] strong', 0)->plaintext;
212
213
        return str_replace(',', '', $member);
214
    }
215
216
    /**
217
     * Get number of user who favorite the anime/manga.
218
     *
219
     * @return string
220
     */
221
    private function getFavorite()
222
    {
223
        $favorite = $this->_parser->find('div[data-id=info2]', 0)->next_sibling()->next_sibling()->next_sibling();
224
        $favorite_title = $favorite->find('span', 0)->plaintext;
225
        $favorite = $favorite->plaintext;
226
        $favorite = trim(str_replace($favorite_title, '', $favorite));
227
        $favorite = str_replace(',', '', $favorite);
228
229
        return preg_replace("/([\s])+/", ' ', $favorite);
230
    }
231
232
    /**
233
     * Get anime/manga detail info.
234
     *
235
     * @return array
236
     */
237
    private function getOtherInfo()
238
    {
239
        $info = [];
240
241
        $anime_info = $this->_parser->find('.js-scrollfix-bottom', 0);
242
        $other_info = (count($anime_info->find('h2')) > 2) ? $anime_info->find('h2', 1) : $anime_info->find('h2', 0);
0 ignored issues
show
Bug introduced by
It seems like $anime_info->find('h2') can also be of type simplehtmldom_1_5\simple_html_dom_node; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

242
        $other_info = (count(/** @scrutinizer ignore-type */ $anime_info->find('h2')) > 2) ? $anime_info->find('h2', 1) : $anime_info->find('h2', 0);
Loading history...
243
        $next_info = $other_info->next_sibling();
0 ignored issues
show
Bug introduced by
The method next_sibling() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

243
        /** @scrutinizer ignore-call */ 
244
        $next_info = $other_info->next_sibling();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
244
        while (true) {
245
            $info_type = $next_info->find('span', 0)->plaintext;
246
247
            $clean_info_type = strtolower(str_replace(': ', '', $info_type));
248
            $clean_info_value = $this->getCleanInfo($info_type, $next_info);
249
            $clean_info_value = $this->getCleanerInfo1($clean_info_type, $clean_info_value);
250
            $clean_info_value = $this->getCleanerInfo2($next_info, $clean_info_type, $clean_info_value);
251
252
            $info[$clean_info_type] = $clean_info_value;
253
254
            $next_info = $next_info->next_sibling();
255
            if ($next_info->tag == 'h2' || $next_info->tag == 'br') {
256
                break;
257
            }
258
        }
259
260
        return $info;
261
    }
262
263
    /**
264
     * Get clean other info.
265
     *
266
     * @param string                             $info_type
267
     * @param \simplehtmldom_1_5\simple_html_dom $next_info
268
     *
269
     * @return string
270
     */
271
    private function getCleanInfo($info_type, $next_info)
272
    {
273
        $info_value = $next_info->plaintext;
274
        $clean_info_value = trim(str_replace($info_type, '', $info_value));
275
        $clean_info_value = preg_replace("/([\s])+/", ' ', $clean_info_value);
276
277
        return str_replace([', add some', '?', 'Not yet aired', 'Unknown'], '', $clean_info_value);
278
    }
279
280
    /**
281
     * Get cleaner other info.
282
     *
283
     * @param string $clean_info_type
284
     * @param string $clean_info_value
285
     *
286
     * @return string|array
287
     */
288
    private function getCleanerInfo1($clean_info_type, $clean_info_value)
289
    {
290
        if ($clean_info_type == 'published' || $clean_info_type == 'aired') {
291
            $start_air = $end_air = '';
292
            if ($clean_info_value != 'Not available') {
293
                $parsed_airing = explode(' to ', $clean_info_value);
294
                $start_air = ($parsed_airing[0] != '?') ? $parsed_airing[0] : '';
295
                if (count($parsed_airing) > 1) {
296
                    $end_air = ($parsed_airing[1] != '?') ? $parsed_airing[1] : '';
297
                }
298
            }
299
300
            $clean_info_value = [];
301
            $clean_info_value['start'] = $start_air;
302
            $clean_info_value['end'] = $end_air;
303
        }
304
305
        return $clean_info_value;
306
    }
307
308
    /**
309
     * Get cleaner other info.
310
     *
311
     * @param \simplehtmldom_1_5\simple_html_dom $next_info
312
     * @param string                             $clean_info_type
313
     * @param string|array                       $clean_info_value
314
     *
315
     * @return string|array
316
     */
317
    private function getCleanerInfo2($next_info, $clean_info_type, $clean_info_value)
318
    {
319
        if ($clean_info_type == 'producers'
320
            || $clean_info_type == 'licensors'
321
            || $clean_info_type == 'studios'
322
            || $clean_info_type == 'genres'
323
            || $clean_info_type == 'authors'
324
        ) {
325
            $info_temp = [];
326
            $info_temp_index = 0;
327
            if ($clean_info_value != 'None found') {
328
                foreach ($next_info->find('a') as $each_info) {
329
                    $temp_id = explode('/', $each_info->href);
330
                    $info_temp[$info_temp_index]['id'] = $clean_info_type == 'authors' ? $temp_id[2] : $temp_id[3];
331
                    $info_temp[$info_temp_index]['name'] = $each_info->plaintext;
332
                    $info_temp_index++;
333
                }
334
            }
335
336
            return $info_temp;
337
        }
338
339
        return $clean_info_value;
340
    }
341
342
    /**
343
     * Get anime/manga relation.
344
     *
345
     * @return array
346
     */
347
    private function getRelated()
348
    {
349
        $related = [];
350
        $related_area = $this->_parser->find('.anime_detail_related_anime', 0);
351
        if ($related_area) {
352
            foreach ($related_area->find('tr') as $rel) {
353
                $rel_type = $rel->find('td', 0)->plaintext;
354
                $rel_type = trim(strtolower(str_replace(':', '', $rel_type)));
355
356
                $each_rel = [];
357
                $each_rel_index = 0;
358
                $rel_anime = $rel->find('td', 1);
359
                foreach ($rel_anime->find('a') as $r) {
360
                    $each_rel[$each_rel_index] = $this->getRelatedDetail($r);
361
                    $each_rel_index++;
362
                }
363
364
                $related[$rel_type] = $each_rel;
365
            }
366
        }
367
368
        return $related;
369
    }
370
371
    /**
372
     * Get related detail.
373
     *
374
     * @param \simplehtmldom_1_5\simple_html_dom $r
375
     *
376
     * @return array
377
     */
378
    private function getRelatedDetail($r)
379
    {
380
        $related = [];
381
        $rel_anime_link = $r->href;
382
        $separated_anime_link = explode('/', $rel_anime_link);
383
384
        $related['id'] = $separated_anime_link[2];
385
        $related['title'] = $r->plaintext;
386
        $related['type'] = $separated_anime_link[1];
387
388
        return $related;
389
    }
390
391
    /**
392
     * Get anime/manga character and its va.
393
     *
394
     * @return array
395
     */
396
    private function getCharacter()
397
    {
398
        $character = [];
399
        $char_index = 0;
400
        $character_area = $this->_parser->find('div[class^=detail-characters-list]', 0);
401
        if ($character_area) {
402
            $character_list = [
403
                $character_area->find('div[class*=fl-l]', 0),
404
                $character_area->find('div[class*=fl-r]', 0),
405
            ];
406
            foreach ($character_list as $character_side) {
407
                if ($character_side) {
408
                    foreach ($character_side->find('table[width=100%]') as $each_char) {
409
                        $char = $each_char->find('tr td', 1);
410
                        $va = $each_char->find('table td', 0);
411
412
                        $character[$char_index]['id'] = $this->getStaffId($char);
413
                        $character[$char_index]['name'] = $this->getStaffName($char);
414
                        $character[$char_index]['role'] = $this->getStaffRole($char);
415
                        $character[$char_index]['image'] = $this->getStaffImage($each_char);
416
417
                        $character[$char_index]['va_id'] = $character[$char_index]['va_name'] = '';
418
                        $character[$char_index]['va_role'] = $character[$char_index]['va_image'] = '';
419
420
                        if ($va) {
421
                            $character[$char_index]['va_id'] = $this->getStaffId($va);
422
                            $character[$char_index]['va_name'] = $this->getStaffName($va, true);
423
                            $character[$char_index]['va_role'] = $this->getStaffRole($va);
424
                            $character[$char_index]['va_image'] = $this->getStaffImage($each_char, true);
425
                        }
426
427
                        $char_index++;
428
                    }
429
                }
430
            }
431
        }
432
433
        return $character;
434
    }
435
436
    /**
437
     * Get anime/manga staff involved.
438
     *
439
     * @return array
440
     */
441
    private function getStaff()
442
    {
443
        $staff = [];
444
        $staff_index = 0;
445
        $staff_area = $this->_parser->find('div[class^=detail-characters-list]', 1);
446
        if ($staff_area) {
447
            $staff_list = [
448
                $staff_area->find('div[class*=fl-l]', 0),
449
                $staff_area->find('div[class*=fl-r]', 0),
450
            ];
451
            foreach ($staff_list as $staff_side) {
452
                if ($staff_side) {
453
                    foreach ($staff_side->find('table[width=100%]') as $each_staff) {
454
                        $st = $each_staff->find('tr td', 1);
455
456
                        $staff[$staff_index]['id'] = $this->getStaffId($st);
457
                        $staff[$staff_index]['name'] = $this->getStaffName($st);
458
                        $staff[$staff_index]['role'] = $this->getStaffRole($st);
459
                        $staff[$staff_index]['image'] = $this->getStaffImage($each_staff);
460
461
                        $staff_index++;
462
                    }
463
                }
464
            }
465
        }
466
467
        return $staff;
468
    }
469
470
    /**
471
     * Get staff id.
472
     *
473
     * @param \simplehtmldom_1_5\simple_html_dom $st
474
     *
475
     * @return string
476
     */
477
    private function getStaffId($st)
478
    {
479
        $staff_id = $st->find('a', 0)->href;
480
        $staff_id = explode('/', $staff_id);
481
482
        return $staff_id[4];
483
    }
484
485
    /**
486
     * Get staff name.
487
     *
488
     * @param \simplehtmldom_1_5\simple_html_dom $st
489
     * @param bool                               $va (Optional)
490
     *
491
     * @return string
492
     */
493
    private function getStaffName($st, $va = false)
494
    {
495
        if ($va) {
496
            return $st->find('a', 0)->plaintext;
497
        }
498
499
        return trim(preg_replace('/\s+/', ' ', $st->find('a', 0)->plaintext));
500
    }
501
502
    /**
503
     * Get staff role.
504
     *
505
     * @param \simplehtmldom_1_5\simple_html_dom $st
506
     *
507
     * @return string
508
     */
509
    private function getStaffRole($st)
510
    {
511
        return trim($st->find('small', 0)->plaintext);
512
    }
513
514
    /**
515
     * Get staff image.
516
     *
517
     * @param \simplehtmldom_1_5\simple_html_dom $each_staff
518
     * @param bool                               $va         (Optional)
519
     *
520
     * @return string
521
     */
522
    private function getStaffImage($each_staff, $va = false)
523
    {
524
        if ($va) {
525
            $staff_image = $each_staff->find('table td', 1)->find('img', 0)->getAttribute('data-src');
526
        } else {
527
            $staff_image = $each_staff->find('tr td', 0)->find('img', 0)->getAttribute('data-src');
528
        }
529
530
        return Helper::imageUrlCleaner($staff_image);
531
    }
532
533
    /**
534
     * Get anime/manga opening and ending song.
535
     *
536
     * @return array
537
     */
538
    private function getSong()
539
    {
540
        $song = [];
541
        $song_area = $this->_parser->find('div[class*="theme-songs opnening"]', 0);
542
        if ($song_area) {
543
            foreach ($song_area->find('span.theme-song') as $each_song) {
544
                $each_song = trim(preg_replace('/#\d*:\s/', '', $each_song->plaintext));
545
                $song['opening'][] = $each_song;
546
            }
547
        }
548
549
        $song_area = $this->_parser->find('div[class*="theme-songs ending"]', 0);
550
        if ($song_area) {
551
            foreach ($song_area->find('span.theme-song') as $each_song) {
552
                $each_song = trim(preg_replace('/#\d*:\s/', '', $each_song->plaintext));
553
                $song['closing'][] = $each_song;
554
            }
555
        }
556
557
        return $song;
558
    }
559
560
    /**
561
     * Get anime/manga all information.
562
     *
563
     * @return array
564
     */
565
    private function getAllInfo()
566
    {
567
        $data = [
568
            'id'        => $this->getId(),
569
            'cover'     => $this->getCover(),
570
            'title'     => $this->getTitle(),
571
            'title2'    => $this->getTitle2(),
572
            'video'     => $this->getVideo(),
573
            'synopsis'  => $this->getSynopsis(),
574
            'score'     => $this->getScore(),
575
            'voter'     => $this->getVoter(),
576
            'rank'      => $this->getRank(),
577
            'popularity'=> $this->getPopularity(),
578
            'members'   => $this->getMembers(),
579
            'favorite'  => $this->getFavorite(),
580
        ];
581
582
        $data = array_merge($data, $this->getOtherInfo());
583
584
        $data2 = [
585
            'related'   => $this->getRelated(),
586
            'character' => $this->getCharacter(),
587
            'staff'     => $this->getStaff(),
588
            'song'      => $this->getSong(),
589
        ];
590
591
        $data = array_merge($data, $data2);
592
593
        return $data;
594
    }
595
}
596