Passed
Push — master ( e27751...290d71 )
by Ryosuke
03:01
created

Bot::getClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace mpyw\HardBotter;
4
5
use mpyw\Cowitter\Client;
6
use mpyw\Co\Co;
7
8
class Bot implements IBotEssential, IbotHelper
9
{
10
    private $client;
11
    private $file;
12
    private $prev;
13
    private $marked = [];
14
    private $mark_limit = 10000;
15
    private $back_limit = 3600;
16
    private $get_error_mode = self::ERRMODE_EXCEPTION;
17
    private $post_error_mode = self::ERRMODE_WARNING;
18
19
    use Traits\CollectorTrait;
20
    use Traits\FollowManagerTrait;
21
    use Traits\TweetManagerTrait;
22
    use Traits\InterceptorTrait;
23
    use Traits\SharedUtilityTrait;
24
25
    /**
26
     * コンストラクタ
27
     * 副作用が大量にあるので注意
28
     */
29
    public function __construct(
30
        Client $client, $filename = 'stamp.json',
31
        $span = 0, $mark_limit = 10000, $back_limit = 3600
32
    ) {
33
        // ヘッダの送出
34
        if (!headers_sent()) {
35
            header('Content-Type: text/html; charset=UTF-8');
36
        }
37
38
        // エラー表示の設定
39
        error_reporting(-1);
40
        ini_set('log_errors', PHP_SAPI === 'cli');
41
        ini_set('display_errors', PHP_SAPI !== 'cli');
42
43
        // 重複起動防止
44
        $file = new \SplFileObject($filename, 'a+b');
45
        if (!$file->flock(LOCK_EX | LOCK_UN)) {
46
            throw new \RuntimeException('Failed to lock file.');
47
        }
48
49
        // JSONとして保存してあるデータを取得
50
        $json = $file->getSize() > 0
51
            ? json_decode($file->fread($file->getSize()), true)
52
            : [];
53
54
        // JSONに前回実行時刻が保存されていた時
55
        if (isset($json['prev'])) {
56
            // 十分に時間が空いたかどうかをチェック
57
            if (!static::expired($json['prev'], $span)) {
58
                throw new \RuntimeException('Execution span is not enough.');
59
            }
60
        }
61
62
        // JSONにマーク済みステータス一覧が記録されていたとき復元する
63
        if (isset($json['marked'])) {
64
            $this->marked = array_map('filter_var', (array)$json['marked']);
65
        }
66
67
        $this->client = $client;
68
        $this->file = $file;
69
        $this->prev = (new \DateTimeImmutable('now', new \DateTimeZone('UTC')))->format('r');
70
        $this->mark_limit = $mark_limit;
71
        $this->back_limit = $back_limit;
72
    }
73
74
    /**
75
     * デストラクタ
76
     */
77
    final public function __destruct()
78
    {
79
        $this->file->ftruncate(0);
80
        $this->file->fwrite(json_encode([
81
            'prev' => $this->prev,
82
            // 収まりきらない古い情報は破棄する
83
            'marked' => array_slice($this->marked, -$this->mark_limit, $this->mark_limit, true),
84
        ]));
85
        $this->file->flock(LOCK_UN);
86
    }
87
88
    /**
89
     * マーク
90
     */
91
    public function mark(\stdClass $status) {
92
        $this->marked[$status->id_str] = true;
93
    }
94
95
    /**
96
     * セッター・ゲッター
97
     */
98
    public function setGetErrorMode($mode) {
99
        $this->get_error_mode = $mode;
100
    }
101
    public function setPostErrorMode($mode) {
102
        $this->post_error_mode = $mode;
103
    }
104
    public function getGetErrorMode()
105
    {
106
        return $this->get_error_mode;
107
    }
108
    public function getPostErrorMode()
109
    {
110
        return $this->post_error_mode;
111
    }
112
    public function getMarkedStatusIds()
113
    {
114
        return $this->marked;
115
    }
116
    public function getBackLimitSeconds()
117
    {
118
        return $this->back_limit;
119
    }
120
    public function getMarkLimitCounts()
121
    {
122
        return $this->mark_limit;
123
    }
124
    public function getClient()
125
    {
126
        return $this->client;
127
    }
128
129
    /**
130
     * clone および serialize 対策
131
     */
132
    final public function __sleep()
133
    {
134
        throw new \BadMethodCallException('Instances are not serializable.');
135
    }
136
    final public function __clone()
137
    {
138
        throw new \BadMethodCallException('Instances are not clonable.');
139
    }
140
}
141