From ced4e3241c9ea2f6018611f77ed571e274113852 Mon Sep 17 00:00:00 2001 From: Little Fluffy Clouds Date: Thu, 10 Jul 2025 18:08:08 +0300 Subject: [PATCH] read database util and file cleanup --- mirzaev/deeproots/system/models/telegram.php | 282 ++-- .../system/models/telegram/commands.php | 1430 ++++++++--------- mirzaev/deeproots/system/public/index.php | 28 +- mirzaev/deeproots/system/public/telegram.php | 30 +- .../system/test/utils/database_read.php | 39 + 5 files changed, 924 insertions(+), 885 deletions(-) create mode 100644 mirzaev/deeproots/system/test/utils/database_read.php diff --git a/mirzaev/deeproots/system/models/telegram.php b/mirzaev/deeproots/system/models/telegram.php index 9bdb48d..ce08035 100755 --- a/mirzaev/deeproots/system/models/telegram.php +++ b/mirzaev/deeproots/system/models/telegram.php @@ -6,24 +6,24 @@ namespace mirzaev\deeproots\models; // Files of the project use mirzaev\deeproots\models\core, - mirzaev\deeproots\models\account\localization; + mirzaev\deeproots\models\account\localization; // Svoboda time use svoboda\time\statement as svoboda; // Baza database use mirzaev\baza\database, - mirzaev\baza\column, - mirzaev\baza\record, - mirzaev\baza\enumerations\encoding, - mirzaev\baza\enumerations\type; + mirzaev\baza\column, + mirzaev\baza\record, + mirzaev\baza\enumerations\encoding, + mirzaev\baza\enumerations\type; // Framework for Telegram use Zanzara\Telegram\Type\User as model; // Built-in libraries use Exception as exception, - RuntimeException as exception_runtime; + RuntimeException as exception_runtime; /** * Telegram account @@ -35,158 +35,158 @@ use Exception as exception, */ final class telegram extends core { - /** - * File - * - * @var string $database Path to the database file - */ - protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'telegram.baza'; + /** + * File + * + * @var string $database Path to the database file + */ + protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'telegram.baza'; - /** - * Database - * - * @var database $database The database - */ - public protected(set) database $database; + /** + * Database + * + * @var database $database The database + */ + public protected(set) database $database; - /** - * Constructor - * - * @return void - */ - public function __construct() - { - // Initializing the database - $this->database = new database() - ->encoding(encoding::utf8) - ->columns( - new column('identifier', type::integer_unsigned), - new column('domain', type::string, ['length' => 32]), - new column('name_first', type::string, ['length' => 64]), - new column('name_second', type::string, ['length' => 64]), - new column('language', type::string, ['length' => 2]), - new column('robot', type::char), - new column('updated', type::integer_unsigned), - new column('created', type::integer_unsigned) - ) - ->connect($this->file); - } + /** + * Constructor + * + * @return void + */ + public function __construct() + { + // Initializing the database + $this->database = new database() + ->encoding(encoding::utf8) + ->columns( + new column('identifier', type::integer_unsigned), + new column('domain', type::string, ['length' => 32]), + new column('name_first', type::string, ['length' => 64]), + new column('name_second', type::string, ['length' => 64]), + new column('language', type::string, ['length' => 2]), + new column('robot', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($this->file); + } - /** - * Initialize - * - * Searches for the telegram account record in the database, and if it does not find it, then create - * - * @param model $telegram The telegram account - * - * @throws exception_runtime if update the telegram account record in the database by the telegram account values - * @throws exception_runtime if failed to find the created telegram account - * @throws exception_runtime if failed to create the telegram account - * - * @return record The telegram account record from the database - */ - public function initialize(model $telegram): record - { - // Searching for the account in the database - $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; + /** + * Initialize + * + * Searches for the telegram account record in the database, and if it does not find it, then create + * + * @param model $telegram The telegram account + * + * @throws exception_runtime if failed to update the telegram account record in the database by the telegram account values + * @throws exception_runtime if failed to find the created telegram account + * @throws exception_runtime if failed to create the telegram account + * + * @return record The telegram account record from the database + */ + public function initialize(model $telegram): record + { + // Searching for the account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; - if ($account instanceof record) { - // Found the telegram account record + if ($account instanceof record) { + // Found the telegram account record - if ( - $account->name_first !== $telegram->getFirstName() || - $account->name_second !== $telegram->getLastName() || - $account->domain !== $telegram->getUsername() - ) { - // The telegram account was updated - - // Updating the account in the database - $updated = $this->database->read( - filter: fn(record $record) => $record->identifier === $telegram->getId(), - update: function (record &$record) use ($telegram){ - // Writing new values into the record - $record->name_first = $telegram->getFirstName(); - $record->name_second = $telegram->getLastName(); - $record->domain = $telegram->getUsername(); - $record->updated = svoboda::timestamp(); - }, - amount: 1 - )[0] ?? null; + if ( + $account->name_first !== $telegram->getFirstName() || + $account->name_second !== $telegram->getLastName() || + $account->domain !== $telegram->getUsername() + ) { + // The telegram account was updated - if ($updated instanceof record && $updated->values() !== $account->values()) { - // Updated the account in the database + // Updating the account in the database + $updated = $this->database->read( + filter: fn(record $record) => $record->identifier === $telegram->getId(), + update: function (record &$record) use ($telegram){ + // Writing new values into the record + $record->name_first = $telegram->getFirstName(); + $record->name_second = $telegram->getLastName(); + $record->domain = $telegram->getUsername(); + $record->updated = svoboda::timestamp(); + }, + amount: 1 + )[0] ?? null; - // Exit (success) - return $updated; - } else { - // Not updated the account in the database + if ($updated instanceof record && $updated->values() !== $account->values()) { + // Updated the account in the database - // Exit (fail) - throw new exception_runtime('Failed to update the account record in the database by the telegram account values'); - } - } + // Exit (success) + return $updated; + } else { + // Not updated the account in the database - // Exit (success) - return $account; - } else { - // Not found the account record + // Exit (fail) + throw new exception_runtime('Failed to update the account record in the database by the telegram account values'); + } + } - if ($this->create($telegram)) { - // Created the account + // Exit (success) + return $account; + } else { + // Not found the account record - // Searching for the created telegram account in the database - $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; + if ($this->create($telegram)) { + // Created the account - if ($account instanceof record) { - // Found the created telegram account + // Searching for the created telegram account in the database + $account = $this->database->read(filter: fn(record $record) => $record->identifier === $telegram->getId(), amount: 1)[0] ?? null; - // Exit (success) - return $account; - } else { - // Not found the created telegram account + if ($account instanceof record) { + // Found the created telegram account - // Exit (fail) - throw new exception_runtime('Failed to find the created telegram account'); - } - } else { - // Not created the telegram account + // Exit (success) + return $account; + } else { + // Not found the created telegram account - // Exit (fail) - throw new exception_runtime('Failed to create the telegram account'); - } - } - } + // Exit (fail) + throw new exception_runtime('Failed to find the created telegram account'); + } + } else { + // Not created the telegram account - /** - * Create - * - * Creates the account record in the database - * - * @param model $telegram The telegram account - * - * @return int|false The record identifier, if created - */ - public function create(model $telegram): int|false - { - // Initializing the identifier - $identifier = (int) $telegram->getId(); + // Exit (fail) + throw new exception_runtime('Failed to create the telegram account'); + } + } + } - // Initializing the record - $record = $this->database->record( - $identifier, - $telegram->getUsername(), - $telegram->getFirstName(), - $telegram->getLastName(), - $telegram->getLanguageCode(), - (int) $telegram->isBot(), - svoboda::timestamp(), - svoboda::timestamp() - ); + /** + * Create + * + * Creates the account record in the database + * + * @param model $telegram The telegram account + * + * @return int|false The record identifier, if created + */ + public function create(model $telegram): int|false + { + // Initializing the identifier + $identifier = (int) $telegram->getId(); - // Creating the record in the database - $created = $this->database->write($record); + // Initializing the record + $record = $this->database->record( + $identifier, + $telegram->getUsername(), + $telegram->getFirstName(), + $telegram->getLastName(), + $telegram->getLanguageCode(), + (int) $telegram->isBot(), + svoboda::timestamp(), + svoboda::timestamp() + ); - // Exit (success) - return $created ? $identifier : false; - } + // Creating the record in the database + $created = $this->database->write($record); + + // Exit (success) + return $created ? $identifier : false; + } } diff --git a/mirzaev/deeproots/system/models/telegram/commands.php b/mirzaev/deeproots/system/models/telegram/commands.php index d7a8eb7..e50feaf 100755 --- a/mirzaev/deeproots/system/models/telegram/commands.php +++ b/mirzaev/deeproots/system/models/telegram/commands.php @@ -6,17 +6,17 @@ namespace mirzaev\deeproots\models\telegram; // Files of the project use mirzaev\deeproots\models\core, - mirzaev\deeproots\models\account, - mirzaev\deeproots\models\question, - mirzaev\deeproots\models\question\localization as question_localization, - mirzaev\deeproots\models\answer, - mirzaev\deeproots\models\telegram\processes\language\select as process_language_select, - mirzaev\deeproots\models\enumerations\language; + mirzaev\deeproots\models\account, + mirzaev\deeproots\models\question, + mirzaev\deeproots\models\question\localization as question_localization, + mirzaev\deeproots\models\answer, + mirzaev\deeproots\models\telegram\processes\language\select as process_language_select, + mirzaev\deeproots\models\enumerations\language; // Framework for Telegram use Zanzara\Context as context, - Zanzara\Telegram\Type\Message as message, - Zanzara\Telegram\Type\Input\InputFile as file_input; + Zanzara\Telegram\Type\Message as message, + Zanzara\Telegram\Type\Input\InputFile as file_input; // Baza database use mirzaev\baza\record; @@ -31,711 +31,711 @@ use mirzaev\baza\record; */ final class commands extends core { - /** - * Menu - * - * Responce for the commands: "/start", '/menu' - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function menu(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing the title - $title = 'πŸ“‹ *' . $localization['menu_title'] . '*'; - - // Sending the message - $context->sendMessage( - << [ - 'inline_keyboard' => [ - [ - [ - 'text' => '🧠 ' . $localization['menu_button_start'], - 'callback_data' => 'projects' - ] - ], - [ - [ - 'text' => 'πŸ“ˆ ' . $localization['menu_button_rating'], - 'callback_data' => 'rating' - ], - [ - 'text' => 'πŸ’° ' . $localization['menu_button_balance'], - 'callback_data' => 'balance' - ] - ] - ], - 'disable_notification' => true, - 'remove_keyboard' => true - ], - ] - )->then(function (message $message) use ($context, $localization, $account) { - // Sended the message - - if ( - $account->authorized_system_accounts || - $account->authorized_system_questions || - $account->authorized_system_settings - ) { - // Found at least one system authorization - - // Initializing the keyboard buffer - $keyboard = []; - - if ($account->authorized_system_accounts) { - // Authorized to accounts - - // Generating the button and writing into the keyboard buffer - $keyboard[] = [ - [ - 'text' => '🐣 ' . $localization['menu_button_system_accounts'], - 'callback_data' => 'system_accounts' - ] - ]; - } - - if ($account->authorized_system_questions) { - // Authorized to questions - - // Generating the button and writing into the keyboard buffer - $keyboard[] = [ - [ - 'text' => 'πŸ—‚ ' . $localization['menu_button_system_questions'], - 'callback_data' => 'system_questions' - ] - ]; - } - - if ($account->authorized_system_settings) { - // Authorized to system settings - - // Generating the button and writing into the keyboard buffer - $keyboard[] = [ - [ - 'text' => 'βš™οΈ ' . $localization['menu_button_system_settings'], - 'callback_data' => 'system_settings' - ] - ]; - } - - // Sending the message - $context->sendMessage( - 'πŸ›  ' . $localization['menu_system_authorized'], - [ - 'reply_markup' => [ - 'inline_keyboard' => $keyboard, - 'disable_notification' => true, - 'remove_keyboard' => true - ], - ] - ); - } - }); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Account - * - * Responce for the command: "/account" - * - * Sends information about account with menu - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function account(context $context): void - { - // Initializing the telegram account - $telegram = $context->get('telegram'); - - if ($telegram instanceof record) { - // Initialized the telegram account - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing title for the message - $title = '🫡 ' . $localization['account_title']; - - // Initializing the account identifier row for the message - $identifier = '*' . $localization['account_identifier'] . ":* $account->identifier \($telegram->identifier\)"; - - // Declaring buufer of rows about authorizations - $authorizations = ''; - - // Initializing rows about authorization - foreach ($account->values() as $key => $value) { - // Iterating over account parameters - - if (str_starts_with($key, 'authorized_')) { - // Iterating over account authorizations - - if (str_starts_with($key, 'authorized_system_') && $value) { - // A system authorization - - // Writing into buffer of rows about authorizations - $authorizations .= 'βœ… ⚠️ *' . ($localization["account_$key"] ?? $key) . ':* ' . $localization['yes'] . "\n"; - } else { - // Not a system authorization - - // Writing into buffer of rows about authorizations - $authorizations .= ($value ? 'βœ…' : '❎') . ' *' . ($localization["account_$key"] ?? $key) . ':* ' . ($value ? $localization['yes'] : $localization['no']) . "\n"; - } - } - } - - // Trimming the last line break character - $authorizations = trim($authorizations, "\n"); - - // Sending the message - $context->sendMessage( - <<sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the telegram account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Language - * - * Responce for the command: "/language" - * - * Send the language selection menu - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function language(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing language - $language = $context->get('language'); - - if ($language instanceof language) { - // Initialized language - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Sending the language selection - process_language_select::menu( - context: $context, - prefix: 'settings_language_', - title: '🌏 *' . $localization['settings_select_language_title'] . '*', - description: '🌏 *' . $localization['settings_select_language_description'] . '*' - ); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized language - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize language*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Repository - * - * Responce for the command: "/repository" - * - * Sends information about project and menu - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function repository(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing title of the message - $title = 'πŸ›οΈ ' . $localization['repository_title']; - - // Sending the message - $context->sendMessage($title . "\n\n" . $localization['repository_text'], [ - 'reply_markup' => [ - 'inline_keyboard' => [ - [ - [ - 'text' => 'πŸ›οΈ ' . $localization['repository_button_code'], - 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots' - ] - ], - [ - [ - 'text' => '⚠️ ' . $localization['repository_button_issues'], - 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' - ], - [ - 'text' => '🌱 ' . $localization['repository_button_suggestions'], - 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' - ] - ] - ], - 'remove_keyboard' => true, - 'disable_notification' => true - ], - 'link_preview_options' => [ - 'is_disabled' => true - ] - ]); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Author - * - * Responce for the command: "/author" - * - * Sends - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function author(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing title of the message - $title = 'πŸ‘½ ' . $localization['author_title']; - - // Sending the message - $context->sendMessage($title . "\n\n" . $localization['author_text'], [ - 'reply_markup' => [ - 'inline_keyboard' => [ - [ - [ - 'text' => 'πŸ“š ' . $localization['author_button_neurojournal'], - 'url' => 'https://mirzaev.sexy' - ], - [ - 'text' => '🀟 ' . $localization['author_button_projects'], - 'url' => 'https://git.svoboda.works/mirzaev?tab=activity' - ] - ], - [ - [ - 'text' => 'βœ–οΈ ' . $localization['author_button_twitter'], - 'url' => 'https://x.com/mirzaev_sexy' - ], - [ - 'text' => 'πŸ¦‹ ' . $localization['author_button_bluesky'], - 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' - ], - [ - 'text' => '⛓️ ' . $localization['author_button_bastyon'], - 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' - ] - ], - [ - [ - 'text' => 'πŸ‡ΊπŸ‡Έ ' . $localization['author_button_youtube_english'], - 'url' => 'https://www.youtube.com/@MIRZAEV' - ], - [ - 'text' => 'πŸ‡·πŸ‡Ί ' . $localization['author_button_youtube_russian'], - 'url' => 'https://www.youtube.com/@MIRZAEV' - ] - ], - [ - [ - 'text' => 'βœ‰οΈ ' . $localization['author_button_message'], - 'url' => 'https://t.me/mirzaev_sexy' - ] - ] - ], - 'remove_keyboard' => true, - 'disable_notification' => true - ], - 'link_preview_options' => [ - 'is_disabled' => true - ] - ]); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Society - * - * Responce for the command: "/society" - * - * Sends the "mushroom" image and the localized text "why so shroomious" - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function society(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Sending the message - $context->sendPhoto( - new file_input(STORAGE . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'mushroom.jpg'), - [ - 'caption' => $localization['why_so_shroomious'], - 'disable_notification' => true - ] - ); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Questions (system) - * - * Sends questions. answers and localizations management menu - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function system_questions(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing the question model - $model_question = new question(); - - // Counting questions - $questions = $model_question->database->count(); - - // Initializing the answer model - $model_answer = new answer(); - - // Counting answers - $answers = $model_answer->database->count(); - - // Declaring the localizations amounts buffer - $localizations = []; - - // Declaring the questions list - $list = ''; - - foreach (language::cases() as $case) { - // Iterating over language - - // Initializing the localization model by the language - $model_question_localization = new question_localization(language: $case); - - // Counting localizations for the language - $amount = $model_question_localization->database->count(); - - // Writing into the localizations amounts buffer - $localizations[] = $amount; - - // Writing into the questions list - $list .= PHP_EOL . $case->flag() . ' *' . $case->label(language::{$account->language ?? LANGUAGE_DEFAULT} ?? language::{LANGUAGE_DEFAULT}) . ':* ' . $amount; - } - - // Deinitializing unnecessary variables - unset($case, $model_question, $model_question_localization, $model_answer, $amount); - - // Searching for unique values in uhe buffer of questions localizations amounts - $uniques = array_unique($localizations, SORT_REGULAR); - - // Is questions amounts matches? - $matches = count($uniques) === 1; - - // Sending the message - $context->sendMessage( - sprintf( - << [ - 'inline_keyboard' => [ - [ - [ - 'text' => 'πŸ” ' . $localization['system_questions_button_search'], - 'callback_data' => 'system_questions_search' - ], - [ - 'text' => '✏️ ' . $localization['system_questions_button_create'], - 'callback_data' => 'system_questions_create' - ] - ] - ], - 'remove_keyboard' => true, - 'disable_notification' => true - ], - 'link_preview_options' => [ - 'is_disabled' => true - ] - ] - ); - } else { - // Not initialized localization - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize localization*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } + /** + * Menu + * + * Responce for the commands: "/start", '/menu' + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function menu(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the title + $title = 'πŸ“‹ *' . $localization['menu_title'] . '*'; + + // Sending the message + $context->sendMessage( + << [ + 'inline_keyboard' => [ + [ + [ + 'text' => '🧠 ' . $localization['menu_button_start'], + 'callback_data' => 'projects' + ] + ], + [ + [ + 'text' => 'πŸ“ˆ ' . $localization['menu_button_rating'], + 'callback_data' => 'rating' + ], + [ + 'text' => 'πŸ’° ' . $localization['menu_button_balance'], + 'callback_data' => 'balance' + ] + ] + ], + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + )->then(function (message $message) use ($context, $localization, $account) { + // Sended the message + + if ( + $account->authorized_system_accounts || + $account->authorized_system_questions || + $account->authorized_system_settings + ) { + // Found at least one system authorization + + // Initializing the keyboard buffer + $keyboard = []; + + if ($account->authorized_system_accounts) { + // Authorized to accounts + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => '🐣 ' . $localization['menu_button_system_accounts'], + 'callback_data' => 'system_accounts' + ] + ]; + } + + if ($account->authorized_system_questions) { + // Authorized to questions + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => 'πŸ—‚ ' . $localization['menu_button_system_questions'], + 'callback_data' => 'system_questions' + ] + ]; + } + + if ($account->authorized_system_settings) { + // Authorized to system settings + + // Generating the button and writing into the keyboard buffer + $keyboard[] = [ + [ + 'text' => 'βš™οΈ ' . $localization['menu_button_system_settings'], + 'callback_data' => 'system_settings' + ] + ]; + } + + // Sending the message + $context->sendMessage( + 'πŸ›  ' . $localization['menu_system_authorized'], + [ + 'reply_markup' => [ + 'inline_keyboard' => $keyboard, + 'disable_notification' => true, + 'remove_keyboard' => true + ], + ] + ); + } + }); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Account + * + * Responce for the command: "/account" + * + * Sends information about account with menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function account(context $context): void + { + // Initializing the telegram account + $telegram = $context->get('telegram'); + + if ($telegram instanceof record) { + // Initialized the telegram account + + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title for the message + $title = '🫡 ' . $localization['account_title']; + + // Initializing the account identifier row for the message + $identifier = '*' . $localization['account_identifier'] . ":* $account->identifier \($telegram->identifier\)"; + + // Declaring buufer of rows about authorizations + $authorizations = ''; + + // Initializing rows about authorization + foreach ($account->values() as $key => $value) { + // Iterating over account parameters + + if (str_starts_with($key, 'authorized_')) { + // Iterating over account authorizations + + if (str_starts_with($key, 'authorized_system_') && $value) { + // A system authorization + + // Writing into buffer of rows about authorizations + $authorizations .= 'βœ… ⚠️ *' . ($localization["account_$key"] ?? $key) . ':* ' . $localization['yes'] . "\n"; + } else { + // Not a system authorization + + // Writing into buffer of rows about authorizations + $authorizations .= ($value ? 'βœ…' : '❎') . ' *' . ($localization["account_$key"] ?? $key) . ':* ' . ($value ? $localization['yes'] : $localization['no']) . "\n"; + } + } + } + + // Trimming the last line break character + $authorizations = trim($authorizations, "\n"); + + // Sending the message + $context->sendMessage( + <<sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the telegram account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the telegram account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Language + * + * Responce for the command: "/language" + * + * Send the language selection menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function language(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing language + $language = $context->get('language'); + + if ($language instanceof language) { + // Initialized language + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the language selection + process_language_select::menu( + context: $context, + prefix: 'settings_language_', + title: '🌏 *' . $localization['settings_select_language_title'] . '*', + description: '🌏 *' . $localization['settings_select_language_description'] . '*' + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized language + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize language*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Repository + * + * Responce for the command: "/repository" + * + * Sends information about project and menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function repository(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title of the message + $title = 'πŸ›οΈ ' . $localization['repository_title']; + + // Sending the message + $context->sendMessage($title . "\n\n" . $localization['repository_text'], [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => 'πŸ›οΈ ' . $localization['repository_button_code'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots' + ] + ], + [ + [ + 'text' => '⚠️ ' . $localization['repository_button_issues'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' + ], + [ + 'text' => '🌱 ' . $localization['repository_button_suggestions'], + 'url' => 'https://git.mirzaev.sexy/mirzaev/deeproots/issues' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ]); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Author + * + * Responce for the command: "/author" + * + * Sends + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function author(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing title of the message + $title = 'πŸ‘½ ' . $localization['author_title']; + + // Sending the message + $context->sendMessage($title . "\n\n" . $localization['author_text'], [ + 'reply_markup' => [ + 'inline_keyboard' => [ + [ + [ + 'text' => 'πŸ“š ' . $localization['author_button_neurojournal'], + 'url' => 'https://mirzaev.sexy' + ], + [ + 'text' => '🀟 ' . $localization['author_button_projects'], + 'url' => 'https://git.svoboda.works/mirzaev?tab=activity' + ] + ], + [ + [ + 'text' => 'βœ–οΈ ' . $localization['author_button_twitter'], + 'url' => 'https://x.com/mirzaev_sexy' + ], + [ + 'text' => 'πŸ¦‹ ' . $localization['author_button_bluesky'], + 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' + ], + [ + 'text' => '⛓️ ' . $localization['author_button_bastyon'], + 'url' => 'https://bsky.app/profile/mirzaev.bsky.social' + ] + ], + [ + [ + 'text' => 'πŸ‡ΊπŸ‡Έ ' . $localization['author_button_youtube_english'], + 'url' => 'https://www.youtube.com/@MIRZAEV' + ], + [ + 'text' => 'πŸ‡·πŸ‡Ί ' . $localization['author_button_youtube_russian'], + 'url' => 'https://www.youtube.com/@MIRZAEV' + ] + ], + [ + [ + 'text' => 'βœ‰οΈ ' . $localization['author_button_message'], + 'url' => 'https://t.me/mirzaev_sexy' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ]); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Society + * + * Responce for the command: "/society" + * + * Sends the "mushroom" image and the localized text "why so shroomious" + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function society(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $context->sendPhoto( + new file_input(STORAGE . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'mushroom.jpg'), + [ + 'caption' => $localization['why_so_shroomious'], + 'disable_notification' => true + ] + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } + + /** + * Questions (system) + * + * Sends questions. answers and localizations management menu + * + * @param context $context Request data from Telegram + * + * @return void + */ + public static function system_questions(context $context): void + { + // Initializing the account + $account = $context->get('account'); + + if ($account instanceof record) { + // Initialized the account + + // Initializing localization + $localization = $context->get('localization'); + + if ($localization) { + // Initialized localization + + // Initializing the question model + $model_question = new question(); + + // Counting questions + $questions = $model_question->database->count(); + + // Initializing the answer model + $model_answer = new answer(); + + // Counting answers + $answers = $model_answer->database->count(); + + // Declaring the localizations amounts buffer + $localizations = []; + + // Declaring the questions list + $list = ''; + + foreach (language::cases() as $case) { + // Iterating over language + + // Initializing the localization model by the language + $model_question_localization = new question_localization(language: $case); + + // Counting localizations for the language + $amount = $model_question_localization->database->count(); + + // Writing into the localizations amounts buffer + $localizations[] = $amount; + + // Writing into the questions list + $list .= PHP_EOL . $case->flag() . ' *' . $case->label(language::{$account->language ?? LANGUAGE_DEFAULT} ?? language::{LANGUAGE_DEFAULT}) . ':* ' . $amount; + } + + // Deinitializing unnecessary variables + unset($case, $model_question, $model_question_localization, $model_answer, $amount); + + // Searching for unique values in uhe buffer of questions localizations amounts + $uniques = array_unique($localizations, SORT_REGULAR); + + // Is questions amounts matches? + $matches = count($uniques) === 1; + + // Sending the message + $context->sendMessage( + sprintf( + << [ + 'inline_keyboard' => [ + [ + [ + 'text' => 'πŸ” ' . $localization['system_questions_button_search'], + 'callback_data' => 'system_questions_search' + ], + [ + 'text' => '✏️ ' . $localization['system_questions_button_create'], + 'callback_data' => 'system_questions_create' + ] + ] + ], + 'remove_keyboard' => true, + 'disable_notification' => true + ], + 'link_preview_options' => [ + 'is_disabled' => true + ] + ] + ); + } else { + // Not initialized localization + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize localization*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } else { + // Not initialized the account + + // Sending the message + $context->sendMessage('⚠️ *Failed to initialize the account*') + ->then(function (message $message) use ($context) { + // Sended the message + + // Ending the conversation process + $context->endConversation(); + }); + } + } } diff --git a/mirzaev/deeproots/system/public/index.php b/mirzaev/deeproots/system/public/index.php index b8fa7e6..37ca65f 100755 --- a/mirzaev/deeproots/system/public/index.php +++ b/mirzaev/deeproots/system/public/index.php @@ -6,30 +6,30 @@ namespace mirzaev\deeproots; // Framework for PHP use mirzaev\minimal\core, - mirzaev\minimal\route; + mirzaev\minimal\route; // Enabling debugging /* ini_set('error_reporting', E_ALL); -ini_set('display_errors', 1); -ini_set('display_startup_errors', 1); */ + ini_set('display_errors', 1); + ini_set('display_startup_errors', 1); */ -// Initializing path to the public directory +// Initializing path to the public directory define('INDEX', __DIR__); // Initializing path to the project root directory -define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); +define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); -// Initializing path to the directory of views -define('VIEWS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views'); +// Initializing path to the directory of views +define('VIEWS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views'); -// Initializing path to the directory of settings -define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings'); +// Initializing path to the directory of settings +define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings'); -// Initializing system settings +// Initializing system settings require SETTINGS . DIRECTORY_SEPARATOR . 'system.php'; -// Initializing path to the directory of the storage -define('STORAGE', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'storage'); +// Initializing path to the directory of the storage +define('STORAGE', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'storage'); // Initializing path to the databases directory define('DATABASES', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'databases'); @@ -42,8 +42,8 @@ $core = new core(namespace: __NAMESPACE__); // Initializing routes $core->router - ->write('/', new route('index', 'index'), 'GET') -; + ->write('/', new route('index', 'index'), 'GET') + ; // Handling request $core->start(); diff --git a/mirzaev/deeproots/system/public/telegram.php b/mirzaev/deeproots/system/public/telegram.php index 6ab3b7a..7f42061 100755 --- a/mirzaev/deeproots/system/public/telegram.php +++ b/mirzaev/deeproots/system/public/telegram.php @@ -6,28 +6,28 @@ namespace mirzaev\deeproots; // Files of the project use mirzaev\deeproots\models\telegram\middlewares, - mirzaev\deeproots\models\telegram\commands, - mirzaev\deeproots\models\telegram\settings, - mirzaev\deeproots\models\telegram\processes\question\search as process_question_search, - mirzaev\deeproots\models\telegram\buttons\question\search as buttons_question_search, - mirzaev\deeproots\models\telegram\processes\question\create as process_question_create, - mirzaev\deeproots\models\enumerations\language; + mirzaev\deeproots\models\telegram\commands, + mirzaev\deeproots\models\telegram\settings, + mirzaev\deeproots\models\telegram\processes\question\search as process_question_search, + mirzaev\deeproots\models\telegram\buttons\question\search as buttons_question_search, + mirzaev\deeproots\models\telegram\processes\question\create as process_question_create, + mirzaev\deeproots\models\enumerations\language; // Framework for Telegram use Zanzara\Zanzara as zanzara, - Zanzara\Context as context, - Zanzara\Config as config; + Zanzara\Context as context, + Zanzara\Config as config; // Enabling debugging /* ini_set('error_reporting', E_ALL); -ini_set('display_errors', 1); -ini_set('display_startup_errors', 1); */ + ini_set('display_errors', 1); + ini_set('display_startup_errors', 1); */ -// Initializing path to the public directory +// Initializing path to the public directory define('INDEX', __DIR__); // Initializing path to the root directory -define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); +define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); // Initializing path to the settings directory define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings'); @@ -82,10 +82,10 @@ $robot->onCommand('society', [commands::class, 'society']); // Initializing the robot settings language buttons handlers foreach (language::cases() as $language) { - // Iterating over languages + // Iterating over languages - // Initializing language buttons - $robot->onCbQueryData(['settings_language_' . $language->name], fn(context $context) => settings::language($context, $language)); + // Initializing language buttons + $robot->onCbQueryData(['settings_language_' . $language->name], fn(context $context) => settings::language($context, $language)); }; $robot->onCbQueryData(['system_questions_search_identifier'], [buttons_question_search::class, 'identifier'])->middleware([middlewares::class, 'system_questions']); diff --git a/mirzaev/deeproots/system/test/utils/database_read.php b/mirzaev/deeproots/system/test/utils/database_read.php new file mode 100644 index 0000000..97b67f7 --- /dev/null +++ b/mirzaev/deeproots/system/test/utils/database_read.php @@ -0,0 +1,39 @@ +encoding(encoding::utf8) + ->columns( + new column('identifier', type::integer_unsigned), + new column('domain', type::string, ['length' => 32]), + new column('name_first', type::string, ['length' => 64]), + new column('name_second', type::string, ['length' => 64]), + new column('language', type::string, ['length' => 2]), + new column('robot', type::char), + new column('updated', type::integer_unsigned), + new column('created', type::integer_unsigned) + ) + ->connect($file); + +// Reading the whole database array +$read = $database->read(); +print_r($read);