Completed
Push — master ( eaac19...9232f4 )
by Владислав
02:07
created

DeCaptchaBase::recognize()   A

Complexity

Conditions 4
Paths 9

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 5 Features 0
Metric Value
dl 0
loc 16
rs 9.2
c 8
b 5
f 0
cc 4
eloc 10
nc 9
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_BALANCE = 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
            self::DECODE_ACTION_BALANCE   => [],
63
        ],
64
    ];
65
66
    protected $limitSettings = [
67
        self::ACTION_RECOGNIZE              => 3,
68
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => 20,
69
    ];
70
71
    /**
72
     * DeCaptchaBase constructor.
73
     *
74
     * @param $params
75
     */
76
    public function __construct($params)
77
    {
78
        $this->setParams($params);
79
        $this->init();
80
    }
81
82
    public function init()
83
    {
84
    }
85
86
    /**
87
     * @param $filePath
88
     *
89
     * @throws DeCaptchaErrors
90
     *
91
     * @return bool
92
     */
93
    public function recognize($filePath)
94
    {
95
        try {
96
            $this->resetLimits();
97
            $this->setParam(static::PARAM_SPEC_FILE, $this->getFilePath($filePath));
98
99
            return $this->requestRecognize() && $this->requestCode();
100
        } catch (DeCaptchaErrors $e) {
101
            if ($this->causeAnError) {
102
                throw $e;
103
            }
104
            $this->errorObject = $e;
105
106
            return false;
107
        }
108
    }
109
110
    /**
111
     * Запуск распознавания капчи.
112
     *
113
     * @deprecated
114
     *
115
     * @param string $filePath Путь до файла или ссылка на него
116
     *
117
     * @return bool
118
     */
119
    public function run($filePath)
120
    {
121
        return $this->recognize($filePath);
122
    }
123
124
    /**
125
     * Универсальная отправка повторяющихся запросов
126
     * @param $action
127
     * @param $decodeAction
128
     * @param $setParam
129
     * @param $decodeSerParam
130
     * @param $ok
131
     * @param $sleep
132
     * @param $repeat
133
     * @return bool
134
     * @throws DeCaptchaErrors
135
     */
136
    protected function requestRepeat($action, $decodeAction, $setParam, $decodeSerParam, $ok, $sleep, $repeat){
137
        while ($this->limitHasNotYetEnded($action)) {
138
            $this->executionDelayed($sleep);
139
            $response = $this->getResponse($action);
140
            $dataRecognize = $this->decodeResponse($decodeAction, $response);
141
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $ok && !empty($dataRecognize[$decodeSerParam])) {
142
                $this->setParam($setParam, $dataRecognize[$decodeSerParam]);
143
                $this->executionDelayed(static::SLEEP_BETWEEN);
144
145
                return true;
146
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $repeat) {
147
                continue;
148
            }
149
            throw new DeCaptchaErrors($dataRecognize[static::DECODE_PARAM_RESPONSE]);
150
        }
151
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
152
    }
153
154
    /**
155
     * @throws DeCaptchaErrors
156
     *
157
     * @return bool
158
     */
159
    protected function requestRecognize()
160
    {
161
        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);
162
    }
163
164
    /**
165
     * @throws DeCaptchaErrors
166
     *
167
     * @return bool
168
     */
169
    protected function requestCode()
170
    {
171
        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);
172
    }
173
174
    /**
175
     * @return \CURLFile|mixed|null|string
176
     */
177
    public function getCode()
178
    {
179
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
180
    }
181
182
    /**
183
     * @return string
184
     */
185
    public function getError()
186
    {
187
        return $this->errorObject->getMessage();
188
    }
189
190
    /**
191
     * @param bool $causeAnError
192
     */
193
    public function setCauseAnError($causeAnError)
194
    {
195
        $this->causeAnError = $causeAnError;
196
    }
197
}
198