Passed
Branch develop (29ed49)
by Alexey
01:58
created

CategoriesScraper::getDataScraper()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.1502

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 6
nop 2
dl 0
loc 17
ccs 9
cts 11
cp 0.8182
crap 5.1502
rs 9.6111
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * @author   Ne-Lexa
6
 * @license  MIT
7
 * @link     https://github.com/Ne-Lexa/google-play-scraper
8
 */
9
10
namespace Nelexa\GPlay\Scraper;
11
12
use Nelexa\GPlay\Exception\GooglePlayException;
13
use Nelexa\GPlay\Http\ResponseHandlerInterface;
14
use Nelexa\GPlay\Model\Category;
15
use Nelexa\GPlay\Util\ScraperUtil;
16
use Psr\Http\Message\RequestInterface;
17
use Psr\Http\Message\ResponseInterface;
18
19
/**
20
 * @internal
21
 */
22
class CategoriesScraper implements ResponseHandlerInterface
23
{
24
    private const CATEGORY_URL_PREFIX = '/store/apps/category/';
25
26
    /**
27
     * @param RequestInterface $request
28
     * @param ResponseInterface $response
29
     * @return mixed
30
     * @throws GooglePlayException
31
     */
32 3
    public function __invoke(RequestInterface $request, ResponseInterface $response)
33
    {
34 3
        $dataCategories = $this->getDataScraper($request, $response);
35
36
        $parseCategories = static function (array $items) use (&$parseCategories) : array {
37
            return array_reduce($items, static function ($results, $item) use (&$parseCategories) {
38 3
                if (is_array($item)) {
39
                    if (
40 3
                        count($item) === 6 &&
41 3
                        strpos($item[0], self::CATEGORY_URL_PREFIX) === 0 &&
42 3
                        strpos($item[0], '?age=') === false
43
                    ) {
44 3
                        $id = basename($item[0]);
45 3
                        $categoryName = $item[1];
46 3
                        $results[] = new Category(
47 3
                            $id,
48 3
                            $categoryName
49
                        );
50
                    } else {
51 3
                        $results = array_merge($results, $parseCategories($item));
52
                    }
53
                }
54 3
                return $results;
55 3
            }, []);
56 3
        };
57 3
        return $parseCategories($dataCategories[0][1][0][3]);
58
    }
59
60
    /**
61
     * @param RequestInterface $request
62
     * @param ResponseInterface $response
63
     * @return array
64
     * @throws GooglePlayException
65
     */
66 3
    private function getDataScraper(RequestInterface $request, ResponseInterface $response): array
67
    {
68 3
        $scriptData = ScraperUtil::extractScriptData($response->getBody()->getContents());
69
70 3
        $dataCategories = null;
71 3
        foreach ($scriptData as $key => $data) {
72 3
            if (isset($data[0][1][0][3][0]) && is_array($data[0][1][0][3][0])) {
73 3
                $dataCategories = $data;
74 3
                break;
75
            }
76
        }
77
78 3
        if ($dataCategories === null) {
79
            throw (new GooglePlayException('Failed to get the list of categories.'))
80
                ->setUrl($request->getUri()->__toString());
81
        }
82 3
        return $dataCategories;
83
    }
84
}
85