CollectorTrait   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 79
ccs 35
cts 35
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
__call() 0 1 ?
B collect() 0 18 5
B collectAsync() 0 19 5
C getFormattedResultAndNextParams() 0 34 8
1
<?php
2
3
namespace mpyw\HardBotter\Traits;
4
5
use mpyw\Co\CoInterface;
6
use Aza\Components\Math\BigMath;
7
8
/**
9
 * @method mixed get($endpoint, array $params = [])
10
 * @method \Generator getAsync($endpoint, array $params = [])
11
 */
12
trait CollectorTrait
13
{
14
    abstract public function __call($method, array $args);
15
16 8
    public function collect($endpoint, $followable_page_count, array $params = [])
17
    {
18
        // カーソルに-1を指定する(不要な場合に余分なパラメータとしてつけても問題ない)
19 8
        $params += ['cursor' => '-1'];
20
        // 初回の結果を取得
21 8
        if (false === $result = $this->get($endpoint, $params)) {
22 2
            return false;
23
        }
24
        // 整形結果と次のリクエストに必要なパラメータを取得
25 8
        list($formatted, $next_params) = static::getFormattedResultAndNextParams($result, $params);
26
        // 次のリクエストが不必要であれば整形結果を返す
27 7
        if ($next_params === null || $followable_page_count < 1) {
28 4
            return $formatted;
29
        }
30
        // 次のリクエストを実行してマージした結果を返す
31 7
        $children = $this->collect($endpoint, $followable_page_count - 1, $next_params);
32 6
        return $children !== false ? array_merge($formatted, $children) : false;
33
    }
34
35 7
    public function collectAsync($endpoint, $followable_page_count, array $params = [])
36
    {
37
        // カーソルに-1を指定する(不要な場合に余分なパラメータとしてつけても問題ない)
38 7
        $params += ['cursor' => '-1'];
39
        // 初回の結果を取得
40 7
        if (false === $result = (yield $this->getAsync($endpoint, $params))) {
41 2
            yield CoInterface::RETURN_WITH => false;
42
        }
43
        // 整形結果と次のリクエストに必要なパラメータを取得
44 7
        list($formatted, $next_params) = static::getFormattedResultAndNextParams($result, $params);
45
        // 次のリクエストが不必要であれば整形結果を返す
46 7
        if ($next_params === null || $followable_page_count < 1) {
47 4
            yield CoInterface::RETURN_WITH => $formatted;
48
        }
49
        // 次のリクエストを実行してマージした結果を返す
50 7
        $children = (yield $this->collectAsync($endpoint, $followable_page_count - 1, $next_params));
51 6
        yield CoInterface::RETURN_WITH => $children !== false ? array_merge($formatted, $children) : false;
52
        // @codeCoverageIgnoreStart
53
    }
54
    // @codeCoverageIgnoreEnd
55
56 15
    protected static function getFormattedResultAndNextParams($result, array $params)
57
    {
58 15
        $is_statuses = is_array($result);
59 15
        $is_searches = isset($result->statuses) && is_array($result->statuses);
60 15
        $is_cursored = isset($result->next_cursor_str);
61
62
        // GET statuses/home_timeline や GET search/tweets など
63 15
        if ($is_statuses || $is_searches) {
64 10
            $formatted = $is_statuses ? $result : $result->statuses;
65 10
            $math = BigMath::createFromServerConfiguration();
66
            return [
67 10
                $formatted,
68 10
                $formatted
69 10
                    ? ['max_id' => $math->subtract(end($formatted)->id_str, 1)] + $params
70
                    : null
71
            ];
72
        }
73
74
        // GET followers/ids など
75 5
        if ($is_cursored) {
76
            // 配列であるプロパティの名前を求める
77 4
            $prop = key(array_filter((array)$result, 'is_array'));
78 4
            $formatted = $result->$prop;
79
            return [
80 4
                $formatted,
81 4
                $result->next_cursor_str
82 4
                    ? ['cursor' => $result->next_cursor_str] + $params
83
                    : null
84
            ];
85
        }
86
87
        // それ以外の場合はそもそもこのメソッドを使うべきではない
88 1
        throw new \BadMethodCallException('Incompatible endpoint.');
89
    }
90
}
91