Skip to content

Commit

Permalink
first
Browse files Browse the repository at this point in the history
  • Loading branch information
jumper423 committed Nov 28, 2016
1 parent 987edcf commit ba07335
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
/vendor
composer.lock
1 change: 1 addition & 0 deletions LICENSE
Expand Up @@ -199,3 +199,4 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

66 changes: 66 additions & 0 deletions README.md
@@ -0,0 +1,66 @@
Captcha
================
[![PHP version](https://badge.fury.io/ph/jumper423%2Fcaptcha.svg)](https://badge.fury.io/ph/jumper423%2Fcaptcha)

Распознавание капч для всех популярных сервисов [rucaptcha.com](http://infoblog1.ru/goto/rucaptcha), 2captcha.com, pixodrom.com, captcha24.com, [socialink.ru](http://www.socialink.ru/?key=84333), anti-captcha.com

Особенности
------------
* Подходит для всех сервисов по распознаванию капч работающие по общим стандартам
* Лёгкость настроки
* Распозвание как по пути до файла, так и по ссылки

Установка
------------
Предпочтительный способ установить это расширение через [composer](http://getcomposer.org/download/).

Либо запустить

```
php composer.phar require --prefer-dist jumper423/captcha "*"
```

или добавить

```
"jumper423/captchar": "*"
```

в файл `composer.json`.

Конфигурация
------------

```php
'components' => [
'captcha' => [
'class' => 'jumper423\Captcha',
'pathTmp' => '@app/captcha',
'apiKey' => '42eab4119020dbc729f657fef270r546',
],
],
```

Использование
------------
Простой пример использования:

```php
$path = 'path/to/captcha.png';
if (\Yii::$app->captcha->run($path)) {
$captcha = \Yii::$app->captcha->result();
} else {
throw new Exception(\Yii::$app->captcha->error());
}
```

Так же можно применять если у Вас есть только ссылка на капчу, но для этого метода Вам следует прописать путь в конфигурации для сохранения капч (pathTmp):

```php
$url = 'https://vk.com/captcha.php?sid=698254154192&s=1';
if (\Yii::$app->captcha->run($url)) {
$captcha = \Yii::$app->captcha->result();
} else {
throw new Exception(\Yii::$app->captcha->error());
}
```
22 changes: 22 additions & 0 deletions composer.json
@@ -0,0 +1,22 @@
{
"name": "jumper423/captcha",
"description": "Распознавание капч для всех популярных сервисов rucaptcha.com, 2captcha.com, pixodrom.com, captcha24.com, socialink.ru, anti-captcha.com",
"keywords": ["yii2", "captcha", "recognition", "rucaptcha.com", "2captcha.com", "pixodrom.com", "captcha24.com", "socialink.ru", "rucaptcha", "2captcha", "pixodrom", "captcha24", "socialink", "anti-captcha.com", "anti-captcha"],
"homepage": "http://infoblog1.ru/learn/cms/yii/raspoznavanie-kapch-na-yii2",
"type": "project",
"license": "Apache License 2.0",
"support": {
"issues": "https://github.com/jumper423/captcha/issues?state=open",
"source": "https://github.com/jumper423/captcha"
},
"minimum-stability": "stable",
"require": {
"php": ">=5.4.0"
},
"config": {
"process-timeout": 1800
},
"autoload": {
"psr-4": {"jumper423\\": "src/"}
}
}
224 changes: 224 additions & 0 deletions src/Captcha.php
@@ -0,0 +1,224 @@
<?php

namespace jumper423;

use Exception;

/**
* Распознавание капчи
*
* Class Captcha
* @package jumper423
*/
class Captcha implements CaptchaInterface
{
/**
* Сервис на который будем загружать капчу
* @var string
*/
public $domain = "rucaptcha.com";
/**
* Путь до парки временного хранения капч (необходимо если будем передавать ссылку на капчу)
* @var string
*/
public $pathTmp = 'captcha';
/**
* Ваш API key
* @var string
*/
private $apiKey;
/**
* false(commenting OFF), true(commenting ON)
* @var bool
*/
public $isVerbose = true;
/**
* Таймаут проверки ответа
* @var int
*/
public $requestTimeout = 5;
/**
* Максимальное время ожидания ответа
* @var int
*/
public $maxTimeout = 120;
/**
* 0 OR 1 - капча из двух или более слов
* @var int
*/
public $isPhrase = 0;
/**
* 0 OR 1 - регистр ответа важен
* @var int
*/
public $isRegSense = 0;
/**
* 0 OR 1 OR 2 OR 3 - 0 = параметр не задействован (значение по умолчанию) 1 = капча состоит только из цифр 2 =
* Капча состоит только из букв 3 = Капча состоит либо только из цифр, либо только из букв.
* @var int
*/
public $isNumeric = 0;
/**
* 0 если не ограничено, иначе обозначает минимальную длину ответа
* @var int
*/
public $minLen = 0;
/**
* 0 если не ограничено, иначе обозначает минимальную длину ответа
* @var int
*/
public $maxLen = 0;
/**
* 0 OR 1 OR 2 0 = параметр не задействован (значение по умолчанию) 1 = капча на кириллице 2 = капча на латинице
* @var int
*/
public $language = 0;
/**
* Ошибка
* @var null|string
*/
private $error = null;
/**
* Результат
* @var null|string
*/
private $result = null;

private $captchaId;

public function setApiKey($apiKey)
{
if (is_callable($apiKey)) {
$this->apiKey = $apiKey();
} else {
$this->apiKey = $apiKey;
}
}

/**
* Запуск распознавания капчи
*
* @param string $filename Путь до файла или ссылка на него
*
* @return bool
*/
public function run($filename)
{
$this->result = null;
$this->error = null;
try {
if (strpos($filename, 'http://') !== false || strpos($filename, 'https://') !== false) {
$current = file_get_contents($filename);
if ($current) {
$path = tempnam(sys_get_temp_dir(), 'captcha');
if (file_put_contents($path, $current)) {
$filename = $path;
} else {
throw new Exception("Нет доступа для записи файла");
}
} else {
throw new Exception("Файл {$filename} не загрузился");
}
} elseif (!file_exists($filename)) {
throw new Exception("Файл {$filename} не найден");
}
$postData = [
'method' => 'post',
'key' => $this->apiKey,
'file' => (version_compare(PHP_VERSION, '5.5.0') >= 0) ? new \CURLFile($filename) : '@' . $filename,
'phrase' => $this->isPhrase,
'regsense' => $this->isRegSense,
'numeric' => $this->isNumeric,
'min_len' => $this->minLen,
'max_len' => $this->maxLen,
'language' => $this->language,
'soft_id' => 882,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://{$this->domain}/in.php");
if (version_compare(PHP_VERSION, '5.5.0') >= 0 && version_compare(PHP_VERSION, '7.0') < 0) {
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$result = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception("CURL вернул ошибку: " . curl_error($ch));
}
curl_close($ch);
$this->setError($result);
list(, $this->captchaId) = explode("|", $result);
$waitTime = 0;
sleep($this->requestTimeout);
while (true) {
$result = file_get_contents("http://{$this->domain}/res.php?key={$this->apiKey}&action=get&id={$this->captchaId}");
$this->setError($result);
if ($result == "CAPCHA_NOT_READY") {
$waitTime += $this->requestTimeout;
if ($waitTime > $this->maxTimeout) {
break;
}
sleep($this->requestTimeout);
} else {
$ex = explode('|', $result);
if (trim($ex[0]) == 'OK') {
$this->result = trim($ex[1]);

return true;
}
}
}
throw new Exception('Лимит времени превышен');
} catch (Exception $e) {
$this->error = $e->getMessage();

return false;
}
}

/**
* Не верно распознана
*/
public function notTrue()
{
file_get_contents("http://{$this->domain}/res.php?key={$this->apiKey}&action=reportbad&id={$this->captchaId}");
}

/**
* Результат
* @return null|string
*/
public function result()
{
return $this->result;
}

/**
* Ошибка
* @return null|string
*/
public function error()
{
return $this->error;
}

/**
* Проверка на то произошла ли ошибка
*
* @param $error
*
* @throws Exception
*/
private function setError($error)
{
if (strpos($error, 'ERROR') !== false) {
if (defined(CaptchaErrors::class . '::' . $error)) {
throw new Exception(CaptchaErrors::$error);
} else {
throw new Exception($error);
}
}
}
}
41 changes: 41 additions & 0 deletions src/CaptchaErrors.php
@@ -0,0 +1,41 @@
<?php

namespace jumper423;

/**
* Ошибки
*
* Class CaptchaErrors
* @package jumper423
*/
class CaptchaErrors{
const ERROR_NO_SLOT_AVAILABLE = 'ERROR_NO_SLOT_AVAILABLE';
const ERROR_ZERO_CAPTCHA_FILESIZE = 'ERROR_ZERO_CAPTCHA_FILESIZE';
const ERROR_TOO_BIG_CAPTCHA_FILESIZE = 'ERROR_TOO_BIG_CAPTCHA_FILESIZE';
const ERROR_ZERO_BALANCE = 'ERROR_ZERO_BALANCE';
const ERROR_IP_NOT_ALLOWED = 'ERROR_IP_NOT_ALLOWED';
const ERROR_CAPTCHA_UNSOLVABLE = 'ERROR_CAPTCHA_UNSOLVABLE';
const ERROR_BAD_DUPLICATES = 'ERROR_BAD_DUPLICATES';
const ERROR_NO_SUCH_METHOD = 'ERROR_NO_SUCH_METHOD';
const ERROR_IMAGE_TYPE_NOT_SUPPORTED = 'ERROR_IMAGE_TYPE_NOT_SUPPORTED';
const ERROR_KEY_DOES_NOT_EXIST = 'ERROR_KEY_DOES_NOT_EXIST';
const ERROR_WRONG_USER_KEY = 'ERROR_WRONG_USER_KEY';
const ERROR_WRONG_ID_FORMAT = 'ERROR_WRONG_ID_FORMAT';
const ERROR_WRONG_FILE_EXTENSION = 'ERROR_WRONG_FILE_EXTENSION';

public $errorsTexts = [
self::ERROR_NO_SLOT_AVAILABLE => 'Нет свободных работников в данный момент, попробуйте позже либо повысьте свою максимальную ставку здесь',
self::ERROR_ZERO_CAPTCHA_FILESIZE => 'Размер капчи которую вы загружаете менее 100 байт',
self::ERROR_TOO_BIG_CAPTCHA_FILESIZE => 'Ваша капча имеет размер более 100 килобайт',
self::ERROR_ZERO_BALANCE => 'Нулевой либо отрицательный баланс',
self::ERROR_IP_NOT_ALLOWED => 'Запрос с этого IP адреса с текущим ключом отклонен. Пожалуйста смотрите раздел управления доступом по IP',
self::ERROR_CAPTCHA_UNSOLVABLE => 'Не смог разгадать капчу',
self::ERROR_BAD_DUPLICATES => 'Функция 100% распознавания не сработала и-за лимита попыток',
self::ERROR_NO_SUCH_METHOD => 'Вы должны слать параметр method в вашем запросе к API, изучите документацию',
self::ERROR_IMAGE_TYPE_NOT_SUPPORTED => 'Невозможно определить тип файла капчи, принимаются только форматы JPG, GIF, PNG',
self::ERROR_KEY_DOES_NOT_EXIST => 'Использован несуществующий key',
self::ERROR_WRONG_USER_KEY => 'Неверный формат параметра key, должно быть 32 символа',
self::ERROR_WRONG_ID_FORMAT => 'Неверный формат ID каптчи. ID должен содержать только цифры',
self::ERROR_WRONG_FILE_EXTENSION => 'Ваша каптча имеет неверное расширение, допустимые расширения jpg,jpeg,gif,png',
];
}
12 changes: 12 additions & 0 deletions src/CaptchaInterface.php
@@ -0,0 +1,12 @@
<?php

namespace jumper423;

interface CaptchaInterface
{
public function run($filename);

public function result();

public function error();
}

0 comments on commit ba07335

Please sign in to comment.