Completed
Push — master ( ec724d...d71ed8 )
by Владислав
02:12
created

DeCaptchaBase::requestUniversal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 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 = 0;
13
    const ACTION_UNIVERSAL = 1;
14
    const ACTION_UNIVERSAL_WITH_CAPTCHA = 2;
15
16
    const ACTION_FIELD_METHOD = 0;
17
    const ACTION_FIELD_KEY = 1;
18
    const ACTION_FIELD_FILE = 2;
19
    const ACTION_FIELD_PHRASE = 3;
20
    const ACTION_FIELD_REGSENSE = 4;
21
    const ACTION_FIELD_NUMERIC = 5;
22
    const ACTION_FIELD_MIN_LEN = 6;
23
    const ACTION_FIELD_MAX_LEN = 7;
24
    const ACTION_FIELD_LANGUAGE = 8;
25
    const ACTION_FIELD_SOFT_ID = 9;
26
    const ACTION_FIELD_CAPTCHA_ID = 10;
27
    const ACTION_FIELD_ACTION = 11;
28
    const ACTION_FIELD_QUESTION = 12;
29
    const ACTION_FIELD_CALC = 13;
30
    const ACTION_FIELD_HEADER_ACAO = 14;
31
    const ACTION_FIELD_TEXTINSTRUCTIONS = 15;
32
    const ACTION_FIELD_PINGBACK = 16;
33
34
    const RESPONSE_RECOGNIZE_OK = 'OK';
35
    const RESPONSE_RECOGNIZE_REPEAT = 'ERROR_NO_SLOT_AVAILABLE';
36
    const RESPONSE_GET_OK = 'OK';
37
    const RESPONSE_GET_REPEAT = 'CAPCHA_NOT_READY';
38
39
    const SLEEP_RECOGNIZE = 5;
40
    const SLEEP_GET = 2;
41
    const SLEEP_BETWEEN = 5;
42
43
    const DECODE_ACTION_RECOGNIZE = 0;
44
    const DECODE_ACTION_GET = 1;
45
    const DECODE_ACTION_UNIVERSAL = 2;
46
47
    const DECODE_PARAM_RESPONSE = 0;
48
    const DECODE_PARAM_CAPTCHA = 1;
49
    const DECODE_PARAM_CODE = 2;
50
51
    protected $actions = [
52
        self::ACTION_RECOGNIZE              => [],
53
        self::ACTION_UNIVERSAL              => [],
54
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => [],
55
    ];
56
57
    protected $decodeSettings = [
58
        self::DECODE_FORMAT => self::RESPONSE_TYPE_STRING,
59
        self::DECODE_ACTION => [
60
            self::DECODE_ACTION_RECOGNIZE => [],
61
            self::DECODE_ACTION_GET       => [],
62
        ],
63
    ];
64
65
    protected $limitSettings = [
66
        self::ACTION_RECOGNIZE              => 3,
67
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => 20,
68
    ];
69
70
    /**
71
     * DeCaptchaBase constructor.
72
     *
73
     * @param $params
74
     */
75
    public function __construct($params)
76
    {
77
        $this->setParams($params);
78
        $this->init();
79
    }
80
81
    public function init()
82
    {
83
    }
84
85
    /**
86
     * @param $filePath
87
     *
88
     * @throws DeCaptchaErrors
89
     *
90
     * @return bool
91
     */
92
    public function recognize($filePath)
93
    {
94
        try {
95
            $this->resetLimits();
96
            $this->setParam(static::PARAM_SPEC_FILE, $this->getFilePath($filePath));
97
98
            return $this->requestRecognize() && $this->requestCode();
99
        } catch (DeCaptchaErrors $e) {
100
            if ($this->causeAnError) {
101
                throw $e;
102
            }
103
            $this->errorObject = $e;
104
105
            return false;
106
        }
107
    }
108
109
    /**
110
     * Запуск распознавания капчи.
111
     *
112
     * @deprecated
113
     *
114
     * @param string $filePath Путь до файла или ссылка на него
115
     *
116
     * @return bool
117
     */
118
    public function run($filePath)
119
    {
120
        return $this->recognize($filePath);
121
    }
122
123
    /**
124
     * Универсальная отправка повторяющихся запросов.
125
     *
126
     * @param int $action
127
     * @param int $decodeAction
128
     * @param int $setParam
129
     * @param int $decodeSerParam
130
     * @param int $ok
131
     * @param int $sleep
132
     * @param int $repeat
133
     *
134
     * @throws DeCaptchaErrors
135
     *
136
     * @return bool
137
     */
138
    protected function requestRepeat($action, $decodeAction, $setParam, $decodeSerParam, $ok, $sleep, $repeat)
139
    {
140
        while ($this->limitHasNotYetEnded($action)) {
141
            $this->executionDelayed($sleep);
142
            $response = $this->getResponse($action);
143
            $dataRecognize = $this->decodeResponse($decodeAction, $response);
144
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $ok && !empty($dataRecognize[$decodeSerParam])) {
145
                $this->setParam($setParam, $dataRecognize[$decodeSerParam]);
146
                $this->executionDelayed(static::SLEEP_BETWEEN);
147
148
                return true;
149
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $repeat) {
150
                continue;
151
            }
152
            throw new DeCaptchaErrors($dataRecognize[static::DECODE_PARAM_RESPONSE]);
153
        }
154
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
155
    }
156
157
    /**
158
     * Универсальная отправка
159
     *
160
     * @param string $action
161
     * @return array
162
     */
163
    protected function requestUniversal($action)
164
    {
165
        $this->setParam(static::ACTION_FIELD_ACTION, $action);
166
        $response = $this->getResponse(static::ACTION_UNIVERSAL);
167
        return $this->decodeResponse(static::DECODE_ACTION_UNIVERSAL, $response);
168
    }
169
170
    /**
171
     * @throws DeCaptchaErrors
172
     *
173
     * @return bool
174
     */
175
    protected function requestRecognize()
176
    {
177
        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);
178
    }
179
180
    /**
181
     * @throws DeCaptchaErrors
182
     *
183
     * @return bool
184
     */
185
    protected function requestCode()
186
    {
187
        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);
188
    }
189
190
    /**
191
     * @return \CURLFile|mixed|null|string
192
     */
193
    public function getCode()
194
    {
195
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
196
    }
197
198
    /**
199
     * @return string
200
     */
201
    public function getError()
202
    {
203
        return $this->errorObject->getMessage();
204
    }
205
206
    /**
207
     * @param bool $causeAnError
208
     */
209
    public function setCauseAnError($causeAnError)
210
    {
211
        $this->causeAnError = $causeAnError;
212
    }
213
}
214