Passed
Push — master ( 290d71...1093d7 )
by Ryosuke
03:54
created

CollectorTrait::getFormattedResultAndNextParams()   C

Complexity

Conditions 8
Paths 14

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 33
ccs 16
cts 16
cp 1
rs 5.3846
cc 8
eloc 20
nc 14
nop 2
crap 8
1
<?php
2
3
namespace mpyw\HardBotter\Traits;
4
5
use mpyw\Co\CoInterface;
6
7
/**
8
 * @method mixed get($endpoint, array $params = [])
9
 * @method \Generator getAsync($endpoint, array $params = [])
10
 */
11
trait CollectorTrait
12
{
13
    abstract public function __call($method, array $args);
14
15 7
    public function collect($endpoint, $followable_page_count, array $params = [])
16
    {
17
        // カーソルに-1を指定する(不要な場合に余分なパラメータとしてつけても問題ない)
18 7
        $params += ['cursor' => '-1'];
19
        // 初回の結果を取得
20 7
        if (false === $result = $this->get($endpoint, $params)) {
21 2
            return false;
22
        }
23
        // 整形結果と次のリクエストに必要なパラメータを取得
24 7
        list($formatted, $next_params) = static::getFormattedResultAndNextParams($result, $params);
25
        // 次のリクエストが不必要であれば整形結果を返す
26 6
        if ($next_params === null || $followable_page_count < 1) {
27 3
            return $formatted;
28
        }
29
        // 次のリクエストを実行してマージした結果を返す
30 6
        $children = $this->collect($endpoint, $followable_page_count - 1, $next_params);
31 5
        return $children !== false ? array_merge($formatted, $children) : $formatted;
32
    }
33
34 5
    public function collectAsync($endpoint, $followable_page_count, array $params = [])
35
    {
36
        // カーソルに-1を指定する(不要な場合に余分なパラメータとしてつけても問題ない)
37 5
        $params += ['cursor' => '-1'];
38
        // 初回の結果を取得
39 5
        if (false === $result = (yield $this->getAsync($endpoint, $params))) {
40 2
            yield CoInterface::RETURN_WITH => false;
41
        }
42
        // 整形結果と次のリクエストに必要なパラメータを取得
43 5
        list($formatted, $next_params) = static::getFormattedResultAndNextParams($result, $params);
44
        // 次のリクエストが不必要であれば整形結果を返す
45 5
        if ($next_params === null || $followable_page_count < 1) {
46 2
            yield CoInterface::RETURN_WITH => $formatted;
47
        }
48
        // 次のリクエストを実行してマージした結果を返す
49 5
        $children = (yield $this->collectAsync($endpoint, $followable_page_count - 1, $next_params));
1 ignored issue
show
Bug introduced by
It seems like $next_params can also be of type null; however, mpyw\HardBotter\Traits\C...orTrait::collectAsync() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
50 4
        yield CoInterface::RETURN_WITH => $children !== false ? array_merge($formatted, $children) : $formatted;
51
        // @codeCoverageIgnoreStart
52
    }
53
    // @codeCoverageIgnoreEnd
54
55 12
    protected static function getFormattedResultAndNextParams($result, array $params)
56
    {
57 12
        $is_statuses = is_array($result);
58 12
        $is_searches = isset($result->statuses) && is_array($result->statuses);
59 12
        $is_cursored = isset($result->next_cursor_str);
60
61
        // GET statuses/home_timeline や GET search/tweets など
62 12
        if ($is_statuses || $is_searches) {
63 10
            $formatted = $is_statuses ? $result : $result->statuses;
64
            return [
65 10
                $formatted,
66 10
                $formatted
67 10
                    ? ['max_id' => bcsub(end($formatted)->id_str, 1)] + $params
68
                    : null
69
            ];
70
        }
71
72
        // GET followers/ids など
73 2
        if ($is_cursored) {
74
            // 配列であるプロパティの名前を求める
75 1
            $prop = key(array_filter((array)$result, 'is_array'));
76 1
            $formatted = $result->$prop;
77
            return [
78 1
                $formatted,
79 1
                $result->next_cursor_str
80 1
                    ? ['cursor' => $result->next_cursor_str] + $params
81
                    : null
82
            ];
83
        }
84
85
        // それ以外の場合はそもそもこのメソッドを使うべきではない
86 1
        throw new \BadMethodCallException('Incompatible endpoint.');
87
    }
88
}
89