Избавление от phpdotenv, переработка сборщика
This commit is contained in:
@@ -73,7 +73,6 @@ class LongPoll extends LongPollAbstract
|
||||
} else {
|
||||
$data = $this->robot->request('groups.getLongPollServer', ['group_id' => $this->group_id]);
|
||||
}
|
||||
unset($this->key, $this->server, $this->ts);
|
||||
list($this->key, $this->server, $this->ts) = [$data['key'], $data['server'], $data['ts']];
|
||||
}
|
||||
}
|
||||
|
@@ -4,8 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace VK\API\Methods;
|
||||
|
||||
use VK\Core;
|
||||
use VK\API\Traits\Request;
|
||||
use \VK\Core;
|
||||
use \VK\API\Traits\Request;
|
||||
use \VK\Robots\RobotAbstract;
|
||||
|
||||
class Message
|
||||
{
|
||||
@@ -13,10 +14,16 @@ class Message
|
||||
|
||||
private const METHOD = 'messages.send';
|
||||
|
||||
public static function post($from, $to, $message, $trolling)
|
||||
public static function post($from, int $to, string $message, int $trolling)
|
||||
{
|
||||
if (is_int($from)) $from = Core::init()->get($from);
|
||||
if (is_int($from)) {
|
||||
// Если получен идентификатор, а не экземпляр RobotAbstract
|
||||
|
||||
// Поиск в регистре
|
||||
$from = Core::init()->get($from);
|
||||
}
|
||||
|
||||
// Параметры
|
||||
$params = [
|
||||
'message' => $message,
|
||||
'peer_id' => $to,
|
||||
@@ -25,6 +32,7 @@ class Message
|
||||
'random_id' => $trolling
|
||||
];
|
||||
|
||||
// Запрос
|
||||
self::request(self::METHOD, $params, $from->getBrowser());
|
||||
}
|
||||
|
||||
|
11
system/BuildAbstract.php
Normal file
11
system/BuildAbstract.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace VK;
|
||||
|
||||
abstract class BuildAbstract
|
||||
{
|
||||
abstract protected function create(): BuildAbstract;
|
||||
abstract protected function delete(): BuildAbstract;
|
||||
}
|
@@ -4,100 +4,80 @@ declare(strict_types=1);
|
||||
|
||||
namespace VK;
|
||||
|
||||
use Exception;
|
||||
use VK\Robots\RobotAbstract;
|
||||
use VK\Browsers\BrowserAbstract;
|
||||
use VK\Proxies\ProxyAbstract;
|
||||
use VK\Captchas\CaptchaAbstract;
|
||||
use VK\Loggers\Jasmo;
|
||||
use \Exception;
|
||||
use \VK\Core;
|
||||
use \VK\BuildAbstract;
|
||||
use \VK\Robots\RobotAbstract;
|
||||
use \VK\Robots\Group;
|
||||
use \VK\Robots\User;
|
||||
use \VK\Browsers\BrowserAbstract;
|
||||
use \VK\Proxies\ProxyAbstract;
|
||||
use \VK\Captchas\CaptchaAbstract;
|
||||
use \VK\Loggers\Jasmo;
|
||||
|
||||
/**
|
||||
* Сборщик
|
||||
*
|
||||
* @package Builder
|
||||
*
|
||||
* @method public group() Создание робота-группы
|
||||
* @method public user() Создание робота-пользователя
|
||||
*
|
||||
* @method private reg() Регистрация в ядре
|
||||
*
|
||||
* @author Arsen Mirzaev
|
||||
*/
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* Собираемый объект
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private object $target;
|
||||
|
||||
/**
|
||||
* Параметры для сборки
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private array $params;
|
||||
|
||||
public function __construct(array $params = [])
|
||||
public function __construct()
|
||||
{
|
||||
$this->params = $params;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Сборщик роботов (паттерн: factory)
|
||||
* Создание робота-группы
|
||||
*
|
||||
* Проверка существования получившегося класса и запись в свойство ядра
|
||||
*
|
||||
* @return object
|
||||
* @return Group
|
||||
*/
|
||||
public function robot($robot = null): object
|
||||
public function group(): Group
|
||||
{
|
||||
// Ищет по словарю и подставляет имя метода вместо отправленного идентификатора
|
||||
if (is_int($robot = (int) ($robot ?? $_ENV['DEFAULT_ROBOT_TYPE'])))
|
||||
$robot = $this->convert('robot', $robot);
|
||||
if (class_exists($robot_class = __NAMESPACE__ . '\\Robots\\' . ucfirst($robot))) {
|
||||
$this->target = new $robot_class($robot);
|
||||
} else {
|
||||
throw new Exception("Неизвестный тип робота");
|
||||
}
|
||||
|
||||
// Присвоение параметров из сборщика в экземпляр класса робота
|
||||
foreach (array_keys(get_class_vars($robot_class)) as $key => $value)
|
||||
{
|
||||
if ($value !== null && isset($this->params[$key]))
|
||||
{
|
||||
$this->target->$value = $this->params[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Добавление в регистр, установка идентификатора и обновление счётчика
|
||||
if (false !== Core::set($this->target->setID(Core::$robots_amount++), $this->target)) return $this->target;
|
||||
else throw new Exception('Ошибка при сборке робота "Group"');
|
||||
return $this->reg(new \VK\Robots\Group());
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертер идентификаторов в значения
|
||||
* Создание робота-пользователя
|
||||
*
|
||||
* Используется конструкция if из-за строгого сравнения
|
||||
*
|
||||
* @param string $var Словарь идентификаторов
|
||||
* @param int $number Идентификатор
|
||||
* @return string
|
||||
* @return User
|
||||
*/
|
||||
private function convert(string $var, int $number): string
|
||||
public function user(): User
|
||||
{
|
||||
if ($var === 'robot') {
|
||||
if ($number === 0) {
|
||||
return 'Group';
|
||||
} else if ($number === 1) {
|
||||
return 'Account';
|
||||
} else throw new Exception('Неизвестный идентификатор робота');
|
||||
} else throw new Exception('Неизвестный тип словаря');
|
||||
return $this->reg(new \VK\Robots\User());
|
||||
}
|
||||
|
||||
/**
|
||||
* Регистрация в ядре
|
||||
*
|
||||
* @return RobotAbstract
|
||||
*
|
||||
* @todo Добавить создание нового процесса (многопоточность)
|
||||
*/
|
||||
private function reg(RobotAbstract $robot): RobotAbstract
|
||||
{
|
||||
// Присвоение идентификатора
|
||||
$robot->id = ++Core::$robots;
|
||||
|
||||
// Регистрация в ядре
|
||||
Core::set($robot->id, $robot);
|
||||
|
||||
return $robot;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Установка журналирования
|
||||
*
|
||||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
||||
* @return RobotAbstract
|
||||
*
|
||||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
||||
*/
|
||||
public function log($file = null): Builder
|
||||
{
|
||||
|
@@ -4,14 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace VK;
|
||||
|
||||
use VK\Loggers\Jasmo;
|
||||
use VK\Traits\Singleton;
|
||||
use VK\Traits\Registry;
|
||||
use \VK\Loggers\Jasmo;
|
||||
use \VK\Traits\Singleton;
|
||||
use \VK\Traits\Registry;
|
||||
|
||||
/**
|
||||
* Ядро фреймворка для работы с VK API
|
||||
*
|
||||
* @package VK
|
||||
*
|
||||
* @property int robots Количество роботов
|
||||
*
|
||||
* @method build(...$params) Инициализация сборщика
|
||||
*
|
||||
* @author Arsen Mirzaev
|
||||
*/
|
||||
class Core
|
||||
@@ -21,25 +26,58 @@ class Core
|
||||
}
|
||||
|
||||
/**
|
||||
* Cчётчик роботов
|
||||
* Количество роботов
|
||||
*
|
||||
* Хранит экземпляры роботов по их идентификаторам
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static int $robots_amount = 0;
|
||||
public static int $robots = 0;
|
||||
|
||||
/**
|
||||
* Создание экземпляра сборщика
|
||||
* Временная зона
|
||||
*
|
||||
* @return Builder
|
||||
* Используется в логировании
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public function build(...$params): Builder
|
||||
{
|
||||
return new Builder($params);
|
||||
public static string $timezone = 'Europe/Moscow';
|
||||
|
||||
/**
|
||||
* Пути
|
||||
*
|
||||
* Архитектура проекта
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static array $path = [
|
||||
'root' => '',
|
||||
'log' => ''
|
||||
];
|
||||
|
||||
protected function __construct() {
|
||||
self::$path = [
|
||||
'root' => dirname(__DIR__) . '..',
|
||||
'log' => self::$path['root'] . '/log'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка журналирования
|
||||
* Инициализация сборщика
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function build(): Builder
|
||||
{
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Активация журналирования
|
||||
*
|
||||
* @return Core
|
||||
*
|
||||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
||||
* @return Core
|
||||
*/
|
||||
public function log($file = null): Core
|
||||
{
|
||||
|
@@ -4,11 +4,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace VK\Loggers;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Jasny\ErrorHandler;
|
||||
use DateTime;
|
||||
use VK\Traits\Singleton;
|
||||
use \DateTime;
|
||||
use \Monolog\Logger;
|
||||
use \Monolog\Handler\StreamHandler;
|
||||
use \Jasny\ErrorHandler;
|
||||
use \VK\Core;
|
||||
use \VK\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Журналист Jasmo
|
||||
@@ -39,7 +40,7 @@ class Jasmo extends LoggerAbstract
|
||||
|
||||
public static function post($file = null): ?Jasmo
|
||||
{
|
||||
$file = $file ?? date_format(new DateTime($_ENV['TIMEZONE']), 'Y.m.d');
|
||||
$file = $file ?? date_format(new DateTime(Core::$timezone), 'Y.m.d');
|
||||
|
||||
/**
|
||||
* Создание логгера по спецификации PSR-3 (Monolog)
|
||||
@@ -51,14 +52,14 @@ class Jasmo extends LoggerAbstract
|
||||
/**
|
||||
* Создание обработчиков (порядок обязателен)
|
||||
*/
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-INFO.log", Logger::INFO, false)); // Инфомация о процессе работы
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-NOTICE.log", Logger::NOTICE, false)); // Уведомления
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-WARNING.log", Logger::WARNING, false)); // Предупреждения
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-ERROR.log", Logger::ERROR, false)); // Ошибки
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-CRITICAL.log", Logger::CRITICAL, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-ALERT.log", Logger::ALERT, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/${file}-EMERGENCY.log", Logger::EMERGENCY, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler($_ENV['PATH_LOGS'] . "/$file.log", Logger::DEBUG)); // Общий лог
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-INFO.log", Logger::INFO, false)); // Инфомация о процессе работы
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-NOTICE.log", Logger::NOTICE, false)); // Уведомления
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-WARNING.log", Logger::WARNING, false)); // Предупреждения
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-ERROR.log", Logger::ERROR, false)); // Ошибки
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-CRITICAL.log", Logger::CRITICAL, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-ALERT.log", Logger::ALERT, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/${file}-EMERGENCY.log", Logger::EMERGENCY, false)); // Критические ошибки
|
||||
self::$logger->pushHandler(new StreamHandler(Core::$path['log'] . "/$file.log", Logger::DEBUG)); // Общий лог
|
||||
|
||||
// test
|
||||
// self::$logger->pushProcessor(function ($record) {
|
||||
@@ -67,7 +68,7 @@ class Jasmo extends LoggerAbstract
|
||||
// return $record;
|
||||
// });
|
||||
|
||||
echo '[' . date_format(new DateTime($_ENV['TIMEZONE']), 'd-m-Y H:i:s') . '] Начало работы', PHP_EOL;
|
||||
echo '[' . date_format(new DateTime(Core::$timezone), 'd-m-Y H:i:s') . '] Начало работы', PHP_EOL;
|
||||
self::$logger->info('Начало работы');
|
||||
|
||||
return self::$instance;
|
||||
@@ -114,7 +115,7 @@ class Jasmo extends LoggerAbstract
|
||||
public function handlerShutdown(): void
|
||||
{
|
||||
self::$logger->info('Завершение работы');
|
||||
echo '[' . date_format(new DateTime($_ENV['TIMEZONE']), 'd-m-Y H:i:s') . '] Завершение работы', PHP_EOL;
|
||||
echo '[' . date_format(new DateTime(Core::$timezone), 'd-m-Y H:i:s') . '] Завершение работы', PHP_EOL;
|
||||
}
|
||||
|
||||
// public function handlerErrors($errno, $errstr, $errfile, $errline, $errcontext): bool
|
||||
|
@@ -19,27 +19,6 @@ use VK\API\LongPoll;
|
||||
*/
|
||||
class Group extends RobotAbstract
|
||||
{
|
||||
/**
|
||||
* ВКонтакте: идентификатор
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public int $id;
|
||||
|
||||
/**
|
||||
* ВКонтакте: токен доступа
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $token;
|
||||
|
||||
/**
|
||||
* ВКонтакте: версия API
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public float $version;
|
||||
|
||||
/**
|
||||
* ВКонтакте: тип API
|
||||
*
|
||||
@@ -61,13 +40,6 @@ class Group extends RobotAbstract
|
||||
*/
|
||||
//protected int $captcha;
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
if (!isset($this->id)) $this->id = (int) $_ENV['DEFAULT_' . strtoupper($name) . '_ID'];
|
||||
if (!isset($this->token)) $this->token = (string) $_ENV['DEFAULT_' . strtoupper($name) . '_TOKEN'];
|
||||
if (!isset($this->version)) $this->version = (float) $_ENV['DEFAULT_API_VERSION'];
|
||||
}
|
||||
|
||||
public function postMethod($method, $params = []): BrowserAbstract
|
||||
{
|
||||
$browser = __NAMESPACE__ . '\\Browsers\\' . ucfirst($_ENV['BROWSER_TYPE']);
|
||||
|
@@ -4,18 +4,32 @@ declare(strict_types=1);
|
||||
|
||||
namespace VK\Robots;
|
||||
|
||||
use VK\Robots\RobotAbstract;
|
||||
use VK\Browsers\BrowserAbstract;
|
||||
use VK\Proxies\ProxyAbstract;
|
||||
use \VK\Browsers\BrowserAbstract;
|
||||
use \VK\Proxies\ProxyAbstract;
|
||||
use \VK\Proxies\CaptchaAbstract;
|
||||
|
||||
abstract class RobotAbstract
|
||||
{
|
||||
/**
|
||||
* Идентификатор в регистре
|
||||
* Идентификатор
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected int $id;
|
||||
|
||||
/**
|
||||
* Токен
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private int $id_registry;
|
||||
protected string $token;
|
||||
|
||||
/**
|
||||
* Версия API
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public float $version = 5.103;
|
||||
|
||||
/**
|
||||
* Используемый браузер
|
||||
@@ -39,23 +53,96 @@ abstract class RobotAbstract
|
||||
protected CaptchaAbstract $captcha;
|
||||
|
||||
/**
|
||||
* Установка идентификатора
|
||||
* Магический сеттер
|
||||
*
|
||||
* @return int
|
||||
* @return mixed
|
||||
*/
|
||||
public function setID(int $id): int
|
||||
public function __set($name, $value)
|
||||
{
|
||||
return $this->id_registry = $id;
|
||||
if ($name === 'id' && empty($this->id)) {
|
||||
$this->id = $value;
|
||||
} else if ($name === 'token' && empty($this->token)) {
|
||||
$this->token = $value;
|
||||
} else if ($name === 'version' && empty($this->version)) {
|
||||
$this->version = $value;
|
||||
} else if ($name === 'browser') {
|
||||
$this->browser = $value;
|
||||
} else if ($name === 'proxy') {
|
||||
$this->proxy = $value;
|
||||
} else if ($name === 'captcha') {
|
||||
$this->captcha = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение идентификатора
|
||||
* Магический геттер
|
||||
*
|
||||
* @return int
|
||||
* @return mixed
|
||||
*/
|
||||
public function getID(): int
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->id;
|
||||
if ($name === 'id') {
|
||||
return $this->id;
|
||||
} else if ($name === 'token') {
|
||||
return $this->token;
|
||||
} else if ($name === 'version') {
|
||||
return $this->version;
|
||||
} else if ($name === 'browser') {
|
||||
return $this->browser;
|
||||
} else if ($name === 'proxy') {
|
||||
return $this->proxy;
|
||||
} else if ($name === 'captcha') {
|
||||
return $this->captcha;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка токена
|
||||
*
|
||||
* @return RobotAbstract
|
||||
*/
|
||||
public function token(string $token): RobotAbstract
|
||||
{
|
||||
$this->token = $token;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Установка браузера
|
||||
*
|
||||
* @return RobotAbstract
|
||||
*/
|
||||
public function browser(BrowserAbstract $browser): RobotAbstract
|
||||
{
|
||||
$this->browser = $browser;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка прокси-сервера
|
||||
*
|
||||
* @return RobotAbstract
|
||||
*/
|
||||
public function proxy(ProxyAbstract $proxy): RobotAbstract
|
||||
{
|
||||
$this->proxy = $proxy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка сервиса антикапчи
|
||||
*
|
||||
* @return RobotAbstract
|
||||
*/
|
||||
public function captcha(CaptchaAbstract $captcha): RobotAbstract
|
||||
{
|
||||
$this->captcha = $captcha;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,8 +152,8 @@ abstract class RobotAbstract
|
||||
*/
|
||||
public function getBrowser(): BrowserAbstract
|
||||
{
|
||||
// return $this->browser;
|
||||
return new \VK\Browsers\Curl;
|
||||
// return $this->browser;
|
||||
return new \VK\Browsers\Curl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,16 +25,17 @@ trait Registry
|
||||
}
|
||||
|
||||
/**
|
||||
* Положить в реестр
|
||||
* Запись в реестр
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $item
|
||||
* @return void
|
||||
*/
|
||||
public static function set(int $key, $item): bool
|
||||
public static function set(int $key, $value): bool
|
||||
{
|
||||
if (!array_key_exists($key, self::$registry)) {
|
||||
self::$registry[$key] = $item;
|
||||
self::$registry[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,18 +43,21 @@ trait Registry
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить из реестра по ключу
|
||||
* Извлечение из реестра
|
||||
*
|
||||
* Если не отправить ключ, то вернёт все значения
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return false|mixed
|
||||
*/
|
||||
public static function get(int $key = null)
|
||||
{
|
||||
if (isset($key) && array_key_exists($key, self::$registry)) {
|
||||
return self::$registry[$key];
|
||||
} else return self::$registry;
|
||||
} else {
|
||||
return self::$registry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,7 +30,9 @@ trait Singleton
|
||||
*/
|
||||
public static function init(): self
|
||||
{
|
||||
if (self::$instance === null) self::$instance = new self;
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user