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