Избавление от phpdotenv, переработка сборщика

This commit is contained in:
RedHood 2020-09-17 22:27:12 +10:00
parent 7c0fcc392d
commit 48946d9070
14 changed files with 253 additions and 253 deletions

View File

@ -1,62 +0,0 @@
######### [SYSTEM] #########
PATH_ROOT = ./
PATH_LOGS = ${PATH_ROOT}/logs
TIMEZONE =
######### [ROBOT] #########
# Тип робота
# Group = 0
# User = 1
DEFAULT_ROBOT_TYPE = 0
######### [BROWSER] #########
# Тип используемого браузера
# Curl = 0
DEFAULT_BROWSER_TYPE = 0
######### [ACCOUNT] #########
# Данные пользователя
# Используется если установлен ROBOT_TYPE=User
DEFAULT_ACCOUNT_LOGIN =
DEFAULT_ACCOUNT_PASSWORD =
DEFAULT_ACCOUNT_TOKEN =
######### [GROUP] #########
DEFAULT_GROUP_ID =
DEFAULT_GROUP_TOKEN =
# Тип используемого API
# LongPoll = 0
# CallBack = 1
DEFAULT_API_TYPE = 0
DEFAULT_API_VERSION = 5.103 # Версия API ВКонтакте
# Массив кодов ошибок ВК, при которых сообщение об ошибке игнорируется и отправляется повторный запрос к api
REQUEST_IGNORE_ERROR=[1,6,9,10,14]
# Максимальное количество попыток загрузки файла
COUNT_TRY_SEND_FILE = 5
# Запрашиваемые права доступа для токена пользователя по уполчанию
ACCESS_GROUPS="notify,friends,photos,audio,video,stories,pages,status,notes,messages,wall,ads,offline,docs,groups,notifications,stats,email,market"
# User-Agent по умолчанию
USERAGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'
# ID приложения ВК по умолчанию
APP_ID = '6660888'
# Домен сервера для подключения CallBack API
SERVER_DOMAIN =
# Произвольный ключ для подключения к CallBack серверу
CALLBACK_SECRET_KEY =

View File

@ -1,5 +1,3 @@
# ИСПОЛЬЗОВАТЬ ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ (20.07.2020)
### Первая версия планируется к середине следующего месяца (15.08.2020)
```php ```php
declare(strict_types=1); declare(strict_types=1);

View File

@ -26,8 +26,7 @@
"php": ">=7.4.0", "php": ">=7.4.0",
"psr/log": "1.*", "psr/log": "1.*",
"monolog/monolog": ">=1.6", "monolog/monolog": ">=1.6",
"jasny/error-handler": "^0.2.0", "jasny/error-handler": "^0.2.0"
"vlucas/phpdotenv": "5.*"
}, },
"require-dev": { "require-dev": {
"phpdocumentor/phpdocumentor": ">=2.9", "phpdocumentor/phpdocumentor": ">=2.9",

View File

@ -73,7 +73,6 @@ class LongPoll extends LongPollAbstract
} else { } else {
$data = $this->robot->request('groups.getLongPollServer', ['group_id' => $this->group_id]); $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']]; list($this->key, $this->server, $this->ts) = [$data['key'], $data['server'], $data['ts']];
} }
} }

View File

@ -4,8 +4,9 @@ declare(strict_types=1);
namespace VK\API\Methods; namespace VK\API\Methods;
use VK\Core; use \VK\Core;
use VK\API\Traits\Request; use \VK\API\Traits\Request;
use \VK\Robots\RobotAbstract;
class Message class Message
{ {
@ -13,10 +14,16 @@ class Message
private const METHOD = 'messages.send'; 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 = [ $params = [
'message' => $message, 'message' => $message,
'peer_id' => $to, 'peer_id' => $to,
@ -25,6 +32,7 @@ class Message
'random_id' => $trolling 'random_id' => $trolling
]; ];
// Запрос
self::request(self::METHOD, $params, $from->getBrowser()); self::request(self::METHOD, $params, $from->getBrowser());
} }

11
system/BuildAbstract.php Normal file
View 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;
}

View File

@ -4,100 +4,80 @@ declare(strict_types=1);
namespace VK; namespace VK;
use Exception; use \Exception;
use VK\Robots\RobotAbstract; use \VK\Core;
use VK\Browsers\BrowserAbstract; use \VK\BuildAbstract;
use VK\Proxies\ProxyAbstract; use \VK\Robots\RobotAbstract;
use VK\Captchas\CaptchaAbstract; use \VK\Robots\Group;
use 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 * @package Builder
*
* @method public group() Создание робота-группы
* @method public user() Создание робота-пользователя
*
* @method private reg() Регистрация в ядре
*
* @author Arsen Mirzaev * @author Arsen Mirzaev
*/ */
class Builder class Builder
{ {
/** public function __construct()
* Собираемый объект
*
* @var object
*/
private object $target;
/**
* Параметры для сборки
*
* @var array
*/
private array $params;
public function __construct(array $params = [])
{ {
$this->params = $params;
return $this; return $this;
} }
/** /**
* Сборщик роботов (паттерн: factory) * Создание робота-группы
* *
* Проверка существования получившегося класса и запись в свойство ядра * @return Group
*
* @return object
*/ */
public function robot($robot = null): object public function group(): Group
{ {
// Ищет по словарю и подставляет имя метода вместо отправленного идентификатора return $this->reg(new \VK\Robots\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"');
} }
/** /**
* Конвертер идентификаторов в значения * Создание робота-пользователя
* *
* Используется конструкция if из-за строгого сравнения * @return User
*
* @param string $var Словарь идентификаторов
* @param int $number Идентификатор
* @return string
*/ */
private function convert(string $var, int $number): string public function user(): User
{ {
if ($var === 'robot') { return $this->reg(new \VK\Robots\User());
if ($number === 0) {
return 'Group';
} else if ($number === 1) {
return 'Account';
} else throw new Exception('Неизвестный идентификатор робота');
} else throw new Exception('Неизвестный тип словаря');
} }
/**
* Регистрация в ядре
*
* @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 * @return RobotAbstract
*
* @todo Добавить установку иного журналиста по спецификации PSR-3
*/ */
public function log($file = null): Builder public function log($file = null): Builder
{ {

View File

@ -4,14 +4,19 @@ declare(strict_types=1);
namespace VK; namespace VK;
use VK\Loggers\Jasmo; use \VK\Loggers\Jasmo;
use VK\Traits\Singleton; use \VK\Traits\Singleton;
use VK\Traits\Registry; use \VK\Traits\Registry;
/** /**
* Ядро фреймворка для работы с VK API * Ядро фреймворка для работы с VK API
* *
* @package VK * @package VK
*
* @property int robots Количество роботов
*
* @method build(...$params) Инициализация сборщика
*
* @author Arsen Mirzaev * @author Arsen Mirzaev
*/ */
class Core 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 public static string $timezone = 'Europe/Moscow';
{
return new Builder($params); /**
* Пути
*
* Архитектура проекта
*
* @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 * @todo Добавить установку иного журналиста по спецификации PSR-3
* @return Core
*/ */
public function log($file = null): Core public function log($file = null): Core
{ {

View File

@ -4,11 +4,12 @@ declare(strict_types=1);
namespace VK\Loggers; namespace VK\Loggers;
use Monolog\Logger; use \DateTime;
use Monolog\Handler\StreamHandler; use \Monolog\Logger;
use Jasny\ErrorHandler; use \Monolog\Handler\StreamHandler;
use DateTime; use \Jasny\ErrorHandler;
use VK\Traits\Singleton; use \VK\Core;
use \VK\Traits\Singleton;
/** /**
* Журналист Jasmo * Журналист Jasmo
@ -39,7 +40,7 @@ class Jasmo extends LoggerAbstract
public static function post($file = null): ?Jasmo 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) * Создание логгера по спецификации 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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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(Core::$path['log'] . "/${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.log", Logger::DEBUG)); // Общий лог
// test // test
// self::$logger->pushProcessor(function ($record) { // self::$logger->pushProcessor(function ($record) {
@ -67,7 +68,7 @@ class Jasmo extends LoggerAbstract
// return $record; // 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('Начало работы'); self::$logger->info('Начало работы');
return self::$instance; return self::$instance;
@ -114,7 +115,7 @@ class Jasmo extends LoggerAbstract
public function handlerShutdown(): void public function handlerShutdown(): void
{ {
self::$logger->info('Завершение работы'); 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 // public function handlerErrors($errno, $errstr, $errfile, $errline, $errcontext): bool

View File

@ -19,27 +19,6 @@ use VK\API\LongPoll;
*/ */
class Group extends RobotAbstract class Group extends RobotAbstract
{ {
/**
* ВКонтакте: идентификатор
*
* @var string
*/
public int $id;
/**
* ВКонтакте: токен доступа
*
* @var string
*/
public string $token;
/**
* ВКонтакте: версия API
*
* @var float
*/
public float $version;
/** /**
* ВКонтакте: тип API * ВКонтакте: тип API
* *
@ -61,13 +40,6 @@ class Group extends RobotAbstract
*/ */
//protected int $captcha; //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 public function postMethod($method, $params = []): BrowserAbstract
{ {
$browser = __NAMESPACE__ . '\\Browsers\\' . ucfirst($_ENV['BROWSER_TYPE']); $browser = __NAMESPACE__ . '\\Browsers\\' . ucfirst($_ENV['BROWSER_TYPE']);

View File

@ -4,18 +4,32 @@ declare(strict_types=1);
namespace VK\Robots; namespace VK\Robots;
use VK\Robots\RobotAbstract; use \VK\Browsers\BrowserAbstract;
use VK\Browsers\BrowserAbstract; use \VK\Proxies\ProxyAbstract;
use VK\Proxies\ProxyAbstract; use \VK\Proxies\CaptchaAbstract;
abstract class RobotAbstract abstract class RobotAbstract
{ {
/** /**
* Идентификатор в регистре * Идентификатор
*
* @var int
*/
protected int $id;
/**
* Токен
* *
* @var string * @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; 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 public function getBrowser(): BrowserAbstract
{ {
// return $this->browser; // return $this->browser;
return new \VK\Browsers\Curl; return new \VK\Browsers\Curl;
} }
/** /**

View File

@ -25,16 +25,17 @@ trait Registry
} }
/** /**
* Положить в реестр * Запись в реестр
*
* @param mixed $key
* @param mixed $value
* *
* @param string $key
* @param mixed $item
* @return void * @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)) { if (!array_key_exists($key, self::$registry)) {
self::$registry[$key] = $item; self::$registry[$key] = $value;
return true; return true;
} }
@ -42,18 +43,21 @@ trait Registry
} }
/** /**
* Получить из реестра по ключу * Извлечение из реестра
* *
* Если не отправить ключ, то вернёт все значения * Если не отправить ключ, то вернёт все значения
* *
* @param string $key * @param mixed $key
*
* @return false|mixed * @return false|mixed
*/ */
public static function get(int $key = null) public static function get(int $key = null)
{ {
if (isset($key) && array_key_exists($key, self::$registry)) { if (isset($key) && array_key_exists($key, self::$registry)) {
return self::$registry[$key]; return self::$registry[$key];
} else return self::$registry; } else {
return self::$registry;
}
} }
/** /**

View File

@ -30,7 +30,9 @@ trait Singleton
*/ */
public static function init(): self public static function init(): self
{ {
if (self::$instance === null) self::$instance = new self; if (self::$instance === null) {
self::$instance = new self;
}
return self::$instance; return self::$instance;
} }

View File

@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
use Dotenv\Dotenv;
use VK\Core as VK;
use VK\API\Methods\Message;
if (!defined('REQUEST_IGNORE_ERROR')) define('REQUEST_IGNORE_ERROR', [1, 6, 9, 10, 14]);
if (!defined('COUNT_TRY_SEND_FILE')) define('COUNT_TRY_SEND_FILE', 5);
// Подключение зависимостей
require_once './vendor/autoload.php';
// Подключение глобальных параметров
Dotenv::createImmutable(__DIR__)->load();
// Инициализация и настрйока ядра
$vk = VK::init()->log();
// Сборка робота
VK::init()->build()->robot();
// Отправка сообщения (от, кому, сообщение)
Message::post(0, 214547089, 'Жопа', 1);
//$stream = $robot->longpoll();
var_dump(VK::init()->get());
// $vk->listen(function ($data) use ($vk) {
// $vk->initVars($id, $message, $payload, $user_id, $type, $data);
// $response = new Message($vk);
// $response->setMessage('чё надо');
// $response->send('214547089');
// });