Compare commits

...

3 Commits

9 changed files with 384 additions and 341 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
!.gitignore
composer.phar
vendor vendor

View File

@ -1,6 +1,7 @@
{ {
"name": "mirzaev/vk-arangodb", "name": "mirzaev/vk-arangodb",
"description": "Module for mirzaev/vk framework for storage data in ArangoDB", "description": "Module for mirzaev/vk framework for storage data in ArangoDB",
"readme": "README.md",
"keywords": [ "keywords": [
"ArangoDB", "ArangoDB",
"vk", "vk",
@ -30,9 +31,9 @@
], ],
"require": { "require": {
"php": "^8.1", "php": "^8.1",
"mirzaev/vk": "~4.0.1", "mirzaev/vk": "~4.0",
"mirzaev/accounts": "1.2.x-dev", "mirzaev/accounts": "~1.2",
"mirzaev/arangodb": "^1.0.0", "mirzaev/arangodb": "~1.0",
"triagens/arangodb": "~3.9.x-dev", "triagens/arangodb": "~3.9.x-dev",
"guzzlehttp/guzzle": "~7.5" "guzzlehttp/guzzle": "~7.5"
}, },

100
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "439d40833ea94e08c6dda41b6bd9e8f0", "content-hash": "8abd06dfbd8e453afbdf3eb269626390",
"packages": [ "packages": [
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
@ -220,16 +220,16 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "2.4.2", "version": "2.4.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "3148458748274be1546f8f2809a6c09fe66f44aa" "reference": "67c26b443f348a51926030c83481b85718457d3d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa", "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d",
"reference": "3148458748274be1546f8f2809a6c09fe66f44aa", "reference": "67c26b443f348a51926030c83481b85718457d3d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -319,7 +319,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/psr7/issues", "issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.4.2" "source": "https://github.com/guzzle/psr7/tree/2.4.3"
}, },
"funding": [ "funding": [
{ {
@ -335,7 +335,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-10-25T13:49:28+00:00" "time": "2022-10-26T14:07:24+00:00"
}, },
{ {
"name": "jasny/error-handler", "name": "jasny/error-handler",
@ -392,17 +392,17 @@
}, },
{ {
"name": "mirzaev/accounts", "name": "mirzaev/accounts",
"version": "1.2.x-dev", "version": "1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.hood.su/mirzaev/accounts", "url": "https://git.mirzaev.sexy/mirzaev/accounts",
"reference": "4b0a1a1c34128c281b83485cde53d97df6c82a49" "reference": "16d592432021356ee5dbbe7794574a36a48988d1"
}, },
"require": { "require": {
"ext-dom": "20031129", "ext-dom": "20031129",
"ext-libxml": "~8.0", "ext-libxml": "~8.1.1",
"guzzlehttp/guzzle": "~7.2", "guzzlehttp/guzzle": "^7.2",
"php": "~8.0" "php": "~8.1"
}, },
"require-dev": { "require-dev": {
"phpdocumentor/phpdocumentor": ">=2.9", "phpdocumentor/phpdocumentor": ">=2.9",
@ -420,31 +420,37 @@
], ],
"authors": [ "authors": [
{ {
"name": "Arsen Mirzaev", "name": "Arsen Mirzaev Tatyano-Muradovich",
"email": "red@hood.su", "email": "arsen@mirzaev.sexy",
"homepage": "https://hood.su/sex", "homepage": "https://mirzaev.sexy",
"role": "Programmer" "role": "Programmer"
} }
], ],
"description": "Менеджер аккаунтов", "description": "Simple accounts manager",
"homepage": "https://git.hood.su/mirzaev/accounts", "homepage": "https://git.mirzaev.sexy/mirzaev/accounts",
"keywords": [ "keywords": [
"accounts" "accounts"
], ],
"support": { "support": {
"chat": "https://vk.me/darkweb228", "email": "arsen@mirzaev.sexy",
"docs": "https://git.hood.su/mirzaev/accounts/manual", "issues": "https://git.mirzaev.sexy/mirzaev/accounts/issues",
"issues": "https://git.hood.su/mirzaev/accounts/issues" "wiki": "https://git.mirzaev.sexy/mirzaev/accounts/wiki"
}, },
"time": "2021-07-31T11:12:52+00:00" "funding": [
{
"url": "https://fund.mirzaev.sexy",
"type": "funding"
}
],
"time": "2022-11-05T23:47:32+00:00"
}, },
{ {
"name": "mirzaev/arangodb", "name": "mirzaev/arangodb",
"version": "1.0.0", "version": "1.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.hood.su/mirzaev/arangodb", "url": "https://git.mirzaev.sexy/mirzaev/arangodb",
"reference": "0012a31e6bea1050385f6b740581f32b9e366128" "reference": "e7da9978d01d3f8bdef6c74809dfb4eb8989f92c"
}, },
"require": { "require": {
"php": "^8.1", "php": "^8.1",
@ -471,25 +477,36 @@
"role": "Developer" "role": "Developer"
} }
], ],
"description": "Реализация управления хранилищем данных ArangoDB", "description": "Simple PHP-framework for ArangoDB",
"homepage": "https://git.hood.su/mirzaev/arangodb", "homepage": "https://git.hood.su/mirzaev/arangodb",
"keywords": [ "keywords": [
"ArangoDb" "ArangoDb"
], ],
"time": "2022-10-25T20:16:30+00:00" "support": {
"email": "arsen@mirzaev.sexy",
"issues": "https://git.mirzaev.sexy/mirzaev/arangodb/issues",
"wiki": "https://git.mirzaev.sexy/mirzaev/arangodb/manual"
},
"funding": [
{
"url": "https://fund.mirzaev.sexy",
"type": "funding"
}
],
"time": "2022-11-06T00:03:56+00:00"
}, },
{ {
"name": "mirzaev/vk", "name": "mirzaev/vk",
"version": "4.0.1", "version": "4.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.hood.su/mirzaev/vk", "url": "https://git.mirzaev.sexy/mirzaev/vk",
"reference": "850a4bbd8ef6ba232c0e810eba5f118345a862fa" "reference": "1f975c1d12ad01aa5c044ef9fbdb66505082b728"
}, },
"require": { "require": {
"guzzlehttp/guzzle": "~7.5", "guzzlehttp/guzzle": "~7.5",
"jasny/error-handler": "~0.2", "jasny/error-handler": "~0.2",
"mirzaev/accounts": "~1.2.x-dev", "mirzaev/accounts": "~1.2.0",
"monolog/monolog": "~1.6", "monolog/monolog": "~1.6",
"php": "~8.1", "php": "~8.1",
"psr/log": "~1.0" "psr/log": "~1.0"
@ -511,21 +528,21 @@
{ {
"name": "Arsen Mirzaev Tatyano-Muradovich", "name": "Arsen Mirzaev Tatyano-Muradovich",
"email": "arsen@mirzaev.sexy", "email": "arsen@mirzaev.sexy",
"homepage": "https://hood.su/mirzaev", "homepage": "https://mirzaev.sexy/mirzaev",
"role": "Programmer" "role": "Programmer"
} }
], ],
"description": "Фреймворк VK API", "description": "PHP-фреймворк ВКонтакте",
"homepage": "https://git.hood.su/mirzaev/vk", "homepage": "https://git.mirzaev.sexy/mirzaev/vk",
"keywords": [ "keywords": [
"api", "api",
"vk" "vk"
], ],
"support": { "support": {
"docs": "https://git.hood.su/mirzaev/vk/manual", "docs": "https://git.mirzaev.sexy/mirzaev/vk/wiki",
"issues": "https://git.hood.su/mirzaev/vk/issues" "issues": "https://git.mirzaev.sexy/mirzaev/vk/issues"
}, },
"time": "2022-10-23T17:22:42+00:00" "time": "2022-11-05T23:52:40+00:00"
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
@ -940,12 +957,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/arangodb/arangodb-php.git", "url": "https://github.com/arangodb/arangodb-php.git",
"reference": "de14fbcf8390e3ae1e706c52695386218eeba151" "reference": "21c460dbbd75eb5c066f9abcc3a9adf4487d6e48"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/arangodb/arangodb-php/zipball/de14fbcf8390e3ae1e706c52695386218eeba151", "url": "https://api.github.com/repos/arangodb/arangodb-php/zipball/21c460dbbd75eb5c066f9abcc3a9adf4487d6e48",
"reference": "de14fbcf8390e3ae1e706c52695386218eeba151", "reference": "21c460dbbd75eb5c066f9abcc3a9adf4487d6e48",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -993,14 +1010,13 @@
"issues": "https://github.com/arangodb/arangodb-php/issues", "issues": "https://github.com/arangodb/arangodb-php/issues",
"source": "https://github.com/arangodb/arangodb-php/tree/3.9" "source": "https://github.com/arangodb/arangodb-php/tree/3.9"
}, },
"time": "2022-02-03T09:42:22+00:00" "time": "2022-10-21T15:30:53+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": {
"mirzaev/accounts": 20,
"triagens/arangodb": 20 "triagens/arangodb": 20
}, },
"prefer-stable": false, "prefer-stable": false,

View File

@ -9,12 +9,14 @@ use mirzaev\arangodb\collection;
// Фреймворк ArangoDB // Фреймворк ArangoDB
use mirzaev\arangodb\document; use mirzaev\arangodb\document;
// Модуль ArangoDB для фреймворка ВКонтакте
use mirzaev\vk\arangodb\longpoll; use mirzaev\vk\arangodb\longpoll;
// Библиотека для работы с API-сервера ArangoDB // Библиотека для работы с API-сервера ArangoDB
use ArangoDBClient\Connection as _connection; use ArangoDBClient\Connection as _connection,
use ArangoDBClient\Statement as _statement; ArangoDBClient\Statement as _statement,
use ArangoDBClient\Document as _document; ArangoDBClient\Document as _document;
/** /**
* Журнал * Журнал

View File

@ -5,11 +5,11 @@ declare(strict_types=1);
namespace mirzaev\vk\arangodb; namespace mirzaev\vk\arangodb;
// Файлы проекта // Файлы проекта
use mirzaev\arangodb\connection; use mirzaev\arangodb\connection,
use mirzaev\arangodb\collection; mirzaev\arangodb\collection,
use mirzaev\arangodb\terminal; mirzaev\arangodb\terminal,
use mirzaev\arangodb\document; mirzaev\arangodb\document,
use mirzaev\vk\arangodb\traits\HTTP\headers\content\disposition; mirzaev\vk\arangodb\traits\HTTP\headers\content\disposition;
// Библиотека для работы с API-сервера ArangoDB // Библиотека для работы с API-сервера ArangoDB
use ArangoDBClient\Document as _document; use ArangoDBClient\Document as _document;
@ -32,7 +32,7 @@ class longpoll
disposition::filename as disposition_filename; disposition::filename as disposition_filename;
} }
const COLLECTION_USERS = 'user'; const COLLECTION_ACCOUNTS = 'account';
const COLLECTION_GROUPS = 'group'; const COLLECTION_GROUPS = 'group';
const COLLECTION_CHATS = 'chat'; const COLLECTION_CHATS = 'chat';
const COLLECTION_MESSAGES = 'message'; const COLLECTION_MESSAGES = 'message';
@ -69,6 +69,7 @@ class longpoll
return true; return true;
} }
} catch (Exception $e) { } catch (Exception $e) {
// Запись ошибки в буфер вывода
terminal::write($e->getMessage() . PHP_EOL . $e->getFile() . ':' . $e->getLine()); terminal::write($e->getMessage() . PHP_EOL . $e->getFile() . ':' . $e->getLine());
} }
@ -78,8 +79,6 @@ class longpoll
/** /**
* Событие: "message_new" * Событие: "message_new"
* *
* Новое сообщение
*
* @param array $data Данные сообщения * @param array $data Данные сообщения
* @param int $group Идентификатор группы * @param int $group Идентификатор группы
* @param string $event Идентификатор события * @param string $event Идентификатор события
@ -91,17 +90,15 @@ class longpoll
if ($this->connection->create) { if ($this->connection->create) {
// Запрошено создание коллекций в случае их отсутствия // Запрошено создание коллекций в случае их отсутствия
collection::init($this->connection->session, static::COLLECTION_USERS); // Инициализация коллекций
collection::init($this->connection->session, static::COLLECTION_ACCOUNTS);
collection::init($this->connection->session, static::COLLECTION_MESSAGES); collection::init($this->connection->session, static::COLLECTION_MESSAGES);
} }
if ($message = document::write($this->connection->session, static::COLLECTION_MESSAGES, static::messages($data, true))) { if ($message = document::write($this->connection->session, static::COLLECTION_MESSAGES, static::messages($data, $data['message']['from_id']))) {
// Записано сообщение // Записано сообщение
// Инициализация коллекции // Инициализация субъектов
$collection = static::COLLECTION_MESSAGES;
// Инициализация аккаунтов
$from = ('mirzaev\\vk\\arangodb\\vk\\' . static::type($data['message']['from_id']))::init($this->connection->session, $data['message']['from_id']); $from = ('mirzaev\\vk\\arangodb\\vk\\' . static::type($data['message']['from_id']))::init($this->connection->session, $data['message']['from_id']);
$to = ('mirzaev\\vk\\arangodb\\vk\\' . static::type($data['message']['peer_id']))::init($this->connection->session, $data['message']['peer_id']); $to = ('mirzaev\\vk\\arangodb\\vk\\' . static::type($data['message']['peer_id']))::init($this->connection->session, $data['message']['peer_id']);
@ -111,14 +108,15 @@ class longpoll
if ($this->connection->create) { if ($this->connection->create) {
// Запрошено создание коллекций в случае их отсутствия // Запрошено создание коллекций в случае их отсутствия
// Инициализация коллекции
collection::init($this->connection->session, static::COLLECTION_ACCESSED, edge: true); collection::init($this->connection->session, static::COLLECTION_ACCESSED, edge: true);
} }
if (document::write($this->connection->session, static::COLLECTION_ACCESSED, [], ['_from' => $from->getId(), '_to' => $message])) { if (document::write($this->connection->session, static::COLLECTION_ACCESSED, ['_from' => $from->getId(), '_to' => $message])) {
// Записано ребро: АККАУНТ (отправитель) -> СООБЩЕНИЕ // Записано ребро: АККАУНТ (отправитель) -> СООБЩЕНИЕ
} }
if (document::write($this->connection->session, static::COLLECTION_ACCESSED, [], ['_from' => $message, '_to' => $to->getId()])) { if (document::write($this->connection->session, static::COLLECTION_ACCESSED, ['_from' => $message, '_to' => $to->getId()])) {
// Записно ребро: СООБЩЕНИЕ -> АККАУНТ (получатель) // Записно ребро: СООБЩЕНИЕ -> АККАУНТ (получатель)
} }
} }
@ -127,12 +125,16 @@ class longpoll
if ($this->journal && journal::init($this->connection->session, $message)->write('create', [ if ($this->journal && journal::init($this->connection->session, $message)->write('create', [
'account' => $from, 'account' => $from,
'changes' => [ 'changes' => [
'new' => collection::search($this->connection->session, <<<AQL 'new' => collection::search($this->connection->session, sprintf(
FOR a IN $collection <<<'AQL'
FILTER a._id == $message FOR a IN %s
LIMIT 1 FILTER a._id == "%s"
RETURN a.data LIMIT 1
AQL), RETURN a.data
AQL,
static::COLLECTION_MESSAGES,
$message
)),
'old' => null 'old' => null
] ]
])) { ])) {
@ -150,8 +152,8 @@ class longpoll
* Обработка сообщений * Обработка сообщений
* *
* @param array $messages Сообщения или сообщение * @param array $messages Сообщения или сообщение
* @param bool $download Активация скачивания файлов на сервер * @param ?int $id Идентификатор аккаунта которому принадлежат вложения
* @param bool $clean Активация очистки массива от пустых данных сообщения * @param bool $clean Очистить массив от пустых данных?
* *
* @return array Обработанные сообщения (зависит от входных данных) * @return array Обработанные сообщения (зависит от входных данных)
* *
@ -163,94 +165,87 @@ class longpoll
* 5. Переделать $message['vk']['metadata']['conversation']['members']['amount_test'] (или удалить) * 5. Переделать $message['vk']['metadata']['conversation']['members']['amount_test'] (или удалить)
* 6. Разобраться с "Мультидиалогом" для старых версий API и существует ли он в новых * 6. Разобраться с "Мультидиалогом" для старых версий API и существует ли он в новых
*/ */
public static function messages(array $messages, bool $download = false, bool $clean = true): array public static function messages(array $messages, ?int $id = null, bool $clean = true): array
{ {
if (isset($messages['message'])) { // Универсализация входных данных - передано одно сообщение
// Передано одно сообщение if (isset($messages['message'])) $buffer[] = &$messages;
// Инициализация
$buffer[] = &$messages;
}
foreach ($buffer ?? $messages as &$message) { foreach ($buffer ?? $messages as &$message) {
// Перебор сообщений // Перебор сообщений
// Инициализация сообщения
$message = [ $message = [
'data' => [ 'id' => [
'id' => [ 'global' => $message['message']['id'],
'global' => $message['message']['id'], 'local' => $message['message']['conversation_message_id']
'local' => $message['message']['conversation_message_id']
],
'text' => $message['message']['text'] ?? $message['message']['body'],
'forward' => static::messages($message['message']['fwd_messages']),
'reply' => static::messages($message['message']['fwd_messages']),
'attachments' => static::attachments($message['message']['attachments'], $download, $clean)
], ],
'metadata' => [ 'text' => $message['message']['text'] ?? $message['message']['body'],
'date' => [ 'forward' => static::messages($message['message']['fwd_messages']),
'create' => $message['message']['date'] ?? null, 'reply' => static::messages($message['message']['fwd_messages']),
'update' => $message['message']['update_time'] ?? null 'attachments' => static::attachments($message['message']['attachments'], $id, $clean),
'date' => [
'create' => $message['message']['date'] ?? null,
'update' => $message['message']['update_time'] ?? null
],
'action' => [
'type' => $message['message']['action'] ?? null,
'target' => [
'id' => $message['message']['action']['member_id'] ?? null
], ],
'action' => [ 'text' => $message['message']['action']['text'] ?? null,
'type' => $message['message']['action'] ?? null, 'email ' => $message['message']['action']['email'] ?? null,
'target' => [ 'cover ' => $message['message']['action']['photo'] ?? null
'id' => $message['message']['action']['member_id'] ?? null ],
], 'hash' => $message['message']['random_id'] ?? null,
'text' => $message['message']['action']['text'] ?? null, 'type' => $message['message']['out'] ?? null,
'email ' => $message['message']['action']['email'] ?? null, 'admin' => [
'cover ' => $message['message']['action']['photo'] ?? null 'id' => $message['message']['admin_author_id'] ?? null
], ],
'hash' => $message['message']['random_id'] ?? null, 'pinned' => [
'type' => $message['message']['out'] ?? null, 'date' => $message['message']['pinned_at'] ?? null
],
'emoji' => $message['message']['emoji'] ?? null,
'readed' => $message['message']['read_state'] ?? null,
'listened' => $message['message']['was_listened'] ?? null,
'hidden' => $message['message']['is_hidden'] ?? null,
'cropped' => $message['message']['is_cropped'] ?? null,
'deleted' => $message['message']['deleted'] ?? null,
'conversation' =>
[
'id' => $message['message']['chat_id'] ?? null,
'admin' => [ 'admin' => [
'id' => $message['message']['admin_author_id'] ?? null 'id' => $message['message']['admin_id'] ?? null
], ],
'pinned' => [ 'title' => $message['message']['title'] ?? null,
'date' => $message['message']['pinned_at'] ?? null 'members' => [
'amount' => $message['message']['members_count'] ?? null,
'amount_test' => $message['message']['users_count'] ?? null
], ],
'emoji' => $message['message']['emoji'] ?? null, 'active' => $message['message']['chat_active'] ?? null,
'readed' => $message['message']['read_state'] ?? null, 'settings' => [
'listened' => $message['message']['was_listened'] ?? null, 'push' => $message['message']['push_settings'] ?? null
'hidden' => $message['message']['is_hidden'] ?? null, ]
'cropped' => $message['message']['is_cropped'] ?? null, ],
'deleted' => $message['message']['deleted'] ?? null, 'important' => $message['message']['important'] ?? null,
'conversation' => 'source' => [
[ 'from' => $message['message']['ref'] ?? null,
'id' => $message['message']['chat_id'] ?? null, 'data' => $message['message']['ref_source'] ?? null
'admin' => [ ],
'id' => $message['message']['admin_id'] ?? null 'payload' => $message['message']['payload'] ?? null,
], 'geo' => [
'title' => $message['message']['title'] ?? null, $message['message']['geo'] ?? null
'members' => [ ],
'amount' => $message['message']['members_count'] ?? null, 'keyboard' => [
'amount_test' => $message['message']['users_count'] ?? null 'block' => $message['client_info']['keyboard'] ?? null,
], 'inline' => $message['client_info']['inline_keyboard'] ?? null,
'active' => $message['message']['chat_active'] ?? null, 'buttons' => $message['client_info']['button_actions'] ?? null,
'settings' => [ ],
'push' => $message['message']['push_settings'] ?? null 'carousel' => $message['client_info']['carousel'] ?? null,
] 'language' => $message['client_info']['lang_id'] ?? null,
],
'important' => $message['message']['important'] ?? null,
'source' => [
'from' => $message['message']['ref'] ?? null,
'data' => $message['message']['ref_source'] ?? null
],
'payload' => $message['message']['payload'] ?? null,
'geo' => [
$message['message']['geo'] ?? null
],
'keyboard' => [
'block' => $message['client_info']['keyboard'] ?? null,
'inline' => $message['client_info']['inline_keyboard'] ?? null,
'buttons' => $message['client_info']['button_actions'] ?? null,
],
'carousel' => $message['client_info']['carousel'] ?? null,
'language' => $message['client_info']['lang_id'] ?? null,
]
]; ];
} }
// Очистка массива, если активировано // Очистка массива
$clean and static::cleaner($messages); $clean and static::cleaner($messages);
return $messages; return $messages;
@ -260,12 +255,12 @@ class longpoll
* Обработка вложений * Обработка вложений
* *
* @param array $attachments Вложения * @param array $attachments Вложения
* @param bool $download Активация скачивания файлов на сервер * @param ?int $id Идентификатор аккаунта которому принадлежат изображения
* @param bool $clean Активация очистки массива от пустых данных сообщения * @param bool $clean Очистить массив от пустых данных?
* *
* @return array Обработанные вложения * @return array Обработанные вложения
*/ */
public static function attachments(array $attachments, bool $download = false, bool $clean = false): array public static function attachments(array $attachments, ?int $id = null, bool $clean = true): array
{ {
foreach ($attachments as &$attachment) { foreach ($attachments as &$attachment) {
// Перебор вложений // Перебор вложений
@ -289,7 +284,7 @@ class longpoll
'key' => $attachment['photo']['access_key'] ?? null 'key' => $attachment['photo']['access_key'] ?? null
], ],
'text' => $attachment['photo']['text'] ?? null, 'text' => $attachment['photo']['text'] ?? null,
'storage' => static::sizes($attachment['photo']['sizes'], $download) ?? null 'storage' => static::sizes($attachment['photo']['sizes'], $id) ?? null
], ],
'metadata' => [ 'metadata' => [
'type' => $attachment['type'] ?? null 'type' => $attachment['type'] ?? null
@ -298,36 +293,35 @@ class longpoll
} }
} }
// Очистка массива, если активировано // Очистка массива
$clean and static::cleaner($attachments); $clean and static::cleaner($attachments);
return $attachments; return $attachments;
} }
/** /**
* Сортировка размеров файла из вложения * Сортировка размеров изображения из вложения
*
* @param array $sizes Размеры файла согласно спецификации в API
* @param bool $download Активация скачивания файлов на сервер
* @param int|null $id Идентификатор аккаунта кому принадлежат изображения
*
* @return array Обработанные размеры
* *
* @see https://vk.com/dev/photo_sizes * @see https://vk.com/dev/photo_sizes
*
* @param array $sizes Размеры изображения согласно спецификации в API
* @param ?int $id Идентификатор аккаунта которому принадлежат изображения
*
* @return array Обработанные размеры
*/ */
public static function sizes(array $sizes, bool $download = false, int|null $id = null): array public static function sizes(array $sizes, ?int $id = null): array
{ {
foreach ($sizes as &$size) { foreach ($sizes as &$size) {
// Перебор размеров // Перебор размеров
if ($download) { if (isset($id)) {
// Запрошено сохранение на сервер // Запрошена запись файлов на сервер
// Инициализация // Инициализация
$browser = new Guzzle(); $browser = new Guzzle();
// Инициализация директории // Инициализация директории
if (!file_exists($path = static::$path_storage . (isset($id) ? static::$path_storage_accounts . PHP_EOL . $id : static::$path_storage_vk) . static::$path_storage_accounts_images . PHP_EOL . date('Y_m_d', time()))) if (!file_exists($path = static::$path_storage . static::$path_storage_accounts . PHP_EOL . $id . static::$path_storage_accounts_images . PHP_EOL . date('Y_m_d', time())))
if (!mkdir($path, 0755, true)) if (!mkdir($path, 0755, true))
throw new Exception('Не удалось инициализировать директорию: ' . $path); throw new Exception('Не удалось инициализировать директорию: ' . $path);
@ -371,8 +365,13 @@ class longpoll
return $sizes; return $sizes;
} }
/**
// Инициализация * Очистить массив от пустых значений
*
* @param array $target Обрабатываемый массив
*
* @return bool Массив был изменён?
*/
public static function cleaner(array &$target): bool public static function cleaner(array &$target): bool
{ {
// Инициализация // Инициализация
@ -400,9 +399,16 @@ class longpoll
return $changes; return $changes;
} }
public function truncate() /**
* Очистить базу данных
*
* Предполагается использование для автоматизации тестирования
*
* @return void
*/
public function truncate(): void
{ {
collection::truncate($this->connection->session, static::COLLECTION_USERS); collection::truncate($this->connection->session, static::COLLECTION_ACCOUNTS);
collection::truncate($this->connection->session, static::COLLECTION_GROUPS); collection::truncate($this->connection->session, static::COLLECTION_GROUPS);
collection::truncate($this->connection->session, static::COLLECTION_CHATS); collection::truncate($this->connection->session, static::COLLECTION_CHATS);
collection::truncate($this->connection->session, static::COLLECTION_MESSAGES); collection::truncate($this->connection->session, static::COLLECTION_MESSAGES);
@ -411,11 +417,11 @@ class longpoll
} }
/** /**
* Определить тип аккаунта * Определить тип субъекта
* *
* @param int $id Идентификатор * @param int $id Идентификатор
* *
* @return string Возвращает 'user', если не прошли другие проверки * @return string Возвращает static::COLLECTION_ACCOUNTS, если не прошли другие проверки
*/ */
public static function type(int $id): string public static function type(int $id): string
{ {
@ -423,8 +429,9 @@ class longpoll
if ($id - 2000000000 >= 0) return static::COLLECTION_CHATS; if ($id - 2000000000 >= 0) return static::COLLECTION_CHATS;
// Группа // Группа
if (((string) $id)[0] === '-') return static::COLLECTION_GROUPS; if ($id < 0) return static::COLLECTION_GROUPS;
return static::COLLECTION_USERS; // Аккаунт
return static::COLLECTION_ACCOUNTS;
} }
} }

View File

@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace mirzaev\vk\arangodb\vk;
// Модуль ArangoDB для фреймворка ВКонтакте
use mirzaev\vk\arangodb\longpoll,
mirzaev\vk\arangodb\journal;
// Фреймворк ArangoDB
use mirzaev\arangodb\collection,
mirzaev\arangodb\document;
// Библиотека для работы с API ArabgoDB
use ArangoDBClient\Document as _document,
ArangoDBClient\Connection as _connection;
/**
* Аккаунт ВКонтакте
*
* @package mirzaev\vk\arangodb\vk
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
class account
{
/**
* Инициализировать
*
* @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте
* @param bool $journal Записывать в журнал?
* @param bool $create Создавать коллекции при их отсутствии?
*
* @return ?_document Инстанция документа
*/
public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document
{
if ($create) {
// Запрошено создание коллекций в случае их отсутствия
// Инициализация коллекции
collection::init($session, longpoll::COLLECTION_ACCOUNTS);
}
// Поиск
if ($account = static::search($session, $id));
else if ($account = document::write($session, longpoll::COLLECTION_ACCOUNTS, ['id' => $id]) and $journal)
journal::init($session, $account)->write('create', [
'changes' => [
'new' => collection::search($session, sprintf(
<<<'AQL'
FOR x IN %s
FILTER x._id == "%s"
LIMIT 1
RETURN x
AQL,
longpoll::COLLECTION_ACCOUNTS,
$account
)),
'old' => null
]
]);
// Поиск
return static::search($session, $id);
}
/**
* Найти
*
* @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте
*
* @return ?_document Инстанция документа
*/
public static function search(_connection $session, int $id): ?_document
{
return collection::search($session, sprintf(
<<<'AQL'
FOR x IN %s
FILTER x.id == %u
LIMIT 1
RETURN x
AQL,
longpoll::COLLECTION_ACCOUNTS,
$id
));
}
}

View File

@ -4,14 +4,24 @@ declare(strict_types=1);
namespace mirzaev\vk\arangodb\vk; namespace mirzaev\vk\arangodb\vk;
use mirzaev\vk\arangodb\longpoll; // Модуль ArangoDB для фреймворка ВКонтакте
use mirzaev\vk\arangodb\journal; use mirzaev\vk\arangodb\longpoll,
use mirzaev\arangodb\collection; mirzaev\vk\arangodb\journal;
use mirzaev\arangodb\document;
use ArangoDBClient\Document as _document;
use ArangoDBClient\Connection as _connection; // Фреймворк ArangoDB
use mirzaev\arangodb\collection,
mirzaev\arangodb\document;
// Библиотека для работы с API ArabgoDB
use ArangoDBClient\Document as _document,
ArangoDBClient\Connection as _connection;
/**
* Чат ВКонтакте
*
* @package mirzaev\vk\arangodb\vk
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
class chat class chat
{ {
/** /**
@ -19,64 +29,62 @@ class chat
* *
* @param _connection $session Сессия соединения с базой данных * @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте * @param int $id Идентификатор ВКонтакте
* @param bool $journal Записывать в журнал * @param bool $journal Записывать в журнал?
* @param bool $create Создавать коллекции при их отсутствии * @param bool $create Создавать коллекции при их отсутствии?
* *
* @return ?_document Инстанция документа * @return ?_document Инстанция документа
*/ */
public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document
{ {
// Инициализация коллекции
$collection = longpoll::COLLECTION_CHATS;
if ($create) { if ($create) {
// Запрошено создание коллекций в случае их отсутствия // Запрошено создание коллекций в случае их отсутствия
// Создание коллекции // Создание коллекции
collection::init($session, $collection); collection::init($session, longpoll::COLLECTION_CHATS);
} }
if ($account = collection::search($session, <<<AQL // Поиск
FOR x IN $collection if ($chat = static::search($session, $id));
FILTER x.data.data.id == $id else if ($chat = document::write($session, longpoll::COLLECTION_CHATS, ['id' => $id]) and $journal)
LIMIT 1 journal::init($session, $chat)->write('create', [
RETURN x.data
AQL)) {
// Найден аккаунт
return $account;
}
if ($account = document::write($session, $collection, ['data' => ['id' => $id]])) {
// Аккаунт записан
// Журналирование
if ($journal && journal::init($session, $account)->write('create', [
'changes' => [ 'changes' => [
'new' => collection::search($session, <<<AQL 'new' => collection::search($session, sprintf(
FOR a IN $collection <<<'AQL'
FILTER a._id == $account FOR x IN %s
FILTER x._id == "%s"
LIMIT 1 LIMIT 1
RETURN a.data RETURN x
AQL), AQL,
longpoll::COLLECTION_CHATS,
$chat
)),
'old' => null 'old' => null
] ]
])) { ]);
// Записаны данные в журнал
}
if ($account = collection::search($session, <<<AQL // Поиск
FOR x IN $collection return static::search($session, $id);
FILTER x.data.data.id == $id }
LIMIT 1
RETURN x
AQL)) {
// Найден аккаунт
return $account; /**
} * Найти в базе данных
} *
* @param _connection $session Сессия соединения с базой данных
return null; * @param int $id Идентификатор ВКонтакте
*
* @return ?_document Инстанция документа
*/
public static function search(_connection $session, int $id): ?_document
{
return collection::search($session, sprintf(
<<<'AQL'
FOR x IN %s
FILTER x.id == %u
LIMIT 1
RETURN x
AQL,
longpoll::COLLECTION_CHATS,
$id
));
} }
} }

View File

@ -19,64 +19,63 @@ class group
* *
* @param _connection $session Сессия соединения с базой данных * @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте * @param int $id Идентификатор ВКонтакте
* @param bool $journal Записывать в журнал * @param bool $journal Записывать в журнал?
* @param bool $create Создавать коллекции при их отсутствии * @param bool $create Создавать коллекции при их отсутствии?
* *
* @return ?_document Инстанция документа * @return ?_document Инстанция документа
*/ */
public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document
{ {
// Инициализация коллекции
$collection = longpoll::COLLECTION_GROUPS;
if ($create) { if ($create) {
// Запрошено создание коллекций в случае их отсутствия // Запрошено создание коллекций в случае их отсутствия
// Создание коллекции // Создание коллекции
collection::init($session, $collection); collection::init($session, longpoll::COLLECTION_GROUPS);
} }
if ($account = collection::search($session, <<<AQL // Поиск
FOR x IN $collection if ($group = static::search($session, $id));
FILTER x.data.data.id == $id else if ($group = document::write($session, longpoll::COLLECTION_GROUPS, ['id' => $id]) and $journal)
LIMIT 1 journal::init($session, $group)->write('create', [
RETURN x.data
AQL)) {
// Найден аккаунт
return $account;
}
if ($account = document::write($session, $collection, ['data' => ['id' => $id]])) {
// Аккаунт записан
// Журналирование
if ($journal && journal::init($session, $account)->write('create', [
'changes' => [ 'changes' => [
'new' => collection::search($session, <<<AQL 'new' => collection::search($session, sprintf(
FOR a IN $collection <<<'AQL'
FILTER a._id == $account FOR x IN %s
FILTER x._id == "%s"
LIMIT 1 LIMIT 1
RETURN a.data RETURN x
AQL), AQL,
longpoll::COLLECTION_GROUPS,
$group
)),
'old' => null 'old' => null
] ]
])) { ]);
// Записаны данные в журнал
}
if ($account = collection::search($session, <<<AQL
FOR x IN $collection
FILTER x.data.data.id == $id
LIMIT 1
RETURN x
AQL)) {
// Найден аккаунт
return $account; // Поиск
} return static::search($session, $id);
} }
return null; /**
* Найти в базе данных
*
* @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте
*
* @return ?_document Инстанция документа
*/
public static function search(_connection $session, int $id): ?_document
{
return collection::search($session, sprintf(
<<<'AQL'
FOR x IN %s
FILTER x.id == %d
LIMIT 1
RETURN x
AQL,
longpoll::COLLECTION_GROUPS,
$id
));
} }
} }

View File

@ -1,82 +0,0 @@
<?php
declare(strict_types=1);
namespace mirzaev\vk\arangodb\vk;
use mirzaev\vk\arangodb\longpoll;
use mirzaev\vk\arangodb\journal;
use mirzaev\arangodb\collection;
use mirzaev\arangodb\document;
use ArangoDBClient\Document as _document;
use ArangoDBClient\Connection as _connection;
class user
{
/**
* Инициализация
*
* @param _connection $session Сессия соединения с базой данных
* @param int $id Идентификатор ВКонтакте
* @param bool $journal Записывать в журнал
* @param bool $create Создавать коллекции при их отсутствии
*
* @return ?_document Инстанция документа
*/
public static function init(_connection $session, int $id, bool $journal = true, bool $create = true): ?_document
{
// Инициализация коллекции
$collection = longpoll::COLLECTION_USERS;
if ($create) {
// Запрошено создание коллекций в случае их отсутствия
// Создание коллекции
collection::init($session, $collection);
}
if ($account = collection::search($session, <<<AQL
FOR x IN $collection
FILTER x.id == $id
LIMIT 1
RETURN x
AQL)) {
// Найден аккаунт
return $account;
}
if ($account = document::write($session, $collection, ['id' => $id])) {
// Аккаунт записан
// Журналирование
if ($journal && journal::init($session, $account)->write('create', [
'changes' => [
'new' => collection::search($session, <<<AQL
FOR a IN $collection
FILTER a._id == $account
LIMIT 1
RETURN a.data
AQL),
'old' => null
]
])) {
// Записаны данные в журнал
}
if ($account = collection::search($session, <<<AQL
FOR x IN $collection
FILTER x.data.data.id == $id
LIMIT 1
RETURN x
AQL)) {
// Найден аккаунт
return $account;
}
}
return null;
}
}