Completed
Push — master ( e6c141...8578af )
by Владислав
03:26
created

DeCaptchaWiki   F

Complexity

Total Complexity 53

Size/Duplication

Total Lines 673
Duplicated Lines 10.85 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 53
c 0
b 0
f 0
lcom 1
cbo 1
dl 73
loc 673
rs 1.6282

13 Methods

Rating   Name   Duplication   Size   Complexity  
A setLang() 0 4 1
B __construct() 0 364 1
A setText() 7 7 2
C getText() 28 28 7
A viewInstall() 0 16 1
F viewExamples() 38 111 16
C viewFields() 0 22 9
A viewFieldLine() 0 14 3
B viewMenu() 0 27 5
A getNameConst() 0 12 4
A view() 0 23 1
A getFileName() 0 9 2
A save() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DeCaptchaWiki often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DeCaptchaWiki, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace jumper423\decaptcha\core;
4
5
/**
6
 * Class DeCaptchaAbstract.
7
 */
8
class DeCaptchaWiki
9
{
10
    protected $texts = [];
11
    /**
12
     * @var DeCaptchaBase
13
     */
14
    protected $class;
15
    protected $lang = 'en';
16
17
    public function setLang($lang)
18
    {
19
        $this->lang = $lang;
20
    }
21
22
    public function __construct($class)
23
    {
24
        $this->class = $class;
25
        $this->texts = [
26
            'constructor_data' => [
27
                $class::ACTION_FIELD_KEY => '94f39af4bb295c40546fba5c932e0d32',
28
            ],
29
            'recognize_file'                                    => true,
30
            'recognize_data_file'                               => 'http://site.com/captcha.jpg',
31
            'recognize_data'                                    => [],
32
            'field_main_name_'.$class::ACTION_FIELD_KEY         => [
33
                'ru' => 'Ключ',
34
                'en' => 'Key',
35
            ],
36
            'field_main_desc_'.$class::ACTION_FIELD_KEY => [
37
                'ru' => 'Ключ от учетной записи',
38
                'en' => 'Key account',
39
            ],
40
            'field_main_name_'.$class::ACTION_FIELD_LANGUAGE => [
41
                'ru' => 'Язык',
42
                'en' => 'Language',
43
            ],
44
            'field_main_desc_'.$class::ACTION_FIELD_LANGUAGE => [
45
                'ru' => 'На каком языке текст на капче',
46
                'en' => 'What language the text on the captcha',
47
            ],
48
            'field_main_name_'.$class::ACTION_FIELD_FILE => [
49
                'ru' => 'Картинка',
50
                'en' => 'Picture',
51
            ],
52
            'field_main_desc_'.$class::ACTION_FIELD_FILE => [
53
                'ru' => 'Путь на файл с картинкой или ссылка на него',
54
                'en' => 'The path to the picture file or link to it',
55
            ],
56
            'field_main_name_'.$class::ACTION_FIELD_PHRASE => [
57
                'ru' => 'Несколько слов',
58
                'en' => 'A few words',
59
            ],
60
            'field_main_desc_'.$class::ACTION_FIELD_PHRASE => [
61
                'ru' => 'Работник должен ввести текст с одним или несколькими пробелами',
62
                'en' => 'The worker must enter text with one or more spaces',
63
            ],
64
            'field_main_name_'.$class::ACTION_FIELD_REGSENSE => [
65
                'ru' => 'Регистр',
66
                'en' => 'Register',
67
            ],
68
            'field_main_desc_'.$class::ACTION_FIELD_REGSENSE => [
69
                'ru' => 'Работник должен ввести ответ с учетом регистра',
70
                'en' => 'The worker must enter the answer case sensitive',
71
            ],
72
            'field_main_name_'.$class::ACTION_FIELD_NUMERIC => [
73
                'ru' => 'Символы',
74
                'en' => 'Characters',
75
            ],
76
            'field_main_desc_'.$class::ACTION_FIELD_NUMERIC => [
77
                'ru' => 'Какие символы используется в капче',
78
                'en' => 'What are the symbols used in captcha',
79
            ],
80
            'field_main_name_'.$class::ACTION_FIELD_CALC => [
81
                'ru' => 'Вычисление',
82
                'en' => 'Calculation',
83
            ],
84
            'field_main_desc_'.$class::ACTION_FIELD_CALC => [
85
                'ru' => 'На капче изображенно математичекая выражение и её необходимо решить',
86
                'en' => 'The captcha shows matematicheskaya expression and must be addressed',
87
            ],
88
            'field_main_name_'.$class::ACTION_FIELD_MIN_LEN => [
89
                'ru' => 'Длина min',
90
                'en' => 'Length min',
91
            ],
92
            'field_main_desc_'.$class::ACTION_FIELD_MIN_LEN => [
93
                'ru' => 'Минимальная длина капчи',
94
                'en' => 'The minimum length of captcha',
95
            ],
96
            'field_main_name_'.$class::ACTION_FIELD_MAX_LEN => [
97
                'ru' => 'Длина max',
98
                'en' => 'Length max',
99
            ],
100
            'field_main_desc_'.$class::ACTION_FIELD_MAX_LEN => [
101
                'ru' => 'Максимальная длина капчи',
102
                'en' => 'The maximum length of the captcha',
103
            ],
104
            'field_main_name_'.$class::ACTION_FIELD_QUESTION => [
105
                'ru' => 'Вопрос',
106
                'en' => 'Question',
107
            ],
108
            'field_main_desc_'.$class::ACTION_FIELD_QUESTION => [
109
                'ru' => 'На изображении задан вопрос, работник должен написать ответ',
110
                'en' => 'The image asked, the employee must write the answer',
111
            ],
112
            'field_main_name_'.$class::ACTION_FIELD_IS_RUSSIAN => [
113
                'ru' => 'Кириллица',
114
                'en' => 'Cyrillic',
115
            ],
116
            'field_main_desc_'.$class::ACTION_FIELD_IS_RUSSIAN => [
117
                'ru' => 'На изображении присутствуют русские символы',
118
                'en' => 'In the image there are Russian characters',
119
            ],
120
            'field_main_name_'.$class::ACTION_FIELD_LANGUAGE => [
121
                'ru' => 'Язык',
122
                'en' => 'Language',
123
            ],
124
            'field_main_desc_'.$class::ACTION_FIELD_LANGUAGE => [
125
                'ru' => 'Символы какого языка размещенны на капче',
126
                'en' => 'The symbols of the language posted on the captcha',
127
            ],
128
            'field_main_name_'.$class::ACTION_FIELD_HEADER_ACAO => [
129
                'ru' => 'Кросс-доменный',
130
                'en' => 'Cross-domain',
131
            ],
132
            'field_main_desc_'.$class::ACTION_FIELD_HEADER_ACAO => [
133
                'ru' => 'Необходимо для кросс-доменных AJAX запросов в браузерных приложениях.',
134
                'en' => 'Need for cross-domain AJAX requests in browser-based applications.',
135
            ],
136
            'field_main_name_'.$class::ACTION_FIELD_INSTRUCTIONS => [
137
                'ru' => 'Инструкция',
138
                'en' => 'Manual',
139
            ],
140
            'field_main_desc_'.$class::ACTION_FIELD_INSTRUCTIONS => [
141
                'ru' => 'Текстовая капча или инструкция для прохождения капчи.',
142
                'en' => 'Text captcha or manual to pass the captcha.',
143
            ],
144
            'field_main_name_'.$class::ACTION_FIELD_PINGBACK => [
145
                'ru' => 'Ответ на',
146
                'en' => 'Response to',
147
            ],
148
            'field_main_desc_'.$class::ACTION_FIELD_PINGBACK => [
149
                'ru' => 'Указание для сервера, что после распознания изображения, нужно отправить ответ на указанный адрес.',
150
                'en' => 'Note to server, after recognizing the image, you need to send a reply to the specified address.',
151
            ],
152
            'field_main_name_'.$class::ACTION_FIELD_LABEL => [
153
                'ru' => 'От куда',
154
                'en' => 'From where',
155
            ],
156
            'field_main_desc_'.$class::ACTION_FIELD_LABEL => [
157
                'ru' => 'Пояснение от куда пришла капча ("vk", "google", "recaptcha", "yandex", "mailru", "yahoo" и т.д.).',
158
                'en' => 'Clarification from where came the captcha ("vk", "google", "recaptcha", "yandex", "Google", "yahoo", etc.).',
159
            ],
160
            'field_main_name_'.$class::ACTION_FIELD_PAGEURL => [
161
                'ru' => 'Адрес',
162
                'en' => 'Link',
163
            ],
164
            'field_main_desc_'.$class::ACTION_FIELD_PAGEURL => [
165
                'ru' => 'Адрес страницы на которой решается капча.',
166
                'en' => 'The address of the page where the captcha is solved.',
167
            ],
168
            'field_main_name_'.$class::ACTION_FIELD_GOOGLEKEY => [
169
                'ru' => 'Google key',
170
                'en' => 'Google key',
171
            ],
172
            'field_main_desc_'.$class::ACTION_FIELD_GOOGLEKEY => [
173
                'ru' => 'Ключ-индентификатор рекапчи на целевой странице. <div class="g-recaptcha" data-sitekey="ВОТ_ЭТОТ"></div>',
174
                'en' => 'Key-the identifier of the recaptcha on the landing page. <div class="g-recaptcha" data-sitekey="THIS"></div>',
175
            ],
176
            'field_main_name_'.$class::ACTION_FIELD_GOOGLETOKEN => [
177
                'ru' => 'Google token',
178
                'en' => 'Google token',
179
            ],
180
            'field_main_desc_'.$class::ACTION_FIELD_GOOGLETOKEN => [
181
                'ru' => 'Секретный токен для предыдущей версии рекапчи. В большинстве случаев сайты используют новую версию и этот токен не требуется. Секретный токен генерируется на сервере Google и вставляется на страницу в атрибуте data-stoken. Выглядит это примерно так: <script type="text/javascript" src="...." data-type="normal"  data-ray="..." async data-sitekey="..." data-stoken="ВОТ_ЭТОТ"></script> Токен действует пару минут после генерации, затем нужно снова зайти на страницу и получить его.',
182
                'en' => 'The secret token for the previous version of recaptcha. In most cases, sites use the new version and this token is not required. The secret token is generated on a Google server and inserted into the page in the attribute data-stoken. It looks like this: <script type="text/javascript" src="...." data-type="normal" data-ray="..." async data-sitekey="..." data-stoken="THIS"></script> the Token is valid a few minutes after generation, then you need to go back to the page and get it.',
183
            ],
184
            'field_main_name_'.$class::ACTION_FIELD_PROXYTYPE => [
185
                'ru' => 'Тип прокси',
186
                'en' => 'The proxy type',
187
            ],
188
            'field_main_desc_'.$class::ACTION_FIELD_PROXYTYPE => [
189
                'ru' => 'Тип прокси (http, socks4, ...)',
190
                'en' => 'The proxy type (http, socks4, ...)',
191
            ],
192
            'field_main_name_'.$class::ACTION_FIELD_PROXY => [
193
                'ru' => 'Адрес прокси',
194
                'en' => 'The proxy address',
195
            ],
196
            'field_main_desc_'.$class::ACTION_FIELD_PROXY => [
197
                'ru' => 'IP адрес прокси ipv4/ipv6.',
198
                'en' => 'IP address of the proxy ipv4/ipv6.',
199
            ],
200
            'field_main_name_'.$class::ACTION_FIELD_PROXYPORT => [
201
                'ru' => 'Порт прокси',
202
                'en' => 'Proxy port',
203
            ],
204
            'field_main_desc_'.$class::ACTION_FIELD_PROXYPORT => [
205
                'ru' => 'Порт прокси.',
206
                'en' => 'Proxy port.',
207
            ],
208
            'field_main_name_'.$class::ACTION_FIELD_PROXYLOGIN => [
209
                'ru' => 'Логин прокси',
210
                'en' => 'Login proxy',
211
            ],
212
            'field_main_desc_'.$class::ACTION_FIELD_PROXYLOGIN => [
213
                'ru' => 'Логин от прокси-сервера.',
214
                'en' => 'Login from proxy server.',
215
            ],
216
            'field_main_name_'.$class::ACTION_FIELD_PROXYPASS => [
217
                'ru' => 'Пароль прокси',
218
                'en' => 'Password proxy',
219
            ],
220
            'field_main_desc_'.$class::ACTION_FIELD_PROXYPASS => [
221
                'ru' => 'Пароль от прокси-сервера.',
222
                'en' => 'The password for the proxy server.',
223
            ],
224
            'field_main_name_'.$class::ACTION_FIELD_USERAGENT => [
225
                'ru' => 'User-Agent браузера',
226
                'en' => 'User-Agent browser',
227
            ],
228
            'field_main_desc_'.$class::ACTION_FIELD_USERAGENT => [
229
                'ru' => 'User-Agent браузера, используемый в эмуляции. Необходимо использовать подпись современного браузера, иначе Google будет возвращать ошибку, требуя обновить браузер.',
230
                'en' => 'User-Agent browser used in emulation. You must use the signature modern browser, otherwise Google will return an error requiring you to upgrade your browser.',
231
            ],
232
            'field_main_name_'.$class::ACTION_FIELD_COOKIES => [
233
                'ru' => 'Куки',
234
                'en' => 'Cookies',
235
            ],
236
            'field_main_desc_'.$class::ACTION_FIELD_COOKIES => [
237
                'ru' => 'Дополнительные cookies которые мы должны использовать во время взаимодействия с целевой страницей.',
238
                'en' => 'Additional cookies which we should use during the interaction with the target page.',
239
            ],
240
            'table_th_name' => [
241
                'ru' => 'Название',
242
                'en' => 'Name',
243
            ],
244
            'table_th_code' => [
245
                'ru' => 'Код',
246
                'en' => 'Code',
247
            ],
248
            'table_th_type' => [
249
                'ru' => 'Тип',
250
                'en' => 'Type',
251
            ],
252
            'table_th_req' => [
253
                'ru' => 'Обяз.', //Обязательное
254
                'en' => 'Req.', //Required
255
            ],
256
            'table_th_def' => [
257
                'ru' => 'По ум.', //По умолчания
258
                'en' => 'By def.', //By default
259
            ],
260
            'table_th_enum' => [
261
                'ru' => 'Возможные значения',
262
                'en' => 'Possible values',
263
            ],
264
            'table_th_desc' => [
265
                'ru' => 'Описание',
266
                'en' => 'Description',
267
            ],
268
            'slug_link' => [
269
                'ru' => 'Ссылка',
270
                'en' => 'Link',
271
            ],
272
            'slug_link_to_service' => [
273
                'ru' => 'Ссылка на сервис',
274
                'en' => 'The link to the service',
275
            ],
276
            'slug_price' => [
277
                'ru' => 'Цены',
278
                'en' => 'Prices',
279
            ],
280
            'slug_service_desc' => [
281
                'ru' => 'Описание сервиса',
282
                'en' => 'The description of the service',
283
            ],
284
            'slug_recognize_desc' => [
285
                'ru' => 'Описание распознания',
286
                'en' => 'Description recognition',
287
            ],
288
            'slug_fields_desc' => [
289
                'ru' => 'Описание полей',
290
                'en' => 'A description of the fields',
291
            ],
292
            'example' => [
293
                'ru' => 'Примеры',
294
                'en' => 'Examples',
295
            ],
296
            'example_initialization' => [
297
                'ru' => 'Инициализация',
298
                'en' => 'Initialization',
299
            ],
300
            'example_initialization_desc' => [
301
                'ru' => 'Указываем ключ, обязательные и дополнительные параметры. Старайтесь по максимуму их заполнить это способствует более быстрому распознанию капчи.',
302
                'en' => 'Specify the key mandatory and optional parameters. Try the best to fill this promotes more rapid recognition of captcha.',
303
            ],
304
            'example_recognize' => [
305
                'ru' => 'Распознавание',
306
                'en' => 'Recognition',
307
            ],
308
            'example_recognize_desc' => [
309
                'ru' => 'В первом параметре передаём ссылку или путь на файл с картинкой, во второй параметры распознания при необходимости переопределения тех которые были переданы при инициализации.',
310
                'en' => 'In the first parameter, pass the link or path to the picture file in the second parameters of the recognition if necessary, override those which were transferred during the initialization.',
311
            ],
312
            'example_nottrue' => [
313
                'ru' => 'Не верно распознано',
314
                'en' => 'Not correctly recognized',
315
            ],
316
            'example_nottrue_desc' => [
317
                'ru' => 'Если Вы сможете понять что ответ которые пришёл не верные. Обязательно добавьте ниже написанный код. Это Вам съекономит деньги.',
318
                'en' => 'If You can understand that the answer which did not come true. Be sure to add below written code. It will save You money.',
319
            ],
320
            'example_balance' => [
321
                'ru' => 'Баланс',
322
                'en' => 'Balance',
323
            ],
324
            'example_error_lang_if' => [
325
                'ru' => true,
326
                'en' => false,
327
            ],
328
            'example_error_lang' => [
329
                'ru' => 'Язык ошибки',
330
                'en' => 'Language errors',
331
            ],
332
            'example_error_lang_desc' => [
333
                'ru' => 'По умолчанию ошибки на англиском языке, если необходимо переоперелить, сделайте следующее',
334
                'en' => 'Default error in English, if you want to properlyt, do the following',
335
            ],
336
            'example_error_interception' => [
337
                'ru' => 'Перехват ошибки',
338
                'en' => 'Intercept errors',
339
            ],
340
            'example_error_interception_desc' => [
341
                'ru' => 'При желании Вы можете перехватывать ошибку, но для этого надо вызвать setCauseAnError',
342
                'en' => 'If you wish, You can catch the error, but you need to call setCauseAnError',
343
            ],
344
            'install' => [
345
                'ru' => 'Установка',
346
                'en' => 'Installation',
347
            ],
348
            'install_preferred' => [
349
                'ru' => 'Предпочтительный способ установить это расширение через',
350
                'en' => 'The preferred way to install this extension via',
351
            ],
352
            'install_start' => [
353
                'ru' => 'Либо запустить',
354
                'en' => 'Or you can run',
355
            ],
356
            'install_add' => [
357
                'ru' => 'или добавить',
358
                'en' => 'or add',
359
            ],
360
            'install_add_file' => [
361
                'ru' => 'в файл',
362
                'en' => 'in file',
363
            ],
364
            'slug_menu' => [
365
                'ru' => 'Меню',
366
                'en' => 'Menu',
367
            ],
368
            'slug_menu_main' => [
369
                'ru' => 'Главная',
370
                'en' => 'Main',
371
            ],
372
            'slug_menu_another' => [
373
                'ru' => 'Documentation in English language',
374
                'en' => 'Документация на русском языке',
375
            ],
376
            'slug_menu_anchor' => [
377
                'ru' => 'Якоря',
378
                'en' => 'Anchor',
379
            ],
380
            'slug_menu_from_service' => [
381
                'ru' => 'Другой функционал от сервиса',
382
                'en' => 'Other functionality from the service',
383
            ],
384
        ];
385
    }
386
387
    /**
388
     * @param string|array $name
389
     * @param string|array $value
390
     */
391 View Code Duplication
    public function setText($name, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
392
    {
393
        if (is_array($name)) {
394
            $name = implode('_', $name);
395
        }
396
        $this->texts[$name] = $value;
397
    }
398
399
    /**
400
     * @param string|array $name
401
     * @param string       $separator
402
     *
403
     * @return string|array
404
     */
405 View Code Duplication
    public function getText($name, $separator = '; ')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
406
    {
407
        $getResult = function ($name, $texts) {
408
            if (is_array($name)) {
409
                $name = implode('_', $name);
410
            }
411
            if (!isset($texts[$name])) {
412
                return null;
413
            }
414
            if (is_array($texts[$name])) {
415
                if (isset($texts[$name][$this->lang])) {
416
                    return $texts[$name][$this->lang];
417
                }
418
419
                return array_values($texts[$name])[0];
420
            }
421
422
            return $texts[$name];
423
        };
424
        $result = $getResult($name, $this->texts);
425
        if (is_array($result)) {
426
            if ($separator) {
427
                $result = implode($separator, $result);
428
            }
429
        }
430
431
        return $result;
432
    }
433
434
    protected function viewInstall()
435
    {
436
        $str = "{$this->getText(['install', 'preferred'])} [composer](http://getcomposer.org/download/).".PHP_EOL;
437
        $str .= PHP_EOL;
438
        $str .= "{$this->getText(['install', 'start'])}".PHP_EOL;
439
        $str .= '```'.PHP_EOL;
440
        $str .= 'php composer.phar require --prefer-dist jumper423/decaptcha "*"'.PHP_EOL;
441
        $str .= '```'.PHP_EOL;
442
        $str .= "{$this->getText(['install', 'add'])}".PHP_EOL;
443
        $str .= '```'.PHP_EOL;
444
        $str .= '"jumper423/decaptcha": "*"'.PHP_EOL;
445
        $str .= '```'.PHP_EOL;
446
        $str .= "{$this->getText(['install', 'add', 'file'])} `composer.json`.".PHP_EOL;
447
448
        return $str;
449
    }
450
451
    protected function viewExamples()
452
    {
453
        $class = $this->class;
454
        $rc = (new \ReflectionClass($class));
455
456
        $str = "####{$this->getText(['example', 'initialization'])}".PHP_EOL;
457
        $str .= "{$this->getText(['example', 'initialization', 'desc'])}".PHP_EOL;
458
        $str .= '```'.PHP_EOL;
459
        $str .= "use {$rc->getName()};".PHP_EOL;
0 ignored issues
show
Bug introduced by
Consider using $rc->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
460
        $str .= ''.PHP_EOL;
461
        $str .= '$captcha = new '.$rc->getShortName().'(['.PHP_EOL;
462
        foreach ($this->texts['constructor_data'] as $key => $val) {
463
            $str .= "    {$rc->getShortName()}::{$this->getNameConst('ACTION_FIELD_', $key)} => ";
464
            if (is_string($val)) {
465
                $str .= "'{$val}'";
466
            } else {
467
                $str .= "{$val}";
468
            }
469
            $str .= ','.PHP_EOL;
470
        }
471
        $str .= ']);'.PHP_EOL;
472
        $str .= '```'.PHP_EOL;
473
474
        $str .= "####{$this->getText(['example', 'recognize'])}".PHP_EOL;
475
        $str .= "{$this->getText(['example', 'recognize', 'desc'])}".PHP_EOL;
476
        $str .= '```'.PHP_EOL;
477
        $str .= 'if ($captcha->recognize(';
478 View Code Duplication
        if ($this->texts['recognize_file']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
479
            $str .= "'{$this->getText(['recognize', 'data', 'file'])}'";
480
        }
481 View Code Duplication
        if ($this->texts['recognize_data']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
482
            if ($this->texts['recognize_file']) {
483
                $str .= ', ';
484
            }
485
            $str .= '['.PHP_EOL;
486
            foreach ($this->texts['recognize_data'] as $key => $val) {
487
                $str .= "    {$rc->getShortName()}::{$this->getNameConst('ACTION_FIELD_', $key)} => ";
488
                if (is_string($val)) {
489
                    $str .= "'{$val}'";
490
                } else {
491
                    $str .= "{$val}";
492
                }
493
                $str .= ','.PHP_EOL;
494
            }
495
            $str .= ']';
496
        }
497
        $str .= ')) {'.PHP_EOL;
498
        $str .= '    $code = $captcha->getCode();'.PHP_EOL;
499
        $str .= '} else {'.PHP_EOL;
500
        $str .= '    $error = $captcha->getError();'.PHP_EOL;
501
        $str .= '}'.PHP_EOL;
502
        $str .= '```'.PHP_EOL;
503
504
        if (in_array('notTrue', get_class_methods($class))) {
505
            $str .= "####{$this->getText(['example', 'nottrue'])}".PHP_EOL;
506
            $str .= "{$this->getText(['example', 'nottrue', 'desc'])}".PHP_EOL;
507
            $str .= '```'.PHP_EOL;
508
            $str .= '$captcha->notTrue();'.PHP_EOL;
509
            $str .= '```'.PHP_EOL;
510
        }
511
512
        if (in_array('getBalance', get_class_methods($class))) {
513
            $str .= "####{$this->getText(['example', 'balance'])}".PHP_EOL;
514
            $str .= '```'.PHP_EOL;
515
            $str .= '$balance = $captcha->getBalance();'.PHP_EOL;
516
            $str .= '```'.PHP_EOL;
517
        }
518
519
        if ($this->getText(['example', 'error', 'lang', 'if'])) {
520
            $str .= "####{$this->getText(['example', 'error', 'lang'])}".PHP_EOL;
521
            $str .= "{$this->getText(['example', 'error', 'lang', 'desc'])}".PHP_EOL;
522
            $str .= '```'.PHP_EOL;
523
            $str .= '$captcha->setErrorLang(\jumper423\decaptcha\core\DeCaptchaErrors::LANG_RU);'.PHP_EOL;
524
            $str .= '```'.PHP_EOL;
525
        }
526
527
        $str .= "####{$this->getText(['example', 'error', 'interception'])}".PHP_EOL;
528
        $str .= "{$this->getText(['example', 'error', 'interception', 'desc'])}".PHP_EOL;
529
        $str .= '```'.PHP_EOL;
530
        $str .= '$captcha->setCauseAnError(true);'.PHP_EOL;
531
        $str .= PHP_EOL;
532
        $str .= 'try {'.PHP_EOL;
533
        $str .= '    $captcha->recognize(';
534 View Code Duplication
        if ($this->texts['recognize_file']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
535
            $str .= "'{$this->getText(['recognize', 'data', 'file'])}'";
536
        }
537 View Code Duplication
        if ($this->texts['recognize_data']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538
            if ($this->texts['recognize_file']) {
539
                $str .= ', ';
540
            }
541
            $str .= '['.PHP_EOL;
542
            foreach ($this->texts['recognize_data'] as $key => $val) {
543
                $str .= "       {$rc->getShortName()}::{$this->getNameConst('ACTION_FIELD_', $key)} => ";
544
                if (is_string($val)) {
545
                    $str .= "'{$val}'";
546
                } else {
547
                    $str .= "{$val}";
548
                }
549
                $str .= ','.PHP_EOL;
550
            }
551
            $str .= '    ]';
552
        }
553
        $str .= ');'.PHP_EOL;
554
        $str .= '    $code = $captcha->getCode();'.PHP_EOL;
555
        $str .= '} catch (\jumper423\decaptcha\core\DeCaptchaErrors $e) {'.PHP_EOL;
556
        $str .= '    ...'.PHP_EOL;
557
        $str .= '}'.PHP_EOL;
558
        $str .= '```'.PHP_EOL;
559
560
        return $str;
561
    }
562
563
    protected function viewFields()
564
    {
565
        $class = $this->class;
566
        $str = " {$this->getText(['table', 'th', 'name'])} | {$this->getText(['table', 'th', 'code'])} | {$this->getText(['table', 'th', 'type'])} | {$this->getText(['table', 'th', 'req'])} | {$this->getText(['table', 'th', 'def'])} | {$this->getText(['table', 'th', 'enum'])} | {$this->getText(['table', 'th', 'desc'])} ".PHP_EOL;
567
        $str .= ' --- | --- | --- | --- | --- | --- | --- '.PHP_EOL;
568
        foreach ($this->class->actions[$class::ACTION_RECOGNIZE][$class::ACTION_FIELDS] as $param => $setting) {
569
            if (array_key_exists($class::ACTION_FIELDS, $setting) && is_array($setting[$class::ACTION_FIELDS])) {
570
                foreach ($setting[$class::ACTION_FIELDS] as $param1 => $setting1) {
571
                    if (array_key_exists($class::PARAM_SLUG_NOTWIKI, $setting1) && $setting1[$class::PARAM_SLUG_NOTWIKI] === true) {
572
                        continue;
573
                    }
574
                    $str .= $this->viewFieldLine($param1, $setting1);
575
                }
576
            }
577
            if (array_key_exists($class::PARAM_SLUG_NOTWIKI, $setting) && $setting[$class::PARAM_SLUG_NOTWIKI] === true) {
578
                continue;
579
            }
580
            $str .= $this->viewFieldLine($param, $setting);
581
        }
582
583
        return $str;
584
    }
585
586
    protected function viewFieldLine($param, $setting)
587
    {
588
        $class = $this->class;
589
        $str = " {$this->getText(['field', 'main', 'name', $param])} |";
590
        $str .= " {$this->getNameConst('ACTION_FIELD_', $param)} |";
591
        $str .= ' '.substr($this->getNameConst('PARAM_FIELD_TYPE_', $setting[$class::PARAM_SLUG_TYPE]), 17).' |';
592
        $str .= ' '.(array_key_exists($class::PARAM_SLUG_REQUIRE, $setting) ? '+' : '-').' |';
593
        $str .= ' '.(array_key_exists($class::PARAM_SLUG_DEFAULT, $setting) ? $setting[$class::PARAM_SLUG_DEFAULT] : '').' |';
594
        $str .= " {$this->getText(['field', 'slug', $class::PARAM_SLUG_ENUM, $param])} |";
595
        $str .= " {$this->getText(['field', 'main', 'desc', $param])} |";
596
        $str .= PHP_EOL;
597
598
        return $str;
599
    }
600
601
    protected function viewMenu()
602
    {
603
        $str = "+ [{$this->getText(['slug', 'menu', 'main'])}](../docs/README-{$this->lang}.md)".PHP_EOL;
604
        $str .= "+ [{$this->getText(['slug', 'menu', 'another'])}](../docs/".$this->getFileName($this->lang == 'ru' ? 'en' : 'ru').')'.PHP_EOL;
605
        $str .= "+ {$this->getText(['slug', 'menu', 'anchor'])}".PHP_EOL;
606
        foreach ([
607
                     ['slug', 'link'],
608
                     ['slug', 'service', 'desc'],
609
                     ['slug', 'price'],
610
                     ['slug', 'recognize', 'desc'],
611
                     ['install'],
612
                     ['example'],
613
                     ['slug', 'fields', 'desc'],
614
                 ] as $anchor) {
615
            $str .= "  + [{$this->getText($anchor)}](#".implode('-', explode(' ', $this->getText($anchor))).')'.PHP_EOL;
616
        }
617
        if ($this->getText(['menu', 'from_service'])) {
618
            $str .= "+ {$this->getText(['slug', 'menu', 'from_service'])}".PHP_EOL;
619
            foreach ($this->texts['menu_from_service'] as $fromServiceClass) {
620
                $fromServiceObject = new $fromServiceClass([]);
621
                $fromServiceObjectWiki = $fromServiceObject->getWiki($this->lang);
622
                $str .= "  + [{$fromServiceObjectWiki->getText(['service', 'name'])}](../docs/{$fromServiceObjectWiki->getFileName()})".PHP_EOL;
623
            }
624
        }
625
626
        return $str;
627
    }
628
629
    protected function getNameConst($keyMask, $value)
630
    {
631
        $class = $this->class;
632
        $constants = (new \ReflectionClass($class))->getConstants();
633
        foreach ($constants as $key => $val) {
634
            if (stripos($key, $keyMask) !== false && $val === $value) {
635
                return $key;
636
            }
637
        }
638
639
        return null;
640
    }
641
642
    public function view()
643
    {
644
        $str = $this->getText(['service', 'name']).PHP_EOL;
645
        $str .= '=============='.PHP_EOL;
646
        $str .= "###{$this->getText(['slug', 'menu'])}".PHP_EOL;
647
        $str .= $this->viewMenu().PHP_EOL.PHP_EOL;
648
        $str .= "###{$this->getText(['slug', 'link'])}".PHP_EOL;
649
        $str .= "[{$this->getText(['slug', 'link', 'to_service'])} {$this->getText(['service', 'name'])}]({$this->getText(['service', 'href'])})".PHP_EOL.PHP_EOL;
650
        $str .= "###{$this->getText(['slug', 'service', 'desc'])}".PHP_EOL;
651
        $str .= "{$this->getText(['service', 'desc'])}".PHP_EOL.PHP_EOL;
652
        $str .= "###{$this->getText(['slug', 'price'])}".PHP_EOL;
653
        $str .= "{$this->getText(['recognize', 'price'])}".PHP_EOL.PHP_EOL;
654
        $str .= "###{$this->getText(['slug', 'recognize', 'desc'])}".PHP_EOL;
655
        $str .= "{$this->getText(['recognize', 'desc'])}".PHP_EOL.PHP_EOL;
656
        $str .= "###{$this->getText(['install'])}".PHP_EOL;
657
        $str .= "{$this->viewInstall()}".PHP_EOL.PHP_EOL;
658
        $str .= "###{$this->getText(['example'])}".PHP_EOL;
659
        $str .= "{$this->viewExamples()}".PHP_EOL.PHP_EOL;
660
        $str .= "###{$this->getText(['slug', 'fields', 'desc'])}".PHP_EOL;
661
        $str .= $this->viewFields().PHP_EOL;
662
663
        return $str;
664
    }
665
666
    public function getFileName($lang = null)
667
    {
668
        if (is_null($lang)) {
669
            $lang = $this->lang;
670
        }
671
        $class = $this->class;
672
673
        return (new \ReflectionClass($class))->getShortName().'-'.$lang.'.md';
674
    }
675
676
    public function save()
677
    {
678
        file_put_contents(__DIR__.'/../../docs/'.$this->getFileName(), $this->view());
679
    }
680
}
681