Completed
Push — master ( 31d905...b5d7ba )
by Sergey
05:31 queued 02:23
created

Pagination::paginateOver()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
rs 8.8571
cc 6
eloc 11
nc 5
nop 3
1
<?php
2
3
namespace seregazhuk\PinterestBot\Helpers;
4
5
use seregazhuk\PinterestBot\Api\Providers\Provider;
6
7
class Pagination
8
{
9
    /**
10
     * @var Provider
11
     */
12
    private $provider;
13
14
    /**
15
     * @var array
16
     */
17
    protected $bookmarks = [];
18
19
    public function __construct(Provider $provider)
20
    {
21
        $this->provider = $provider;
22
    }
23
24
    /**
25
     * Iterate through results of Api function call. By
26
     * default generator will return all pagination results.
27
     * To limit result batches, set $limit. Call function
28
     * of object to get data.
29
     *
30
     * @param string $method
31
     * @param array $params
32
     * @param int $limit
33
     * @return \Iterator
34
     */
35
    public function paginateOver($method, $params, $limit = 0)
36
    {
37
        $resultsNum = 0;
38
        while (true) {
39
            
40
            $results = $this->callProviderRequest($method, $params);
41
            if (empty($results) || $this->checkEndBookMarks()) {
42
                return;
43
            }
44
45
            foreach ($results as $result) {
46
                $resultsNum++;
47
                yield $result;
48
49
                if ($this->reachesLimit($limit, $resultsNum)) {
50
                    return;
51
                }
52
            }
53
        }
54
    }
55
56
    protected function callProviderRequest($method, array $params)
57
    {
58
        $params['bookmarks'] = $this->bookmarks;
59
        $response = call_user_func_array([$this->provider, $method], $params);
60
61
        if ($this->responseHasData($response)) {
62
            $this->getBookMarks($response);
63
64
            return $this->getDataFromPaginatedResponse($response);
65
        }
66
67
        return [];
68
    }
69
70
    protected function getDataFromPaginatedResponse($response)
71
    {
72
        if ($this->responseHasData($response)) {
73
            $res = $this->clearResponseFromMetaData($response);
74
75
            return $res['data'];
76
        }
77
78
        return [];
79
    }
80
81
    /**
82
     * @param array $response
83
     *
84
     * @return bool
85
     */
86
    protected function responseHasData($response)
87
    {
88
        return isset($response['data']) && !empty($response['data']);
89
    }
90
91
    /**
92
     * Check if we get batches limit in pagination.
93
     *
94
     * @param int $limit
95
     * @param int $resultsNum
96
     *
97
     * @return bool
98
     */
99
    protected function reachesLimit($limit, $resultsNum)
100
    {
101
        return $limit && $resultsNum >= $limit;
102
    }
103
104
    /**
105
     * Remove 'module' data from response.
106
     *
107
     * @param array $response
108
     *
109
     * @return array mixed
110
     */
111
    protected function clearResponseFromMetaData($response)
112
    {
113
        if (isset($response['data'][0]['type']) && $response['data'][0]['type'] == 'module') {
114
            array_shift($response['data']);
115
        }
116
117
        return $response;
118
    }
119
120
    /**
121
     * @param $response
122
     *
123
     * @return array
124
     */
125
    protected function getBookMarks($response)
126
    {
127
        $this->bookmarks = isset($response['bookmarks']) ? $response['bookmarks'] : [];
128
129
        return $this;
130
    }
131
132
    protected function checkEndBookMarks()
133
    {
134
        return !empty($this->bookmarks) && $this->bookmarks[0] == '-end-';
135
    }
136
}
137