Completed
Push — master ( fa8b7a...f05216 )
by Владислав
02:37
created

DeCaptchaBase   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 15
Bugs 9 Features 0
Metric Value
wmc 21
lcom 2
cbo 3
dl 0
loc 242
rs 10
c 15
b 9
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A init() 0 3 1
B recognize() 0 19 5
A run() 0 4 1
B requestRepeat() 0 21 6
A requestUniversal() 0 7 1
A requestRecognize() 0 4 1
A requestCode() 0 4 1
A getCode() 0 4 1
A getError() 0 4 1
A setCauseAnError() 0 4 1
A getWiki() 0 6 1
1
<?php
2
3
namespace jumper423\decaptcha\core;
4
5
/**
6
 * Распознавание капчи.
7
 *
8
 * Class DeCaptchaBase
9
 */
10
class DeCaptchaBase extends DeCaptchaAbstract implements DeCaptchaInterface
11
{
12
    const ACTION_RECOGNIZE = 1;
13
    const ACTION_UNIVERSAL = 2;
14
    const ACTION_UNIVERSAL_WITH_CAPTCHA = 3;
15
16
    const ACTION_FIELD_METHOD = 1;
17
    const ACTION_FIELD_KEY = 2;
18
    const ACTION_FIELD_FILE = 3;
19
    const ACTION_FIELD_PHRASE = 4;
20
    const ACTION_FIELD_REGSENSE = 5;
21
    const ACTION_FIELD_NUMERIC = 6;
22
    const ACTION_FIELD_MIN_LEN = 7;
23
    const ACTION_FIELD_MAX_LEN = 8;
24
    const ACTION_FIELD_LANGUAGE = 9;
25
    const ACTION_FIELD_SOFT_ID = 10;
26
    const ACTION_FIELD_CAPTCHA_ID = 11;
27
    const ACTION_FIELD_ACTION = 12;
28
    const ACTION_FIELD_QUESTION = 13;
29
    const ACTION_FIELD_CALC = 14;
30
    const ACTION_FIELD_HEADER_ACAO = 15;
31
    const ACTION_FIELD_INSTRUCTIONS = 16;
32
    const ACTION_FIELD_PINGBACK = 17;
33
    const ACTION_FIELD_TASK = 18;
34
    const ACTION_FIELD_IS_RUSSIAN = 19;
35
    const ACTION_FIELD_LABEL = 20;
36
    const ACTION_FIELD_GOOGLEKEY = 21;
37
    const ACTION_FIELD_RECAPTCHA = 22;
38
    const ACTION_FIELD_PROXY = 22;
39
    const ACTION_FIELD_PROXYTYPE = 23;
40
    const ACTION_FIELD_PAGEURL = 24;
41
    const ACTION_FIELD_GOOGLETOKEN = 25;
42
    const ACTION_FIELD_PROXYLOGIN = 26;
43
    const ACTION_FIELD_PROXYPASS = 27;
44
    const ACTION_FIELD_USERAGENT = 28;
45
    const ACTION_FIELD_COOKIES = 29;
46
    const ACTION_FIELD_PROXYPORT = 30;
47
    const ACTION_FIELD_COORDINATE = 31;
48
49
    const RESPONSE_RECOGNIZE_OK = 'OK';
50
    const RESPONSE_RECOGNIZE_REPEAT = 'ERROR_NO_SLOT_AVAILABLE';
51
    const RESPONSE_GET_OK = 'OK';
52
    const RESPONSE_GET_REPEAT = 'CAPCHA_NOT_READY';
53
54
    const SLEEP_RECOGNIZE = 5;
55
    const SLEEP_GET = 2;
56
    const SLEEP_BETWEEN = 5;
57
58
    const DECODE_ACTION_RECOGNIZE = 1;
59
    const DECODE_ACTION_GET = 2;
60
    const DECODE_ACTION_UNIVERSAL = 3;
61
62
    const DECODE_PARAM_RESPONSE = 1;
63
    const DECODE_PARAM_CAPTCHA = 2;
64
    const DECODE_PARAM_CODE = 3;
65
66
    public $actions = [
67
        self::ACTION_RECOGNIZE              => [],
68
        self::ACTION_UNIVERSAL              => [],
69
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => [],
70
    ];
71
72
    protected $decodeSettings = [
73
        self::DECODE_FORMAT => self::RESPONSE_TYPE_STRING,
74
        self::DECODE_ACTION => [
75
            self::DECODE_ACTION_RECOGNIZE => [],
76
            self::DECODE_ACTION_GET       => [],
77
        ],
78
    ];
79
80
    protected $limitSettings = [
81
        self::ACTION_RECOGNIZE              => 3,
82
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => 20,
83
    ];
84
85
    /**
86
     * @var DeCaptchaWiki
87
     */
88
    protected $wiki;
89
90
    /**
91
     * DeCaptchaBase constructor.
92
     *
93
     * @param $params
94
     */
95
    public function __construct($params)
96
    {
97
        $this->setParams($params);
98
        $this->wiki = new DeCaptchaWiki($this);
99
        $this->init();
100
    }
101
102
    public function init()
103
    {
104
    }
105
106
    /**
107
     * @param $filePath
108
     * @param array $additionally
109
     *
110
     * @throws DeCaptchaErrors
111
     *
112
     * @return bool
113
     */
114
    public function recognize($filePath, $additionally = [])
115
    {
116
        try {
117
            $this->resetLimits();
118
            if ($filePath) {
119
                $additionally[static::ACTION_FIELD_FILE] = $filePath;
120
            }
121
            $this->setParams($additionally);
122
123
            return $this->requestRecognize() && $this->requestCode();
124
        } catch (DeCaptchaErrors $e) {
125
            if ($this->causeAnError) {
126
                throw $e;
127
            }
128
            $this->errorObject = $e;
129
130
            return false;
131
        }
132
    }
133
134
    /**
135
     * Запуск распознавания капчи.
136
     *
137
     * @deprecated
138
     *
139
     * @param string $filePath Путь до файла или ссылка на него
140
     *
141
     * @return bool
142
     */
143
    public function run($filePath)
144
    {
145
        return $this->recognize($filePath);
146
    }
147
148
    /**
149
     * Универсальная отправка повторяющихся запросов.
150
     *
151
     * @param int      $action
152
     * @param int      $decodeAction
153
     * @param int      $setParam
154
     * @param int      $decodeSerParam
155
     * @param int      $ok
156
     * @param int      $sleep
157
     * @param int      $repeat
158
     * @param int|null $error
159
     *
160
     * @throws DeCaptchaErrors
161
     *
162
     * @return bool
163
     */
164
    protected function requestRepeat($action, $decodeAction, $setParam, $decodeSerParam, $ok, $sleep, $repeat, $error = null)
165
    {
166
        if (is_null($error)) {
167
            $error = static::DECODE_PARAM_RESPONSE;
168
        }
169
        while ($this->limitHasNotYetEnded($action)) {
170
            $this->executionDelayed($sleep);
171
            $response = $this->getResponse($action);
172
            $dataRecognize = $this->decodeResponse($decodeAction, $response);
173
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $ok && !empty($dataRecognize[$decodeSerParam])) {
174
                $this->setParam($setParam, $dataRecognize[$decodeSerParam]);
175
                $this->executionDelayed(static::SLEEP_BETWEEN);
176
177
                return true;
178
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $repeat) {
179
                continue;
180
            }
181
            throw new DeCaptchaErrors($dataRecognize[$error]);
182
        }
183
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
184
    }
185
186
    /**
187
     * Универсальная отправка.
188
     *
189
     * @param string $action
190
     *
191
     * @return array
192
     */
193
    protected function requestUniversal($action)
194
    {
195
        $this->setParam(static::ACTION_FIELD_ACTION, $action);
196
        $response = $this->getResponse(static::ACTION_UNIVERSAL);
197
198
        return $this->decodeResponse(static::DECODE_ACTION_UNIVERSAL, $response);
199
    }
200
201
    /**
202
     * @throws DeCaptchaErrors
203
     *
204
     * @return bool
205
     */
206
    protected function requestRecognize()
207
    {
208
        return $this->requestRepeat(static::ACTION_RECOGNIZE, static::DECODE_ACTION_RECOGNIZE, static::PARAM_SPEC_CAPTCHA, static::DECODE_PARAM_CAPTCHA, static::RESPONSE_RECOGNIZE_OK, static::SLEEP_RECOGNIZE, static::RESPONSE_RECOGNIZE_REPEAT);
209
    }
210
211
    /**
212
     * @throws DeCaptchaErrors
213
     *
214
     * @return bool
215
     */
216
    protected function requestCode()
217
    {
218
        return $this->requestRepeat(static::ACTION_UNIVERSAL_WITH_CAPTCHA, static::DECODE_ACTION_GET, static::PARAM_SPEC_CODE, static::DECODE_PARAM_CODE, static::RESPONSE_GET_OK, static::SLEEP_GET, static::RESPONSE_GET_REPEAT);
219
    }
220
221
    /**
222
     * @return \CURLFile|mixed|null|string
223
     */
224
    public function getCode()
225
    {
226
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
227
    }
228
229
    /**
230
     * @return string
231
     */
232
    public function getError()
233
    {
234
        return $this->errorObject->getMessage();
235
    }
236
237
    /**
238
     * @param bool $causeAnError
239
     */
240
    public function setCauseAnError($causeAnError)
241
    {
242
        $this->causeAnError = $causeAnError;
243
    }
244
245
    public function getWiki($lang = 'en')
246
    {
247
        $this->wiki->setLang($lang);
248
249
        return $this->wiki;
250
    }
251
}
252