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

CategoriesScraper   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 92.59%

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 61
ccs 25
cts 27
cp 0.9259
rs 10
c 0
b 0
f 0
wmc 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getDataScraper() 0 17 5
A __invoke() 0 26 5
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