<?php declare(strict_types=1); namespace mirzaev\site\account\models; // Файлы проекта use mirzaev\site\account\models\vk; // Фреймворк ArangoDB use mirzaev\arangodb\collection, mirzaev\arangodb\document; // Библиотека для ArangoDB use ArangoDBClient\Document as _document; // Встроенные библиотеки use exception; /** * Модель аккаунта * * @package mirzaev\site\account\models * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> */ final class account extends core { /** * Коллекция */ public const COLLECTION = 'account'; /** * Инстанция в базе данных */ public ?_document $instance; /** * Прочитать * * @param string $login Входной псевдоним * @param array &$errors Журнал ошибок * * @return ?self Инстанция аккаунта, если найден */ public static function read(string $login, array &$errors = []): ?self { try { if (collection::init(static::$db->session, self::COLLECTION)) { // Инициализирована коллекция // Инициализация инстанции аккаунта $instance = new self; // Поиск аккаунта $instance->instance = collection::search( static::$db->session, sprintf( <<<AQL FOR d IN %s FILTER d.login == '%s' RETURN d AQL, self::COLLECTION, $login ) ); return $instance; } throw new exception('Не удалось инициализировать коллекцию'); } catch (exception $e) { // Запись в журнал ошибок $errors[] = [ 'text' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), 'stack' => $e->getTrace() ]; } return null; } /** * Создать * * @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; } }