Добавлен LongPoll. Переработка ядра, переработка сборщика, переработка сообщений.
This commit is contained in:
parent
48946d9070
commit
ce92d44b8b
|
@ -1,3 +1,4 @@
|
||||||
/logs
|
/logs
|
||||||
|
/temp
|
||||||
/vendor
|
/vendor
|
||||||
.env
|
.env
|
File diff suppressed because it is too large
Load Diff
|
@ -4,75 +4,268 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\API;
|
namespace VK\API;
|
||||||
|
|
||||||
class LongPoll extends LongPollAbstract
|
use \Exception;
|
||||||
|
use \VK\Core,
|
||||||
|
\VK\Robots\RobotAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LongPoll
|
||||||
|
*
|
||||||
|
* @property string $key Ключ к серверу
|
||||||
|
* @property string $server Сервер
|
||||||
|
* @property string $ts Идентификатор последнего события
|
||||||
|
*
|
||||||
|
* @method public function __construct(object $robot) Инициализация
|
||||||
|
* @method public function get(int $wait = 25) Получить события
|
||||||
|
* @method public function handle(callable $function, int $wait = 25) Обработать события
|
||||||
|
*
|
||||||
|
* @see https://vk.com/dev/bots_longpoll
|
||||||
|
* @see https://vk.com/dev/groups.getLongPollServer
|
||||||
|
* @see https://vk.com/dev/groups.setLongPollSettings
|
||||||
|
*
|
||||||
|
* @package VK\API\LongPoll
|
||||||
|
* @author Арсен Мирзаев <red@hood.su>
|
||||||
|
*
|
||||||
|
* @todo Добавить обработку ошибок ($request['errors];)
|
||||||
|
*/
|
||||||
|
class LongPoll
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Объект взаимодействия лонгпола
|
* Робот
|
||||||
*
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
private $robot;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Тип объекта: пользователь или группа
|
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $auth_type;
|
private RobotAbstract $robot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ключ сессии
|
* Ключ к серверу
|
||||||
|
*
|
||||||
|
* @see $this->get()
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $key;
|
private string $key;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $group_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $ts;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Сервер (URL)
|
||||||
|
*
|
||||||
|
* @see $this->get()
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $server;
|
private string $server;
|
||||||
|
|
||||||
public function __construct(object $robot, array $params = [])
|
/**
|
||||||
|
* Идентификатор последнего события
|
||||||
|
*
|
||||||
|
* От него отсчитываются новые, необработанные события
|
||||||
|
*
|
||||||
|
* @see $this->get()
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private string $ts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Инициализация
|
||||||
|
*
|
||||||
|
* @param object $robot Робот
|
||||||
|
*/
|
||||||
|
public function __construct(object $robot)
|
||||||
{
|
{
|
||||||
|
// Инициализация робота
|
||||||
|
if (!$robot->id) {
|
||||||
|
throw new Exception('Роботу необходимо задать идентификатор ВКонтакте');
|
||||||
|
}
|
||||||
|
if (!$robot->token) {
|
||||||
|
throw new Exception('Роботу необходимо задать токен для доступа к LongPoll');
|
||||||
|
}
|
||||||
|
if (!$robot->version) {
|
||||||
|
throw new Exception('Роботу необходимо задать версию используемого API ВКонтакте');
|
||||||
|
}
|
||||||
$this->robot = $robot;
|
$this->robot = $robot;
|
||||||
if ($_ENV['ROBOT_TYPE']) {
|
|
||||||
$this->robot->auth_type = 'user';
|
// Остановка процессов-дубликатов
|
||||||
$this->user_id = $this->robot->request('users.get', [])['id'];
|
if (!file_exists(Core::init()->path['temp'])) {
|
||||||
} else {
|
// Если не существует каталога temp, то создать
|
||||||
$this->robot->auth_type = 'group';
|
mkdir(Core::init()->path['temp'], 0775, true);
|
||||||
$this->group_id = $this->robot->request('groups.getById', [])['id'];
|
}
|
||||||
$this->robot->request('groups.setLongPollSettings', [
|
if (file_exists($lock = Core::init()->path['temp'] . '/' . $this->robot->id . '_' . (int) $this->robot->session . '.longpoll')) {
|
||||||
'group_id' => $this->group_id,
|
// Если существует файл-блокировщик, то удалить его
|
||||||
'enabled' => 1,
|
unlink($lock);
|
||||||
'api_version' => $this->robot->version,
|
|
||||||
'message_new' => 1,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
$this->getLongPollServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLongPollServer()
|
/**
|
||||||
|
* Установить настройки
|
||||||
|
*
|
||||||
|
* Полная настройка и активация LongPoll
|
||||||
|
*
|
||||||
|
* @param bool $status = true Активация или деактивация
|
||||||
|
* @param string ...$params Изменяемые параметры
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function post(bool $status = true, string ...$params): array
|
||||||
{
|
{
|
||||||
if ($this->robot->auth_type == 'user') {
|
// Инициализация настроек
|
||||||
$data = $this->robot->request('messages.getLongPollServer', ['need_pts' => 1, 'lp_version' => 3]);
|
$settings = [
|
||||||
} else {
|
'group_id' => $this->robot->id,
|
||||||
$data = $this->robot->request('groups.getLongPollServer', ['group_id' => $this->group_id]);
|
'access_token' => $this->robot->token,
|
||||||
|
'v' => $this->robot->version,
|
||||||
|
'api_version' => $this->robot->version
|
||||||
|
];
|
||||||
|
|
||||||
|
// Установка переданных параметров
|
||||||
|
foreach ($params as $param) {
|
||||||
|
if ($param === 'group_id' || $param === 'access_token' || $param === 'v' || $param === 'api_version') {
|
||||||
|
// Блокировка параметров от изменения
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
list($this->key, $this->server, $this->ts) = [$data['key'], $data['server'], $data['ts']];
|
|
||||||
|
if ($status === true && !array_key_exists('enabled', $settings)) {
|
||||||
|
// Если запущена активация и не был передан параметр статуса LongPoll
|
||||||
|
|
||||||
|
// Установка параметра активации LongPoll
|
||||||
|
$settings['enabled'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = (int) $status;
|
||||||
|
|
||||||
|
if ($param === 'all') {
|
||||||
|
// Если передан параметр: установка ВСЕХ значений
|
||||||
|
$settings['message_new'] = $status;
|
||||||
|
$settings['message_reply'] = $status;
|
||||||
|
$settings['message_allow'] = $status;
|
||||||
|
$settings['message_deny'] = $status;
|
||||||
|
$settings['message_edit'] = $status;
|
||||||
|
$settings['message_typing_state'] = $status;
|
||||||
|
$settings['photo_new'] = $status;
|
||||||
|
$settings['audio_new'] = $status;
|
||||||
|
$settings['video_new'] = $status;
|
||||||
|
$settings['wall_reply_new'] = $status;
|
||||||
|
$settings['wall_reply_edit'] = $status;
|
||||||
|
$settings['wall_reply_delete'] = $status;
|
||||||
|
$settings['wall_reply_restore'] = $status;
|
||||||
|
$settings['wall_post_new'] = $status;
|
||||||
|
$settings['wall_repost'] = $status;
|
||||||
|
$settings['board_post_new'] = $status;
|
||||||
|
$settings['board_post_edit'] = $status;
|
||||||
|
$settings['board_post_restore'] = $status;
|
||||||
|
$settings['board_post_delete'] = $status;
|
||||||
|
$settings['photo_comment_new'] = $status;
|
||||||
|
$settings['photo_comment_edit'] = $status;
|
||||||
|
$settings['photo_comment_delete'] = $status;
|
||||||
|
$settings['photo_comment_restore'] = $status;
|
||||||
|
$settings['video_comment_new'] = $status;
|
||||||
|
$settings['video_comment_edit'] = $status;
|
||||||
|
$settings['video_comment_delete'] = $status;
|
||||||
|
$settings['video_comment_restore'] = $status;
|
||||||
|
$settings['market_comment_new'] = $status;
|
||||||
|
$settings['market_comment_edit'] = $status;
|
||||||
|
$settings['market_comment_delete'] = $status;
|
||||||
|
$settings['market_comment_restore'] = $status;
|
||||||
|
$settings['poll_vote_new'] = $status;
|
||||||
|
$settings['group_join'] = $status;
|
||||||
|
$settings['group_leave'] = $status;
|
||||||
|
$settings['group_change_settings'] = $status;
|
||||||
|
$settings['group_change_photo'] = $status;
|
||||||
|
$settings['group_officers_edit'] = $status;
|
||||||
|
$settings['user_block'] = $status;
|
||||||
|
$settings['user_unblock'] = $status;
|
||||||
|
$settings['like_add'] = $status;
|
||||||
|
$settings['like_remove'] = $status;
|
||||||
|
$settings['message_event'] = $status;
|
||||||
|
} else {
|
||||||
|
// Иначе
|
||||||
|
|
||||||
|
// Установка значения
|
||||||
|
$settings[$param] = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->robot->browser()->api('groups.setLongPollSettings', $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить события
|
||||||
|
*
|
||||||
|
* @param int $wait Время ожидания новых событий (в секундах)
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get(int $wait = 25): array
|
||||||
|
{
|
||||||
|
if (empty($this->key) || empty($this->server) || empty($this->ts)) {
|
||||||
|
// Если не инициализирован LongPoll-сервер
|
||||||
|
|
||||||
|
// Запрос на получение доступа и данных LongPoll-сервера
|
||||||
|
$response = $this->robot->browser()->api('groups.getLongPollServer', [
|
||||||
|
'group_id' => $this->robot->id,
|
||||||
|
'access_token' => $this->robot->token,
|
||||||
|
'v' => $this->robot->version
|
||||||
|
])['response'];
|
||||||
|
|
||||||
|
// Ключ доступа
|
||||||
|
$this->key = $response['key'];
|
||||||
|
|
||||||
|
// Сервер хранящий события
|
||||||
|
$this->server = $response['server'];
|
||||||
|
|
||||||
|
// Идентификатор последнего события
|
||||||
|
$this->ts = $response['ts'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запрос на получение событий
|
||||||
|
return $this->robot->browser()->post($this->server . '?act=a_check&key=' . $this->key . '&ts=' . $this->ts . '&wait=' . $wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обработать события
|
||||||
|
*
|
||||||
|
* Получает и обрабатывает события
|
||||||
|
*
|
||||||
|
* @param callable $function Обработка
|
||||||
|
* @param int $wait Время ожидания новых событий (в секундах)
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function handle(callable $function, int $wait = 25): array
|
||||||
|
{
|
||||||
|
// Файл-блокировщик и PID процесса
|
||||||
|
$lock = Core::init()->path['temp'] . '/' . $this->robot->id . '_' . (int) $this->robot->session . '.longpoll';
|
||||||
|
$pid = getmypid();
|
||||||
|
|
||||||
|
// Создание или пересоздание файла-блокировщика
|
||||||
|
file_put_contents($lock, $pid);
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Выполняется пока существует файл-блокировщик
|
||||||
|
|
||||||
|
// Запрос на получение событий
|
||||||
|
$request = $this->get($wait);
|
||||||
|
|
||||||
|
// [ВНИМАНИЕ] Соединение будет открыто даже при создании нового процесса LongPoll
|
||||||
|
|
||||||
|
if (!file_exists($lock) || (int) fread(fopen($lock, 'r'), filesize($lock)) !== $pid) {
|
||||||
|
// Проверка существования файла-блокировщика и соответствие его PID
|
||||||
|
|
||||||
|
// Завершение работы
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($request['response']['updates'])) {
|
||||||
|
// Если получены необработанные события
|
||||||
|
|
||||||
|
// Обработка событий
|
||||||
|
$function($request['response']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Новый идентификатор последнего события
|
||||||
|
$this->ts = $request['response']['ts'];
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
return $request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace VK\API;
|
|
||||||
|
|
||||||
abstract class LongPollAbstract
|
|
||||||
{
|
|
||||||
abstract public function __construct(object $robot, array $params = []);
|
|
||||||
abstract public function getRobotInfo();
|
|
||||||
}
|
|
|
@ -4,43 +4,76 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\API\Methods;
|
namespace VK\API\Methods;
|
||||||
|
|
||||||
use \VK\Core;
|
use \Exception;
|
||||||
use \VK\API\Traits\Request;
|
use \VK\Core,
|
||||||
use \VK\Robots\RobotAbstract;
|
\VK\Robots\RobotAbstract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сообщение
|
||||||
|
*
|
||||||
|
* Отправляет сообщение
|
||||||
|
*
|
||||||
|
* @method public static function put(RobotAbstract $from, int $to, string $message, int $mode = 2) Отправить сообщение
|
||||||
|
*
|
||||||
|
* @see https://vk.com/dev/messages.send
|
||||||
|
* @see https://vk.com/dev/messages.getById
|
||||||
|
*
|
||||||
|
* @package VK\API\Methods\Message
|
||||||
|
* @author Арсен Мирзаев <red@hood.su>
|
||||||
|
*
|
||||||
|
* @todo Добавить обработку ошибок ($request['errors];)
|
||||||
|
*/
|
||||||
class Message
|
class Message
|
||||||
{
|
{
|
||||||
use Request;
|
/**
|
||||||
|
* Отправить сообщение
|
||||||
private const METHOD = 'messages.send';
|
*
|
||||||
|
* @param $from Экземпляр робота
|
||||||
public static function post($from, int $to, string $message, int $trolling)
|
* @param int $to Идентификатор получателя
|
||||||
|
* @param string $message Текст сообщения
|
||||||
|
* @param int $mode Режим доставки сообщения
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function put(RobotAbstract $from, int $to, string $message, int $mode = 2): array
|
||||||
{
|
{
|
||||||
if (is_int($from)) {
|
$random_id = time();
|
||||||
// Если получен идентификатор, а не экземпляр RobotAbstract
|
$check = false;
|
||||||
|
|
||||||
// Поиск в регистре
|
// Режим доставки сообщений (усложнение по возрастанию)
|
||||||
$from = Core::init()->get($from);
|
if ($mode >= 1) {
|
||||||
|
// Дополнительное умножение
|
||||||
|
$random_id *= rand();
|
||||||
|
|
||||||
|
if ($mode >= 2) {
|
||||||
|
// Проверка отправки (по умолчанию)
|
||||||
|
$check = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Параметры
|
// Запрос: отправить сообщение
|
||||||
$params = [
|
$request = $from->browser()->api('messages.send', [
|
||||||
'message' => $message,
|
|
||||||
'peer_id' => $to,
|
|
||||||
'access_token' => $from->token,
|
'access_token' => $from->token,
|
||||||
'v' => $from->version,
|
'v' => $from->version,
|
||||||
'random_id' => $trolling
|
'peer_id' => $to,
|
||||||
];
|
'message' => $message,
|
||||||
|
'random_id' => $random_id
|
||||||
|
]);
|
||||||
|
|
||||||
// Запрос
|
if ($check) {
|
||||||
self::request(self::METHOD, $params, $from->getBrowser());
|
// Если активирована проверка отправленного сообщения
|
||||||
|
|
||||||
|
// Запрос: получить сообщение по ID
|
||||||
|
if ($from->browser()->api('messages.getById', [
|
||||||
|
'access_token' => $from->token,
|
||||||
|
'v' => $from->version,
|
||||||
|
'message_ids' => is_int($request["response"]) ? $request["response"] : $request["response"]['message_id']
|
||||||
|
])['response']['count'] === 0) {
|
||||||
|
// Если сообщения не существует, то повтор
|
||||||
|
self::put($from, $to, $message, $mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get()
|
return $request;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function delete()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,56 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\API\Methods;
|
namespace VK\API\Methods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Абстракция метода API
|
||||||
|
*
|
||||||
|
* @method protected static put(string $url, ...$params) Создать
|
||||||
|
* @method protected static post(string $url, ...$params) Изменить
|
||||||
|
* @method protected static get(string $url, ...$params) Получить
|
||||||
|
* @method protected static delete(string $url, ...$params) Удалить
|
||||||
|
*
|
||||||
|
* @package VK\API\Methods
|
||||||
|
* @author Арсен Мирзаев <red@hood.su>
|
||||||
|
*/
|
||||||
abstract class MethodAbstract
|
abstract class MethodAbstract
|
||||||
{
|
{
|
||||||
abstract public static function post();
|
/**
|
||||||
abstract public static function get();
|
* Создать
|
||||||
abstract public static function delete();
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function put(): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Изменить
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function post(): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function get(): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удалить
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function delete(): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace VK\API\Traits;
|
|
||||||
|
|
||||||
use VK\Browsers\BrowserAbstract;
|
|
||||||
use Exception;
|
|
||||||
/**
|
|
||||||
* Паттерн registry
|
|
||||||
*/
|
|
||||||
trait Request
|
|
||||||
{
|
|
||||||
private static function request(string $method, array $params, BrowserAbstract $browser)
|
|
||||||
{
|
|
||||||
$url = 'https://api.vk.com/method/' . $method;
|
|
||||||
|
|
||||||
foreach ($params as $key => $value) {
|
|
||||||
$post[$key] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// while (True) {
|
|
||||||
// try {
|
|
||||||
return $browser::post($url, $post);
|
|
||||||
// } catch (Exception $e) {
|
|
||||||
// // if (in_array($e->getCode(), $this->request_ignore_error)) {
|
|
||||||
// // sleep(1);
|
|
||||||
// // continue;
|
|
||||||
// // } else
|
|
||||||
// // throw new Exception($e->getMessage(), $e->getCode());
|
|
||||||
// throw new Exception('Жопа');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,9 +4,108 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\Browsers;
|
namespace VK\Browsers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Абстракция браузера
|
||||||
|
*
|
||||||
|
* @method public static api(string $method, ...$params) Запрос к API ВКонтакте
|
||||||
|
* @method protected static put(string $url, ...$params) Создать
|
||||||
|
* @method protected static post(string $url, ...$params) Изменить
|
||||||
|
* @method protected static get(string $url, ...$params) Получить
|
||||||
|
* @method protected static delete(string $url, ...$params) Удалить
|
||||||
|
*
|
||||||
|
* @package Browsers
|
||||||
|
* @author Arsen Mirzaev
|
||||||
|
*/
|
||||||
abstract class BrowserAbstract
|
abstract class BrowserAbstract
|
||||||
{
|
{
|
||||||
abstract public static function post($method, $params = []);
|
/**
|
||||||
abstract public static function getToken($url);
|
* Запрос к VK API
|
||||||
abstract protected static function checkSSL($domain);
|
*
|
||||||
|
* @param string $method Метод VK API
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function api(string $method, array $params): array
|
||||||
|
{
|
||||||
|
$url = 'https://api.vk.com/method/' . $method;
|
||||||
|
|
||||||
|
// while (True) {
|
||||||
|
// try {
|
||||||
|
return $this->post($url, $params);
|
||||||
|
// } catch (Exception $e) {
|
||||||
|
// // if (in_array($e->getCode(), $this->request_ignore_error)) {
|
||||||
|
// // sleep(1);
|
||||||
|
// // continue;
|
||||||
|
// // } else
|
||||||
|
// // throw new Exception($e->getMessage(), $e->getCode());
|
||||||
|
// throw new Exception('Жопа');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создать
|
||||||
|
*
|
||||||
|
* Для запросов на создание (REST)
|
||||||
|
* Реализация HTTP PUT
|
||||||
|
*
|
||||||
|
* @param string $url Запрашиваемая ссылка
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function put(string $url, array $params = null): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Изменить
|
||||||
|
*
|
||||||
|
* Для запросов на изменение (REST)
|
||||||
|
* Реализация HTTP POST
|
||||||
|
*
|
||||||
|
* @param string $url Запрашиваемая ссылка
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function post(string $url, array $params = null): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить
|
||||||
|
*
|
||||||
|
* Для запросов на получение (REST)
|
||||||
|
* Реализация HTTP GET
|
||||||
|
*
|
||||||
|
* @param string $url Запрашиваемая ссылка
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function get(string $url, array $params = null): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удалить
|
||||||
|
*
|
||||||
|
* Для запросов на удаление (REST)
|
||||||
|
* Реализация HTTP DELETE
|
||||||
|
*
|
||||||
|
* @param string $url Запрашиваемая ссылка
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
|
*/
|
||||||
|
public static function delete(string $url, array $params = null): array
|
||||||
|
{
|
||||||
|
return ['error' => 'Метод не поддерживается'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,92 +6,49 @@ namespace VK\Browsers;
|
||||||
|
|
||||||
use VK\Core;
|
use VK\Core;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
/**
|
||||||
|
* Реализация CURL
|
||||||
|
*
|
||||||
|
* @method protected static put(string $url, ...$params) Создать
|
||||||
|
*
|
||||||
|
* @package Browsers
|
||||||
|
* @author Arsen Mirzaev
|
||||||
|
*/
|
||||||
class Curl extends BrowserAbstract
|
class Curl extends BrowserAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* SSL шифрование
|
* Изменить
|
||||||
*
|
*
|
||||||
* @var bool
|
* Для запросов на изменение (REST)
|
||||||
|
* Реализация HTTP POST
|
||||||
|
*
|
||||||
|
* @param string $url Запрашиваемая ссылка
|
||||||
|
* @param array $params Передаваемые параметры
|
||||||
|
*
|
||||||
|
* @return array Ответ сервера
|
||||||
*/
|
*/
|
||||||
private static bool $ssl = false;
|
public static function post(string $url, array $params = null): array
|
||||||
|
|
||||||
public static function post($url, $params = [])
|
|
||||||
{
|
{
|
||||||
$c = curl_init();
|
$c = curl_init();
|
||||||
curl_setopt($c, CURLOPT_HTTPHEADER, [
|
curl_setopt($c, CURLOPT_HTTPHEADER, [
|
||||||
"Content-Type:multipart/form-data"
|
'Content-Type: multipart/form-data'
|
||||||
]);
|
]);
|
||||||
curl_setopt($c, CURLOPT_URL, $url);
|
curl_setopt($c, CURLOPT_URL, $url);
|
||||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
|
||||||
curl_setopt($c, CURLOPT_POSTFIELDS, $params);
|
curl_setopt($c, CURLOPT_POSTFIELDS, $params);
|
||||||
|
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 0);
|
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
|
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
|
||||||
$result = json_decode(curl_exec($c), True);
|
$result = json_decode(curl_exec($c), True);
|
||||||
curl_close($c);
|
curl_close($c);
|
||||||
|
|
||||||
if (isset($result['response']))
|
if (isset($result['response'])) {
|
||||||
return $result['response'];
|
|
||||||
else if (isset($result['error']))
|
|
||||||
throw new Exception(json_encode($result), $result['error']['error_code']);
|
|
||||||
else if (!isset($result))
|
|
||||||
self::post($url, $params);
|
|
||||||
else
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
} else if (isset($result['error'])) {
|
||||||
|
throw new Exception(json_encode($result), $result['error']['error_code']);
|
||||||
public static function getToken($url)
|
} else if (!isset($result)) {
|
||||||
{
|
self::post($url, $params);
|
||||||
if (!self::checkSSL('localhost')) {
|
} else {
|
||||||
$core = Core::init();
|
return ['response' => $result];
|
||||||
$core->logger->notice('Соединение не защищено. Необходимо включить SSL шифрование');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($curl = curl_init()) {
|
|
||||||
curl_setopt($curl, CURLOPT_URL, $url);
|
|
||||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
|
|
||||||
curl_setopt($curl, CURLOPT_USERAGENT, $_ENV['USERAGENT']);
|
|
||||||
if (isset($post_values)) {
|
|
||||||
curl_setopt($curl, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_values);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($cookie and isset(self::$cookie)) {
|
|
||||||
$send_cookie = [];
|
|
||||||
foreach (self::$cookie as $cookie_name => $cookie_val) {
|
|
||||||
$send_cookie[] = "$cookie_name=$cookie_val";
|
|
||||||
}
|
|
||||||
curl_setopt($curl, CURLOPT_COOKIE, join('; ', $send_cookie));
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_setopt(
|
|
||||||
$curl,
|
|
||||||
CURLOPT_HEADERFUNCTION,
|
|
||||||
function ($curl, $header) use (&$headers) {
|
|
||||||
$len = strlen($header);
|
|
||||||
$header = explode(':', $header, 2);
|
|
||||||
if (count($header) < 2) // ignore invalid headers
|
|
||||||
return $len;
|
|
||||||
|
|
||||||
$name = strtolower(trim($header[0]));
|
|
||||||
if (isset($headers) and !array_key_exists($name, $headers))
|
|
||||||
$headers[$name] = [trim($header[1])];
|
|
||||||
else
|
|
||||||
$headers[$name][] = trim($header[1]);
|
|
||||||
|
|
||||||
return $len;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$out = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
//if (isset($headers['set-cookie']))
|
|
||||||
// $this->parseCookie($headers['set-cookie']);
|
|
||||||
return ['header' => $headers, 'body' => $out];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,118 +4,108 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK;
|
namespace VK;
|
||||||
|
|
||||||
use \Exception;
|
use \VK\Core,
|
||||||
use \VK\Core;
|
\VK\Robots\RobotAbstract,
|
||||||
use \VK\BuildAbstract;
|
\VK\Robots\Group,
|
||||||
use \VK\Robots\RobotAbstract;
|
\VK\Robots\User,
|
||||||
use \VK\Robots\Group;
|
\VK\Loggers\Jasmo;
|
||||||
use \VK\Robots\User;
|
|
||||||
use \VK\Browsers\BrowserAbstract;
|
|
||||||
use \VK\Proxies\ProxyAbstract;
|
|
||||||
use \VK\Captchas\CaptchaAbstract;
|
|
||||||
use \VK\Loggers\Jasmo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сборщик
|
* Сборщик
|
||||||
*
|
*
|
||||||
* @package Builder
|
* @property Core $core Ядро
|
||||||
*
|
*
|
||||||
* @method public group() Создание робота-группы
|
* @method public function __construct(Core $core = null) Инициализация
|
||||||
* @method public user() Создание робота-пользователя
|
* @method public function group() Создание робота-группы
|
||||||
|
* @method public function user() Создание робота-пользователя
|
||||||
|
* @method private function reg() Регистрация в ядре
|
||||||
|
* @method public function log(string $file = null) Журналирование
|
||||||
*
|
*
|
||||||
* @method private reg() Регистрация в ядре
|
* @package VK\Builder
|
||||||
*
|
* @author Arsen Mirzaev <red@hood.su>
|
||||||
* @author Arsen Mirzaev
|
|
||||||
*/
|
*/
|
||||||
class Builder
|
class Builder
|
||||||
{
|
{
|
||||||
public function __construct()
|
/**
|
||||||
|
* Инициализация
|
||||||
|
*
|
||||||
|
* @param Core $core Ядро
|
||||||
|
*/
|
||||||
|
public function __construct(Core $core = null)
|
||||||
{
|
{
|
||||||
return $this;
|
if (isset($core)) {
|
||||||
|
$this->core = $core::init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создание робота-группы
|
* Создание робота-группы
|
||||||
*
|
*
|
||||||
|
* @param int $id Идентификатор
|
||||||
|
*
|
||||||
* @return Group
|
* @return Group
|
||||||
*/
|
*/
|
||||||
public function group(): Group
|
public function group(int $id): Group
|
||||||
{
|
{
|
||||||
return $this->reg(new \VK\Robots\Group());
|
// Создание робота
|
||||||
|
$robot = new Group();
|
||||||
|
|
||||||
|
// Идентификатор
|
||||||
|
$robot->id = $id;
|
||||||
|
|
||||||
|
// Сессия
|
||||||
|
$robot->session = isset($this->core) ? count($this->core->get($id)) : 0;
|
||||||
|
|
||||||
|
return isset($this->core) ? $this->reg($robot) : $robot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создание робота-пользователя
|
* Создание робота-пользователя
|
||||||
*
|
*
|
||||||
|
* @param int $id Идентификатор
|
||||||
|
*
|
||||||
* @return User
|
* @return User
|
||||||
*/
|
*/
|
||||||
public function user(): User
|
public function user(): User
|
||||||
{
|
{
|
||||||
return $this->reg(new \VK\Robots\User());
|
return $this->reg(new User());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрация в ядре
|
* Регистрация в ядре
|
||||||
*
|
*
|
||||||
|
* @param RobotAbstract $robot Регистрируемый робот
|
||||||
|
*
|
||||||
* @return RobotAbstract
|
* @return RobotAbstract
|
||||||
*
|
*
|
||||||
* @todo Добавить создание нового процесса (многопоточность)
|
* @todo Добавить создание нового процесса (многопоточность)
|
||||||
*/
|
*/
|
||||||
private function reg(RobotAbstract $robot): RobotAbstract
|
private function reg(RobotAbstract $robot): RobotAbstract
|
||||||
{
|
{
|
||||||
// Присвоение идентификатора
|
|
||||||
$robot->id = ++Core::$robots;
|
|
||||||
|
|
||||||
// Регистрация в ядре
|
// Регистрация в ядре
|
||||||
Core::set($robot->id, $robot);
|
$this->core->set((int) $robot->id, $robot);
|
||||||
|
|
||||||
|
// Количество роботов
|
||||||
|
++$this->core->robots;
|
||||||
|
|
||||||
return $robot;
|
return $robot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка журналирования
|
* Журналирование
|
||||||
*
|
*
|
||||||
* @return RobotAbstract
|
* @param string $file Файл для журналирования
|
||||||
|
*
|
||||||
|
* @return Builder
|
||||||
*
|
*
|
||||||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
||||||
|
* @todo Более гибкое журналирование
|
||||||
*/
|
*/
|
||||||
public function log($file = null): Builder
|
public function log(string $file = null): Builder
|
||||||
{
|
{
|
||||||
|
// Инициализация журналиста (требует переработки)
|
||||||
Jasmo::init()::post($file)::postErrorHandler()::postShutdownHandler();
|
Jasmo::init()::post($file)::postErrorHandler()::postShutdownHandler();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Установка браузера
|
|
||||||
*
|
|
||||||
* @return RobotAbstract
|
|
||||||
*/
|
|
||||||
public function browser(BrowserAbstract $browser): Builder
|
|
||||||
{
|
|
||||||
$this->browser = $browser;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Установка прокси
|
|
||||||
*
|
|
||||||
* @return RobotAbstract
|
|
||||||
*/
|
|
||||||
public function proxy(ProxyAbstract $proxy): Builder
|
|
||||||
{
|
|
||||||
$this->proxy = $proxy;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Установка обработчика капч
|
|
||||||
*
|
|
||||||
* @return RobotAbstract
|
|
||||||
*/
|
|
||||||
public function captcha(CaptchaAbstract $captcha): Builder
|
|
||||||
{
|
|
||||||
$this->captcha = $captcha;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,27 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK;
|
namespace VK;
|
||||||
|
|
||||||
use \VK\Loggers\Jasmo;
|
use \VK\Builder,
|
||||||
use \VK\Traits\Singleton;
|
\VK\Loggers\Jasmo,
|
||||||
use \VK\Traits\Registry;
|
\VK\Traits\Singleton,
|
||||||
|
\VK\Traits\Registry,
|
||||||
|
\VK\Robots\RobotAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ядро фреймворка для работы с VK API
|
* Ядро
|
||||||
|
*
|
||||||
|
* @property int $robots Количество роботов
|
||||||
|
* @property string $timezone Временная зона (журналирование)
|
||||||
|
* @property array $path Пути (архитектура проекта)
|
||||||
|
*
|
||||||
|
* @method protected static function __construct() Инициализация
|
||||||
|
* @method public static function init() Запуск инициализации или получение инстанции
|
||||||
|
* @method public public function build() Сборщик
|
||||||
|
* @method public function set($id, $value) Запись в реестр
|
||||||
|
* @method public function get($id = null) Чтение из реестра
|
||||||
*
|
*
|
||||||
* @package VK
|
* @package VK
|
||||||
*
|
* @author Арсен Мирзаев <red@hood.su>
|
||||||
* @property int robots Количество роботов
|
|
||||||
*
|
|
||||||
* @method build(...$params) Инициализация сборщика
|
|
||||||
*
|
|
||||||
* @author Arsen Mirzaev
|
|
||||||
*/
|
*/
|
||||||
class Core
|
class Core
|
||||||
{
|
{
|
||||||
|
@ -32,7 +39,7 @@ class Core
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
public static int $robots = 0;
|
public int $robots = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Временная зона
|
* Временная зона
|
||||||
|
@ -41,7 +48,7 @@ class Core
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public static string $timezone = 'Europe/Moscow';
|
public string $timezone = 'Europe/Moscow';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Пути
|
* Пути
|
||||||
|
@ -50,39 +57,52 @@ class Core
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static array $path = [
|
public array $path = [
|
||||||
'root' => '',
|
'root' => '',
|
||||||
'log' => ''
|
'logs' => './logs',
|
||||||
|
'temp' => './temp'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected function __construct() {
|
/**
|
||||||
self::$path = [
|
* Инициализация
|
||||||
'root' => dirname(__DIR__) . '..',
|
*
|
||||||
'log' => self::$path['root'] . '/log'
|
* @see Singleton->__construct() Внимание на protected
|
||||||
];
|
*/
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$this->path['root'] = $root = dirname(__DIR__);
|
||||||
|
$this->path['logs'] = $root . '/logs';
|
||||||
|
$this->path['temp'] = $root . '/temp';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Инициализация сборщика
|
* Сборщик
|
||||||
*
|
*
|
||||||
* @return Builder
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public function build(): Builder
|
public function build(): Builder
|
||||||
{
|
{
|
||||||
return new Builder();
|
return new Builder($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Активация журналирования
|
* Запись в реестр
|
||||||
*
|
*
|
||||||
* @return Core
|
* Модификация наследуемого метода
|
||||||
*
|
*
|
||||||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
* @param mixed $id
|
||||||
|
* @param mixed $robot
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function log($file = null): Core
|
public static function set(int $id, RobotAbstract $robot): bool
|
||||||
{
|
{
|
||||||
Jasmo::init()::post($file)::postErrorHandler()::postShutdownHandler();
|
if (empty(self::$registry[$id])) {
|
||||||
|
self::$registry[$id] = [];
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
array_push(self::$registry[$id], $robot);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,64 +4,92 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\Robots;
|
namespace VK\Robots;
|
||||||
|
|
||||||
use VK\Browsers\BrowserAbstract;
|
use \VK\Browsers\BrowserAbstract,
|
||||||
use VK\Parsers\Curl;
|
\VK\API\Methods\Message,
|
||||||
use Exception;
|
\VK\API\LongPoll;
|
||||||
use VK\API\LongPoll;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Робот: "Группа"
|
* Робот-группа ВКонтакте
|
||||||
*
|
*
|
||||||
* Класс реализовывающий работу от лица группы ВКонтакте
|
* Класс реализовывающий работу от лица группы ВКонтакте
|
||||||
*
|
*
|
||||||
* @package Robots
|
* @property LongPoll $longpoll LongPoll-сессия
|
||||||
* @author Arsen Mirzaev
|
*
|
||||||
|
* @method public function message(int $to, string $message, int $mode = 2) Отправить сообщение
|
||||||
|
* @method public function __set($name, $value) Магический метод-сеттер
|
||||||
|
* @method public function __get($name) Магический метод-геттер
|
||||||
|
*
|
||||||
|
* @package VK\Robots\Group
|
||||||
|
* @author Arsen Mirzaev <red@hood.su>
|
||||||
|
*
|
||||||
|
* @todo Вместо методов реализовать фабрику методов API, как было раньше
|
||||||
*/
|
*/
|
||||||
class Group extends RobotAbstract
|
class Group extends RobotAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* ВКонтакте: тип API
|
* LongPoll-сессия
|
||||||
*
|
*
|
||||||
* @var string
|
* @var LongPoll
|
||||||
*/
|
*/
|
||||||
public string $api;
|
protected LongPoll $longpoll;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ВКонтакте: активатор мобильной версии
|
* Отправить сообщение
|
||||||
*
|
*
|
||||||
* @var bool
|
* @param int $to Идентификатор получателя
|
||||||
|
* @param string $message Текст сообщения
|
||||||
|
* @param int $mode Режим доставки сообщения
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
//protected bool $mobile = false;
|
public function message(int $to, string $message, int $mode = 2): array
|
||||||
|
{
|
||||||
|
return Message::put($this, $to, $message, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ВКонтакте: идентификатор капчи
|
* Магический метод-сеттер
|
||||||
*
|
*
|
||||||
* @var int
|
* @param mixed $name Название
|
||||||
|
* @param mixed $value Значение
|
||||||
|
*
|
||||||
|
* @see RobotAbstract Модификация наследуемого метода
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
//protected int $captcha;
|
public function __set($name, $value): void
|
||||||
|
|
||||||
public function postMethod($method, $params = []): BrowserAbstract
|
|
||||||
{
|
{
|
||||||
$browser = __NAMESPACE__ . '\\Browsers\\' . ucfirst($_ENV['BROWSER_TYPE']);
|
parent::__set($name, $value);
|
||||||
return (new $browser)->post();
|
|
||||||
|
if ($name === 'longpoll') {
|
||||||
|
if ($value instanceof LongPoll) {
|
||||||
|
$this->longpoll = $value;
|
||||||
|
} else {
|
||||||
|
$this->longpoll = new LongPoll($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function longpoll(...$params): LongPoll
|
/**
|
||||||
|
* Магический метод-геттер
|
||||||
|
*
|
||||||
|
* @param mixed $name Название
|
||||||
|
*
|
||||||
|
* @see RobotAbstract Модификация наследуемого метода
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
{
|
{
|
||||||
return new LongPoll($this, $params);
|
if (!empty($parent = parent::__get($name))) {
|
||||||
|
return $parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function callback()
|
if ($name === 'longpoll') {
|
||||||
{
|
if (empty($this->longpoll)) {
|
||||||
return new CallBack($this, $params);
|
$this->longpoll = new LongPoll($this);
|
||||||
}
|
}
|
||||||
|
return $this->longpoll;
|
||||||
protected function genToken(): string
|
|
||||||
{
|
|
||||||
return 'test';
|
|
||||||
}
|
}
|
||||||
protected function genTokenMobile(string $captcha_key, int $captcha_id): string
|
|
||||||
{
|
|
||||||
return 'test 2';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,33 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace VK\Robots;
|
namespace VK\Robots;
|
||||||
|
|
||||||
use \VK\Browsers\BrowserAbstract;
|
use \Exception;
|
||||||
use \VK\Proxies\ProxyAbstract;
|
use \VK\Browsers\BrowserAbstract,
|
||||||
use \VK\Proxies\CaptchaAbstract;
|
\VK\Proxies\ProxyAbstract,
|
||||||
|
\VK\Captcha\CaptchaAbstract,
|
||||||
|
\VK\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Абстракция робота
|
||||||
|
*
|
||||||
|
* @property int $id Идентификатор
|
||||||
|
* @property int $session Сессия
|
||||||
|
* @property string $token Токен
|
||||||
|
* @property float $version Версия API
|
||||||
|
* @property BrowserAbstract $browser Браузер
|
||||||
|
* @property ProxyAbstract $proxy Прокси
|
||||||
|
* @property CaptchaAbstract $captcha Обработчик капчи
|
||||||
|
*
|
||||||
|
* @method protected static function put(string $url, ...$params) Создать
|
||||||
|
* @method protected static function post(string $url, ...$params) Изменить
|
||||||
|
* @method protected static function get(string $url, ...$params) Получить
|
||||||
|
* @method protected static function delete(string $url, ...$params) Удалить
|
||||||
|
* @method public function __set($name, $value) Магический метод-сеттер
|
||||||
|
* @method public function __get($name) Магический метод-геттер
|
||||||
|
*
|
||||||
|
* @package API/Methods
|
||||||
|
* @author Арсен Мирзаев <red@hood.su>
|
||||||
|
*/
|
||||||
abstract class RobotAbstract
|
abstract class RobotAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -17,6 +40,13 @@ abstract class RobotAbstract
|
||||||
*/
|
*/
|
||||||
protected int $id;
|
protected int $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сессия
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected int $session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Токен
|
* Токен
|
||||||
*
|
*
|
||||||
|
@ -29,17 +59,17 @@ abstract class RobotAbstract
|
||||||
*
|
*
|
||||||
* @var float
|
* @var float
|
||||||
*/
|
*/
|
||||||
public float $version = 5.103;
|
protected float $version = 5.124;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Используемый браузер
|
* Браузер
|
||||||
*
|
*
|
||||||
* @var BrowserAbstract
|
* @var BrowserAbstract
|
||||||
*/
|
*/
|
||||||
protected BrowserAbstract $browser;
|
protected BrowserAbstract $browser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Прокси-сервер
|
* Прокси
|
||||||
*
|
*
|
||||||
* @var ProxyAbstract
|
* @var ProxyAbstract
|
||||||
*/
|
*/
|
||||||
|
@ -55,12 +85,17 @@ abstract class RobotAbstract
|
||||||
/**
|
/**
|
||||||
* Магический сеттер
|
* Магический сеттер
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @param mixed $name Название
|
||||||
|
* @param mixed $value Значение
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __set($name, $value)
|
public function __set($name, $value): void
|
||||||
{
|
{
|
||||||
if ($name === 'id' && empty($this->id)) {
|
if ($name === 'id' && empty($this->id)) {
|
||||||
$this->id = $value;
|
$this->id = $value;
|
||||||
|
} else if ($name === 'session' && empty($this->session)) {
|
||||||
|
$this->session = $value;
|
||||||
} else if ($name === 'token' && empty($this->token)) {
|
} else if ($name === 'token' && empty($this->token)) {
|
||||||
$this->token = $value;
|
$this->token = $value;
|
||||||
} else if ($name === 'version' && empty($this->version)) {
|
} else if ($name === 'version' && empty($this->version)) {
|
||||||
|
@ -77,12 +112,16 @@ abstract class RobotAbstract
|
||||||
/**
|
/**
|
||||||
* Магический геттер
|
* Магический геттер
|
||||||
*
|
*
|
||||||
|
* @param mixed $name Название
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
if ($name === 'id') {
|
if ($name === 'id') {
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
} else if ($name === 'session') {
|
||||||
|
return $this->session;
|
||||||
} else if ($name === 'token') {
|
} else if ($name === 'token') {
|
||||||
return $this->token;
|
return $this->token;
|
||||||
} else if ($name === 'version') {
|
} else if ($name === 'version') {
|
||||||
|
@ -97,7 +136,9 @@ abstract class RobotAbstract
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка токена
|
* Токен
|
||||||
|
*
|
||||||
|
* @param string $token Токен
|
||||||
*
|
*
|
||||||
* @return RobotAbstract
|
* @return RobotAbstract
|
||||||
*/
|
*/
|
||||||
|
@ -110,19 +151,30 @@ abstract class RobotAbstract
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка браузера
|
* Браузер
|
||||||
*
|
*
|
||||||
* @return RobotAbstract
|
* @param BrowserAbstract $browser Браузер
|
||||||
|
*
|
||||||
|
* @return BrowserAbstract
|
||||||
*/
|
*/
|
||||||
public function browser(BrowserAbstract $browser): RobotAbstract
|
public function browser(BrowserAbstract $browser = null): BrowserAbstract
|
||||||
{
|
{
|
||||||
$this->browser = $browser;
|
if (isset($this->browser) && $browser === null) {
|
||||||
|
// Если не передан браузер и свойство иниициализировано
|
||||||
return $this;
|
return $this->browser;
|
||||||
|
} else if ($browser === null) {
|
||||||
|
// Иначе если не передан браузер свойство не инициализировано
|
||||||
|
return $this->browser = new \VK\Browsers\Curl();
|
||||||
|
} else {
|
||||||
|
// Иначе полученный браузер записывается в свойство и возвращается
|
||||||
|
return $this->browser = $browser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка прокси-сервера
|
* Установка прокси
|
||||||
|
*
|
||||||
|
* @param ProxyAbstract $proxy Прокси
|
||||||
*
|
*
|
||||||
* @return RobotAbstract
|
* @return RobotAbstract
|
||||||
*/
|
*/
|
||||||
|
@ -134,7 +186,9 @@ abstract class RobotAbstract
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка сервиса антикапчи
|
* Установка обработчика капчи
|
||||||
|
*
|
||||||
|
* @param CaptchaAbstract $captcha Обработчик капчи
|
||||||
*
|
*
|
||||||
* @return RobotAbstract
|
* @return RobotAbstract
|
||||||
*/
|
*/
|
||||||
|
@ -145,38 +199,27 @@ abstract class RobotAbstract
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Получение браузера
|
// * Метод получения токена аккаунта
|
||||||
*
|
// *
|
||||||
* @return int
|
// * @return string
|
||||||
*/
|
// */
|
||||||
public function getBrowser(): BrowserAbstract
|
// public function getToken($captcha_key = null, $captcha_id = null): string
|
||||||
{
|
// {
|
||||||
// return $this->browser;
|
// if (!empty($_ENV['ACCOUNT_TOKEN'])) {
|
||||||
return new \VK\Browsers\Curl;
|
// return $_ENV['ACCOUNT_TOKEN'];
|
||||||
}
|
// } else if ($this->mobile) {
|
||||||
|
// $this->token_access = $this->genTokenMobile($captcha_key, $this->captcha_id ?? $captcha_id);
|
||||||
|
// } else {
|
||||||
|
// $this->token_access = $this->genToken();
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
// return $this->token_access;
|
||||||
* Метод получения токена аккаунта
|
// }
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getToken($captcha_key = null, $captcha_id = null): string
|
|
||||||
{
|
|
||||||
if (!empty($_ENV['ACCOUNT_TOKEN'])) {
|
|
||||||
return $_ENV['ACCOUNT_TOKEN'];
|
|
||||||
} else if ($this->mobile) {
|
|
||||||
$this->token_access = $this->genTokenMobile($captcha_key, $this->captcha_id ?? $captcha_id);
|
|
||||||
} else {
|
|
||||||
$this->token_access = $this->genToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->token_access;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
abstract protected function genToken(): string;
|
// abstract protected function genToken(): string;
|
||||||
abstract protected function genTokenMobile(string $captcha_key, int $captcha_id): string;
|
// abstract protected function genTokenMobile(string $captcha_key, int $captcha_id): string;
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * @param null $access_groups
|
// * @param null $access_groups
|
||||||
|
|
|
@ -49,7 +49,7 @@ trait Registry
|
||||||
*
|
*
|
||||||
* @param mixed $key
|
* @param mixed $key
|
||||||
*
|
*
|
||||||
* @return false|mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function get(int $key = null)
|
public static function get(int $key = null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,46 +12,46 @@ trait Singleton
|
||||||
/**
|
/**
|
||||||
* Экземпляр класса
|
* Экземпляр класса
|
||||||
*
|
*
|
||||||
* @var LoggerAbstract
|
* @var object
|
||||||
*/
|
*/
|
||||||
protected static $instance;
|
protected static object $instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Блокировка конструктора
|
* Заблокирован
|
||||||
*/
|
*/
|
||||||
protected function __construct()
|
protected function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Инициализатор экземпляра класса
|
* Инициализация
|
||||||
*
|
*
|
||||||
* @return LoggerAbstract
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function init(): self
|
public static function init(): self
|
||||||
{
|
{
|
||||||
if (self::$instance === null) {
|
if (!isset(self::$instance)) {
|
||||||
self::$instance = new self;
|
self::$instance = new self;
|
||||||
}
|
}
|
||||||
return self::$instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Блокировка магического метода __clone()
|
* Заблокирован
|
||||||
*/
|
*/
|
||||||
private function __clone()
|
private function __clone()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Блокировка магического метода __sleep()
|
* Заблокирован
|
||||||
*/
|
*/
|
||||||
private function __sleep()
|
private function __sleep()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Блокировка магического метода __wakeup()
|
* Заблокирован
|
||||||
*/
|
*/
|
||||||
private function __wakeup()
|
private function __wakeup()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue