Избавление от 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
declare(strict_types=1);

View File

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

View File

@ -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']];
}
}

View File

@ -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
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;
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
{

View File

@ -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
{

View File

@ -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

View File

@ -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']);

View File

@ -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;
}
/**

View File

@ -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;
}
}
/**

View File

@ -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;
}

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');
// });