forked from mirzaev/ff
ребрендинг + строка пакостей
This commit is contained in:
169
mirzaev/site/ff/system/models/account_model.php
Normal file
169
mirzaev/site/ff/system/models/account_model.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mirzaev\site\ff\models;
|
||||
|
||||
// Файлы проекта
|
||||
use mirzaev\site\ff\models\vk_model as vk;
|
||||
|
||||
// Фреймворк ArangoDB
|
||||
use mirzaev\arangodb\collection,
|
||||
mirzaev\arangodb\document;
|
||||
|
||||
// Библиотека для ArangoDB
|
||||
use ArangoDBClient\Document as _document;
|
||||
|
||||
// Встроенные библиотеки
|
||||
use exception;
|
||||
|
||||
/**
|
||||
* Модель регистрации, аутентификации и авторизации
|
||||
*
|
||||
* @package mirzaev\site\ff\models
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
final class account_model extends core
|
||||
{
|
||||
/**
|
||||
* Коллекция
|
||||
*/
|
||||
public const COLLECTION = 'account';
|
||||
|
||||
/**
|
||||
* Создать
|
||||
*
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта, если удалось создать
|
||||
*/
|
||||
public static function create(array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
// Запись аккаунта в базу данных
|
||||
$_id = document::write(static::$db->session, self::COLLECTION);
|
||||
|
||||
if ($account = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d._id == '$_id'
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION
|
||||
))) {
|
||||
// Найден созданный аккаунт
|
||||
|
||||
return $account;
|
||||
} else throw new exception('Не удалось создать аккаунт');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Связь аккаунта с аккаунтом ВКонтакте
|
||||
*
|
||||
* @param _document $account Инстанция аккаунта
|
||||
* @param _document $vk Инстанция аккаунта ВКонтакте
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return bool Статус выполнения
|
||||
*/
|
||||
public static function connect(_document $account, _document $vk, array &$errors = []): bool
|
||||
{
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$db->session, self::COLLECTION)
|
||||
&& collection::init(static::$db->session, vk::COLLECTION)
|
||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . vk::COLLECTION, true)
|
||||
) {
|
||||
// Инициализированы коллекции
|
||||
|
||||
if (document::write(static::$db->session, self::COLLECTION . '_edge_' . vk::COLLECTION, [
|
||||
'_from' => $account->getId(),
|
||||
'_to' => $vk->getId()
|
||||
])) {
|
||||
// Создано ребро: account -> vk
|
||||
|
||||
return true;
|
||||
} else throw new exception('Не удалось создать ребро: account -> vk');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск связанного аккаунта ВКонтакте
|
||||
*
|
||||
* @param _document $account Инстанция аккаунта
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта, если удалось найти
|
||||
*/
|
||||
public static function vk(_document $account, array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$db->session, self::COLLECTION)
|
||||
&& collection::init(static::$db->session, vk::COLLECTION)
|
||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . vk::COLLECTION, true)
|
||||
) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
if ($vk = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR document IN %s
|
||||
LET edge = (
|
||||
FOR edge IN %s
|
||||
FILTER edge._from == '%s'
|
||||
SORT edge._key DESC
|
||||
LIMIT 1
|
||||
RETURN edge
|
||||
)
|
||||
FILTER document._id == edge[0]._to
|
||||
LIMIT 1
|
||||
RETURN document
|
||||
AQL,
|
||||
vk::COLLECTION,
|
||||
self::COLLECTION . '_edge_' . vk::COLLECTION,
|
||||
$account->getId()
|
||||
))) {
|
||||
// Найден аккаунт ВКонтакте
|
||||
|
||||
return $vk;
|
||||
} else throw new exception('Не удалось найти аккаунт ВКонтакте');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
143
mirzaev/site/ff/system/models/core.php
Normal file
143
mirzaev/site/ff/system/models/core.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mirzaev\site\ff\models;
|
||||
|
||||
use mirzaev\minimal\model;
|
||||
|
||||
use mirzaev\arangodb\connection;
|
||||
|
||||
use exception;
|
||||
|
||||
/**
|
||||
* Ядро моделей
|
||||
*
|
||||
* @package mirzaev\site\ff\models
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class core extends model
|
||||
{
|
||||
/**
|
||||
* Коллекция в которой хранятся аккаунты
|
||||
*/
|
||||
public const SETTINGS = '../settings/arangodb.php';
|
||||
|
||||
/**
|
||||
* Соединение с базой данных
|
||||
*/
|
||||
protected static connection $db;
|
||||
|
||||
public function __construct(connection $db = null)
|
||||
{
|
||||
if (isset($db)) {
|
||||
// Получена инстанция соединения с базой данных
|
||||
|
||||
// Запись и инициализация соединения с базой данных
|
||||
$this->__set('db', $db);
|
||||
} else {
|
||||
// Не получена инстанция соединения с базой данных
|
||||
|
||||
// Инициализация соединения с базой данных по умолчанию
|
||||
$this->__get('db');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать свойство
|
||||
*
|
||||
* @param string $name Название
|
||||
* @param mixed $value Значение
|
||||
*/
|
||||
public function __set(string $name, mixed $value = null): void
|
||||
{
|
||||
match ($name) {
|
||||
'db' => (function () use ($value) {
|
||||
if ($this->__isset('db')) {
|
||||
// Свойство уже было инициализировано
|
||||
|
||||
// Выброс исключения (неудача)
|
||||
throw new exception('Запрещено реинициализировать соединение с базой данных ($this->db)', 500);
|
||||
} else {
|
||||
// Свойство ещё не было инициализировано
|
||||
|
||||
if ($value instanceof connection) {
|
||||
// Передано подходящее значение
|
||||
|
||||
// Запись свойства (успех)
|
||||
self::$db = $value;
|
||||
} else {
|
||||
// Передано неподходящее значение
|
||||
|
||||
// Выброс исключения (неудача)
|
||||
throw new exception('Соединение с базой данных ($this->db) должен быть инстанцией mirzaev\arangodb\connection', 500);
|
||||
}
|
||||
}
|
||||
})(),
|
||||
default => parent::__set($name, $value)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать свойство
|
||||
*
|
||||
* @param string $name Название
|
||||
*
|
||||
* @return mixed Содержимое
|
||||
*/
|
||||
public function __get(string $name): mixed
|
||||
{
|
||||
return match ($name) {
|
||||
'db' => (function () {
|
||||
if (!$this->__isset('db')) {
|
||||
// Свойство не инициализировано
|
||||
|
||||
// Инициализация значения по умолчанию исходя из настроек
|
||||
$this->__set('db', new connection(require static::SETTINGS));
|
||||
}
|
||||
|
||||
return self::$db;
|
||||
})(),
|
||||
default => parent::__get($name)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить свойство на инициализированность
|
||||
*
|
||||
* @param string $name Название
|
||||
*/
|
||||
public function __isset(string $name): bool
|
||||
{
|
||||
return match ($name) {
|
||||
default => parent::__isset($name)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить свойство
|
||||
*
|
||||
* @param string $name Название
|
||||
*/
|
||||
public function __unset(string $name): void
|
||||
{
|
||||
match ($name) {
|
||||
default => parent::__isset($name)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Статический вызов
|
||||
*
|
||||
* @param string $name Название
|
||||
* @param array $arguments Параметры
|
||||
*/
|
||||
public static function __callStatic(string $name, array $arguments): mixed
|
||||
{
|
||||
match ($name) {
|
||||
'db' => (new static)->__get('db'),
|
||||
default => throw new exception("Не найдено свойство или функция: $name", 500)
|
||||
};
|
||||
}
|
||||
}
|
216
mirzaev/site/ff/system/models/session_model.php
Normal file
216
mirzaev/site/ff/system/models/session_model.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mirzaev\site\ff\models;
|
||||
|
||||
// Файлы проекта
|
||||
use mirzaev\site\ff\models\account_model as account;
|
||||
|
||||
// Фреймворк ArangoDB
|
||||
use mirzaev\arangodb\collection,
|
||||
mirzaev\arangodb\document;
|
||||
|
||||
// Библиотека для ArangoDB
|
||||
use ArangoDBClient\Document as _document;
|
||||
|
||||
// Встроенные библиотеки
|
||||
use exception;
|
||||
|
||||
/**
|
||||
* Модель сессий
|
||||
*
|
||||
* @package mirzaev\site\ff\models
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
final class session_model extends core
|
||||
{
|
||||
/**
|
||||
* Коллекция
|
||||
*/
|
||||
public const COLLECTION = 'session';
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*
|
||||
* @param ?string $hash Хеш сессии в базе данных
|
||||
* @param ?int $expires Дата окончания работы сессии (используется при создании новой сессии)
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция сессии, если удалось найти или создать
|
||||
*/
|
||||
public static function initialization(?string $hash = null, ?int $expires = null, array &$errors = []): ?_document
|
||||
{
|
||||
$a = new _document();
|
||||
$a->hash = 'dolboeb227';
|
||||
return $a;
|
||||
try {
|
||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
if (isset($hash) && $session = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d.hash == '$hash' && d.expires > %d
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION,
|
||||
time()
|
||||
))) {
|
||||
// Найдена сессия по хешу
|
||||
|
||||
// Возврат сессии
|
||||
return $session;
|
||||
} else if ($session = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d.ip == '%s' && d.expires > %d
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION,
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
time()
|
||||
))) {
|
||||
// Найдена сессия по данным пользователя
|
||||
|
||||
// Возврат сессии
|
||||
return $session;
|
||||
} else {
|
||||
// Не найдена сессия
|
||||
|
||||
// Запись сессии в базу данных
|
||||
$_id = document::write(static::$db->session, self::COLLECTION, [
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'expires' => $expires ?? time() + 604800
|
||||
]);
|
||||
|
||||
if ($session = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d._id == '$_id' && d.expires > %d
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION,
|
||||
time()
|
||||
))) {
|
||||
// Найдена созданная сессия
|
||||
|
||||
// Запись хеша
|
||||
$session->hash = sodium_bin2hex(sodium_crypto_generichash($_id));
|
||||
|
||||
if (document::update(static::$db->session, $session)) {
|
||||
// Записано обновление
|
||||
|
||||
return $session;
|
||||
} else throw new exception('Не удалось записать данные сессии');
|
||||
} else throw new exception('Не удалось создать или найти созданную сессию');
|
||||
}
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Связь сессии с аккаунтом
|
||||
*
|
||||
* @param _document $session Инстанция сессии
|
||||
* @param _document $account Инстанция аккаунта
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return bool Статус выполнения
|
||||
*/
|
||||
public static function connect(_document $session, _document $account, array &$errors = []): bool
|
||||
{
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$db->session, self::COLLECTION)
|
||||
&& collection::init(static::$db->session, account::COLLECTION)
|
||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
||||
) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
if (document::write(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, [
|
||||
'_from' => $session->getId(),
|
||||
'_to' => $account->getId()
|
||||
])) {
|
||||
// Создано ребро: session -> account
|
||||
|
||||
return true;
|
||||
} else throw new exception('Не удалось создать ребро: session -> account');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск связанного аккаунта
|
||||
*
|
||||
* @param _document $session Инстанция сессии
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта, если удалось найти
|
||||
*/
|
||||
public static function account(_document $session, array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$db->session, self::COLLECTION)
|
||||
&& collection::init(static::$db->session, account::COLLECTION)
|
||||
&& collection::init(static::$db->session, self::COLLECTION . '_edge_' . account::COLLECTION, true)
|
||||
) {
|
||||
// Инициализированы коллекции
|
||||
|
||||
if ($account = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR document IN %s
|
||||
LET edge = (
|
||||
FOR edge IN %s
|
||||
FILTER edge._from == '%s'
|
||||
SORT edge._key DESC
|
||||
LIMIT 1
|
||||
RETURN edge
|
||||
)
|
||||
FILTER document._id == edge[0]._to
|
||||
LIMIT 1
|
||||
RETURN document
|
||||
AQL,
|
||||
account::COLLECTION,
|
||||
self::COLLECTION . '_edge_' . account::COLLECTION,
|
||||
$session->getId()
|
||||
))) {
|
||||
// Найден аккаунт
|
||||
|
||||
return $account;
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
555
mirzaev/site/ff/system/models/vk_model.php
Normal file
555
mirzaev/site/ff/system/models/vk_model.php
Normal file
@@ -0,0 +1,555 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mirzaev\site\ff\models;
|
||||
|
||||
// Файлы проекта
|
||||
use mirzaev\site\ff\models\account_model as account;
|
||||
|
||||
// Фреймворк ArangoDB
|
||||
use mirzaev\arangodb\collection,
|
||||
mirzaev\arangodb\document;
|
||||
|
||||
// Фреймворк ВКонтакте
|
||||
use mirzaev\vk\robots\user as robot;
|
||||
|
||||
// Библиотека для ArangoDB
|
||||
use ArangoDBClient\Document as _document;
|
||||
|
||||
// Библиотека браузера
|
||||
use GuzzleHttp\Client as browser;
|
||||
|
||||
// Встроенные библиотеки
|
||||
use exception;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Модель аккаунта ВКонтакте
|
||||
*
|
||||
* @package mirzaev\site\ff\models
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
final class vk_model extends core
|
||||
{
|
||||
/**
|
||||
* Коллекция
|
||||
*/
|
||||
public const COLLECTION = 'vk';
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*
|
||||
* @param string $response Ответ сервера ВКонтакте с данными аккаунта
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта ВКонтакте, если удалось создать
|
||||
*/
|
||||
public static function initialization(string $response = '', array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
// Инициализация данных аккаунта ВКонтакте
|
||||
$data = json_decode($response);
|
||||
|
||||
if ($account = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d.id == $data->user_id
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION
|
||||
))) {
|
||||
// Найден аккаунт ВКонтакте
|
||||
|
||||
return $account;
|
||||
} else {
|
||||
// Не найден аккаунт ВКонтакте
|
||||
|
||||
return self::create($response, $errors);
|
||||
}
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание
|
||||
*
|
||||
* @param string $response Ответ сервера ВКонтакте с данными аккаунта
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта ВКонтакте, если удалось создать
|
||||
*/
|
||||
public static function create(string $response = '', array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
// Запись аккаунта в базу данных
|
||||
$_id = document::write(static::$db->session, self::COLLECTION);
|
||||
|
||||
if ($account = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR d IN %s
|
||||
FILTER d._id == '$_id'
|
||||
RETURN d
|
||||
AQL,
|
||||
self::COLLECTION
|
||||
))) {
|
||||
// Найден созданный аккаунт ВКонтакте
|
||||
|
||||
if (document::update(static::$db->session, $account)) {
|
||||
// Записано обновление
|
||||
|
||||
// Запись данных об аккаунте ВКонтакте и возврат (bool)
|
||||
return self::update($account, json_decode($response), $errors);
|
||||
}
|
||||
}
|
||||
throw new exception('Не удалось создать аккаунт ВКонтакте');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запросить ключ
|
||||
*
|
||||
* @param string $code Код полученный от ВКонтакте
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?string Тело ответа, если получен код ответа 200
|
||||
*/
|
||||
public static function key(string $code = '', array &$errors = []): ?string
|
||||
{
|
||||
try {
|
||||
// Инициализация браузера
|
||||
$browser = new browser();
|
||||
|
||||
// Запрос
|
||||
$response = $browser->request('GET', "https://oauth.vk.com/access_token?client_id=51447080&client_secret=KYlk0nGELW0A9ds7NQi6&redirect_uri=https://virus.mirzaev.sexy/account/vk/connect&code=$code");
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
// Ответ сервера: 200
|
||||
|
||||
return (string) $response->getBody();
|
||||
} else throw new exception('Не удалось получить ключ ВКонтакте (' . $response->getStatusCode() . ')');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск связанного аккаунта
|
||||
*
|
||||
* @param _document $vk Инстанция аккаунта ВКонтакте
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта, если удалось найти
|
||||
*/
|
||||
public static function account(_document $vk, array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$db->session, self::COLLECTION)
|
||||
&& collection::init(static::$db->session, account::COLLECTION)
|
||||
&& collection::init(static::$db->session, account::COLLECTION . '_edge_' . self::COLLECTION, true)
|
||||
) {
|
||||
// Инициализированы коллекции
|
||||
|
||||
if ($account = collection::search(static::$db->session, sprintf(
|
||||
<<<AQL
|
||||
FOR document IN %s
|
||||
LET edge = (
|
||||
FOR edge IN %s
|
||||
FILTER edge._to == '%s'
|
||||
SORT edge._key DESC
|
||||
LIMIT 1
|
||||
RETURN edge
|
||||
)
|
||||
FILTER document._id == edge[0]._from
|
||||
LIMIT 1
|
||||
RETURN document
|
||||
AQL,
|
||||
account::COLLECTION,
|
||||
account::COLLECTION . '_edge_' . self::COLLECTION,
|
||||
$vk->getId()
|
||||
))) {
|
||||
// Найден аккаунт
|
||||
|
||||
return $account;
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запрос данных аккаунта ВКонтакте с серверов ВКонтакте
|
||||
*
|
||||
* @param robot $vk Инстанция аккаунта ВКонтакте
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?stdClass Данные аккаунта ВКонтакте, если получены
|
||||
*/
|
||||
public static function parse(robot $vk, array &$errors = []): ?stdClass
|
||||
{
|
||||
try {
|
||||
// Запрос к API-серверу ВКонтакте
|
||||
$response = $vk->user->get(fields: [
|
||||
'activities',
|
||||
'about',
|
||||
// 'blacklisted',
|
||||
// 'blacklisted_by_me',
|
||||
'books',
|
||||
'bdate',
|
||||
'can_be_invited_group',
|
||||
'can_post',
|
||||
'can_see_all_posts',
|
||||
'can_see_audio',
|
||||
'can_send_friend_request',
|
||||
'can_write_private_message',
|
||||
'career',
|
||||
'common_count',
|
||||
'connections',
|
||||
'contacts',
|
||||
'city',
|
||||
'country',
|
||||
'crop_photo',
|
||||
'domain',
|
||||
'education',
|
||||
'exports',
|
||||
'followers_count',
|
||||
'friend_status',
|
||||
'has_photo',
|
||||
'has_mobile',
|
||||
'home_town',
|
||||
'photo_50',
|
||||
'photo_100',
|
||||
'photo_200',
|
||||
'photo_200_orig',
|
||||
'photo_400_orig',
|
||||
'photo_max',
|
||||
'photo_max_orig',
|
||||
'sex',
|
||||
'site',
|
||||
'schools',
|
||||
'screen_name',
|
||||
'status',
|
||||
'verified',
|
||||
'games',
|
||||
'interests',
|
||||
'is_favorite',
|
||||
'is_friend',
|
||||
'is_hidden_from_feed',
|
||||
'last_seen',
|
||||
'maiden_name',
|
||||
'military',
|
||||
'movies',
|
||||
'music',
|
||||
'nickname',
|
||||
'occupation',
|
||||
'online',
|
||||
'personal',
|
||||
'photo_id',
|
||||
'quotes',
|
||||
'relation',
|
||||
'relatives',
|
||||
'timezone',
|
||||
'tv',
|
||||
'universities'
|
||||
])[0];
|
||||
|
||||
if (!empty($response)) {
|
||||
// Получен ответ
|
||||
|
||||
return $response;
|
||||
}
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление данных аккаунта ВКонтакте
|
||||
*
|
||||
* Все файлы (аватар, например) будут скачаны на сервер
|
||||
*
|
||||
* @param _document $vk Инстанция аккаунта ВКонтакте
|
||||
* @param stdClass $data Информация об аккаунте (self::parse() или json_decode())
|
||||
* @param array &$errors Журнал ошибок
|
||||
*
|
||||
* @return ?_document Инстанция аккаунта ВКонтакте, если удалось обновить
|
||||
*/
|
||||
public static function update(_document $vk, stdClass $data, array &$errors = []): ?_document
|
||||
{
|
||||
try {
|
||||
if (collection::init(static::$db->session, self::COLLECTION)) {
|
||||
// Инициализирована коллекция
|
||||
|
||||
if (empty($vk->id) and isset($data->user_id) || isset($data->id)) {
|
||||
// Получен идентификатор
|
||||
|
||||
// Запись
|
||||
$vk->id = $data->user_id ?? $data->id;
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->user_id, $data->id);
|
||||
} else if (empty($vk->id)) throw new exception('Не удалось найти идентификатор аккаунта ВКонтакте');
|
||||
|
||||
if (isset($data->access_token, $data->expires_in)) {
|
||||
// Получен ключ
|
||||
|
||||
// Запись
|
||||
$vk->access = [
|
||||
'key' => $data->access_token,
|
||||
'expires' => $data->expires_in
|
||||
];
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->access_token, $data->expires_in);
|
||||
}
|
||||
|
||||
// Инициализация браузера
|
||||
$browser = new browser();
|
||||
|
||||
// Инициализация директории с обложкой
|
||||
if (!file_exists($path = INDEX . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . $vk->id . DIRECTORY_SEPARATOR . 'cover' . DIRECTORY_SEPARATOR))
|
||||
mkdir($path, 0775, true);
|
||||
|
||||
if (isset($data->photo_50)) {
|
||||
// Получено изображение 50x50
|
||||
|
||||
if ($browser->get($data->photo_50, ['sink' => $file = "$path/50x50.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'50x50' => ($vk->cover['50x50'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_50,
|
||||
'public' => "/storage/$vk->id/cover/50x50.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение 50x50 с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_50);
|
||||
}
|
||||
|
||||
// Инициализация директории с обложкой
|
||||
if (!file_exists($path = INDEX . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . $vk->id . DIRECTORY_SEPARATOR . 'cover' . DIRECTORY_SEPARATOR))
|
||||
mkdir($path, 0775, true);
|
||||
|
||||
if (isset($data->photo_100)) {
|
||||
// Получено изображение 100x100
|
||||
|
||||
if ($browser->get($data->photo_100, ['sink' => $file = "$path/100x100.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'100x100' => ($vk->cover['100x100'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_100,
|
||||
'public' => "/storage/$vk->id/cover/100x100.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение 100x100 с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_100);
|
||||
}
|
||||
|
||||
// Инициализация директории с обложкой
|
||||
if (!file_exists($path = INDEX . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . $vk->id . DIRECTORY_SEPARATOR . 'cover' . DIRECTORY_SEPARATOR))
|
||||
mkdir($path, 0775, true);
|
||||
|
||||
if (isset($data->photo_200)) {
|
||||
// Получено изображение 200x200
|
||||
|
||||
if ($browser->get($data->photo_200, ['sink' => $file = "$path/200x200.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'200x200' => ($vk->cover['200x200'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_200,
|
||||
'public' => "/storage/$vk->id/cover/200x200.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение 200x200 с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_200);
|
||||
}
|
||||
|
||||
if (isset($data->photo_200_orig)) {
|
||||
// Получено изображение 200x
|
||||
|
||||
if ($browser->get($data->photo_200_orig, ['sink' => $file = "$path/200x.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'200x' => ($vk->cover['200x'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_200_orig,
|
||||
'public' => "/storage/$vk->id/cover/200x.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение 200x с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_200_orig);
|
||||
}
|
||||
|
||||
if (isset($data->photo_400_orig)) {
|
||||
// Получено изображение 400x
|
||||
|
||||
if ($browser->get($data->photo_400_orig, ['sink' => $file = "$path/400x.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'400x' => ($vk->cover['400x'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_400_orig,
|
||||
'public' => "/storage/$vk->id/cover/400x.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение 400x с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_400_orig);
|
||||
}
|
||||
|
||||
if (isset($data->photo_max)) {
|
||||
// Получено изображение MAXxMAX
|
||||
|
||||
if ($browser->get($data->photo_max, ['sink' => $file = "$path/MAXxMAX.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'MAXxMAX' => ($vk->cover['MAXxMAX'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_max,
|
||||
'public' => "/storage/$vk->id/cover/MAXxMAX.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение MAXxMAX с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_max);
|
||||
}
|
||||
|
||||
if (isset($data->photo_max_orig)) {
|
||||
// Получено изображение MAXx
|
||||
|
||||
if ($browser->get($data->photo_max_orig, ['sink' => $file = "$path/MAXx.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'MAXx' => ($vk->cover['MAXx'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_max_orig,
|
||||
'public' => "/storage/$vk->id/cover/MAXx.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение MAXx с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_max_orig);
|
||||
}
|
||||
|
||||
if (isset($data->crop_photo)) {
|
||||
// Получено изображение MAXx
|
||||
|
||||
if ($browser->get($data->photo_max_orig, ['sink' => $file = "$path/MAXx.jpg"])->getStatusCode() === 200)
|
||||
$vk->cover =
|
||||
($vk->cover ?? []) +
|
||||
[
|
||||
'MAXx' => ($vk->cover['MAXx'] ?? []) +
|
||||
[
|
||||
'source' => $data->photo_max_orig,
|
||||
'public' => "/storage/$vk->id/cover/MAXx.jpg",
|
||||
'local' => $file,
|
||||
]
|
||||
];
|
||||
else throw new exception('Не удалось получить изображение MAXx с серверов ВКонтакте');
|
||||
|
||||
// Удаление из списка необработанных
|
||||
unset($data->photo_max_orig);
|
||||
}
|
||||
|
||||
// Перебор оставшихся параметров
|
||||
foreach ($data as $key => $value) $vk->{$key} = $value;
|
||||
|
||||
if (document::update(static::$db->session, $vk)) {
|
||||
// Записано обновление
|
||||
|
||||
return $vk;
|
||||
} else throw new exception('Не удалось записать данные аккаунта ВКонтакте');
|
||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||
} catch (exception $e) {
|
||||
// Запись в журнал ошибок
|
||||
$errors[] = [
|
||||
'text' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'stack' => $e->getTrace()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user