diff --git a/composer.json b/composer.json index f854190..fcc8a1f 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "require": { "php": "^8.5", "mirzaev/minimal": "^3.7", - "mirzaev/baza": "^3.3", + "mirzaev/baza": "^3.4", "mirzaev/record": "^1.0", "mirzaev/languages": "^1.0", "mirzaev/currencies": "^2.0", @@ -36,7 +36,8 @@ "twig/intl-extra": "^3.10", "react/filesystem": "^0.1.2", "nyholm/psr7": "^1.8", - "irazasyed/telegram-bot-sdk": "^3.15" + "irazasyed/telegram-bot-sdk": "^3.15", + "nutgram/nutgram": "^4.40" }, "suggest": { "mirzaev/files": "Easy working with files", diff --git a/composer.lock b/composer.lock index 0afc042..9eff16b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "263bb53da6ce430d79d9b25bdf81f921", + "content-hash": "4cea1a922de2838a239ca7633443750c", "packages": [ { "name": "badfarm/zanzara", @@ -917,16 +917,16 @@ }, { "name": "illuminate/collections", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "d3f104a32fdfbf416cd1a839dad0e2c670a03f4e" + "reference": "18ca56ad53265a18508198473b1523c1ad46edad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/d3f104a32fdfbf416cd1a839dad0e2c670a03f4e", - "reference": "d3f104a32fdfbf416cd1a839dad0e2c670a03f4e", + "url": "https://api.github.com/repos/illuminate/collections/zipball/18ca56ad53265a18508198473b1523c1ad46edad", + "reference": "18ca56ad53265a18508198473b1523c1ad46edad", "shasum": "" }, "require": { @@ -973,11 +973,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-01-07T21:26:29+00:00" + "time": "2026-01-23T16:02:04+00:00" }, { "name": "illuminate/conditionable", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1023,7 +1023,7 @@ }, { "name": "illuminate/contracts", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1071,7 +1071,7 @@ }, { "name": "illuminate/macroable", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1117,7 +1117,7 @@ }, { "name": "illuminate/reflection", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/reflection.git", @@ -1168,16 +1168,16 @@ }, { "name": "illuminate/support", - "version": "v12.47.0", + "version": "v12.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1757ae693f552f82179ebcdb0a4983a56e645f27" + "reference": "196cae049b187ebffbe72efd22ef3ae57dd0a2db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1757ae693f552f82179ebcdb0a4983a56e645f27", - "reference": "1757ae693f552f82179ebcdb0a4983a56e645f27", + "url": "https://api.github.com/repos/illuminate/support/zipball/196cae049b187ebffbe72efd22ef3ae57dd0a2db", + "reference": "196cae049b187ebffbe72efd22ef3ae57dd0a2db", "shasum": "" }, "require": { @@ -1244,7 +1244,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-01-13T14:50:24+00:00" + "time": "2026-01-27T02:58:23+00:00" }, { "name": "irazasyed/telegram-bot-sdk", @@ -1707,16 +1707,16 @@ }, { "name": "nesbot/carbon", - "version": "3.11.0", + "version": "3.11.1", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1" + "reference": "f438fcc98f92babee98381d399c65336f3a3827f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/f438fcc98f92babee98381d399c65336f3a3827f", + "reference": "f438fcc98f92babee98381d399c65336f3a3827f", "shasum": "" }, "require": { @@ -1740,7 +1740,7 @@ "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan": "^2.1.22", "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4" + "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" }, "bin": [ "bin/carbon" @@ -1783,14 +1783,14 @@ } ], "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbon.nesbot.com", + "homepage": "https://carbonphp.github.io/carbon/", "keywords": [ "date", "datetime", "time" ], "support": { - "docs": "https://carbon.nesbot.com/docs", + "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", "issues": "https://github.com/CarbonPHP/carbon/issues", "source": "https://github.com/CarbonPHP/carbon" }, @@ -1808,7 +1808,7 @@ "type": "tidelift" } ], - "time": "2025-12-02T21:04:28+00:00" + "time": "2026-01-29T09:26:29+00:00" }, { "name": "netresearch/jsonmapper", @@ -1861,6 +1861,153 @@ }, "time": "2024-09-08T10:13:13+00:00" }, + { + "name": "nutgram/hydrator", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/nutgram/hydrator.git", + "reference": "06bf4182112fd3f917c019e0529e1a8f0aa700f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nutgram/hydrator/zipball/06bf4182112fd3f917c019e0529e1a8f0aa700f3", + "reference": "06bf4182112fd3f917c019e0529e1a8f0aa700f3", + "shasum": "" + }, + "require": { + "php": "^8.1", + "psr/container": "^1.1 || ^2.0" + }, + "require-dev": { + "illuminate/container": "^10.0", + "phpunit/phpunit": "^10" + }, + "type": "library", + "autoload": { + "psr-4": { + "SergiX44\\Hydrator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sergio Brighenti", + "email": "sergio@brighenti.me", + "homepage": "https://github.com/SergiX44" + }, + { + "name": "Anatoly Fenric", + "email": "afenric@gmail.com", + "homepage": "https://github.com/fenric" + } + ], + "description": "Hydrator for PHP 8.0+", + "homepage": "https://github.com/nutgram/hydrator", + "keywords": [ + "data-mapper", + "dto", + "hydrator", + "jsonmapper", + "mapper", + "php8" + ], + "support": { + "issues": "https://github.com/nutgram/hydrator/issues", + "source": "https://github.com/nutgram/hydrator/tree/7.0.2" + }, + "time": "2025-11-23T18:23:30+00:00" + }, + { + "name": "nutgram/nutgram", + "version": "4.40.2", + "source": { + "type": "git", + "url": "https://github.com/nutgram/nutgram.git", + "reference": "caf0deb11f6dae93b407f5bb85a94d5336a1b945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nutgram/nutgram/zipball/caf0deb11f6dae93b407f5bb85a94d5336a1b945", + "reference": "caf0deb11f6dae93b407f5bb85a94d5336a1b945", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^7.2", + "illuminate/macroable": ">=9.0", + "laravel/serializable-closure": "^1.0|^2.0", + "nutgram/hydrator": "^7.0.2", + "php": "^8.2", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "sergix44/container": "^3.0" + }, + "require-dev": { + "ext-reflection": "*", + "mockery/mockery": "^1.6", + "pestphp/pest": "^3.0|^4.0", + "roave/security-advisories": "dev-latest", + "vimeo/psalm": "^6.1.0" + }, + "suggest": { + "ext-sodium": "To validate WebApp data for Third-Party Use" + }, + "type": "library", + "autoload": { + "files": [ + "src/Support/Helpers.php" + ], + "psr-4": { + "SergiX44\\Nutgram\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sergio Brighenti", + "email": "sergio@brighenti.me", + "role": "Developer" + }, + { + "name": "Luca Patera", + "email": "lucapatera@outlook.it", + "role": "Developer" + } + ], + "description": "The Telegram bot library that doesn't drive you nuts", + "homepage": "https://github.com/SergiX44/Nutgram", + "keywords": [ + "api", + "bot", + "framework", + "laravel", + "library", + "nutgram", + "telegram" + ], + "support": { + "issues": "https://github.com/nutgram/nutgram/issues", + "source": "https://github.com/nutgram/nutgram/tree/4.40.2" + }, + "funding": [ + { + "url": "https://github.com/Lukasss93", + "type": "github" + }, + { + "url": "https://github.com/SergiX44", + "type": "github" + } + ], + "time": "2026-01-25T17:57:40+00:00" + }, { "name": "nyholm/psr7", "version": "1.8.2", @@ -3758,6 +3905,62 @@ }, "time": "2018-05-29T20:21:04+00:00" }, + { + "name": "sergix44/container", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sergix44/container.git", + "reference": "202747e5e9b6a46eb9681259d861753dd5a9fab2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sergix44/container/zipball/202747e5e9b6a46eb9681259d861753dd5a9fab2", + "reference": "202747e5e9b6a46eb9681259d861753dd5a9fab2", + "shasum": "" + }, + "require": { + "ext-reflection": "*", + "php": "^8.1", + "psr/container": "^1.1|^2.0" + }, + "provide": { + "psr/container-implementation": "^1.1|^2.0" + }, + "require-dev": { + "pestphp/pest": "^2.0", + "php-di/php-di": "^7.0", + "vimeo/psalm": "^5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "SergiX44\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sergio Brighenti", + "email": "sergio@brighenti.me" + } + ], + "description": "A simple and fast service container", + "support": { + "issues": "https://github.com/sergix44/container/issues", + "source": "https://github.com/sergix44/container/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/SergiX44", + "type": "github" + } + ], + "time": "2024-06-18T12:52:08+00:00" + }, { "name": "svoboda/time", "version": "1.0.0", @@ -3793,16 +3996,16 @@ }, { "name": "symfony/cache", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f" + "reference": "92e9960386c7e01f58198038c199d522959a843c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f", - "reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f", + "url": "https://api.github.com/repos/symfony/cache/zipball/92e9960386c7e01f58198038c199d522959a843c", + "reference": "92e9960386c7e01f58198038c199d522959a843c", "shasum": "" }, "require": { @@ -3869,7 +4072,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v8.0.3" + "source": "https://github.com/symfony/cache/tree/v8.0.5" }, "funding": [ { @@ -3889,7 +4092,7 @@ "type": "tidelift" } ], - "time": "2025-12-28T10:45:32+00:00" + "time": "2026-01-27T16:18:07+00:00" }, { "name": "symfony/cache-contracts", @@ -4046,16 +4249,16 @@ }, { "name": "symfony/config", - "version": "v8.0.3", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "58063686fd7b8e676f14b5a4808cb85265c5216e" + "reference": "8f45af92f08f82902827a8b6f403aaf49d893539" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/58063686fd7b8e676f14b5a4808cb85265c5216e", - "reference": "58063686fd7b8e676f14b5a4808cb85265c5216e", + "url": "https://api.github.com/repos/symfony/config/zipball/8f45af92f08f82902827a8b6f403aaf49d893539", + "reference": "8f45af92f08f82902827a8b6f403aaf49d893539", "shasum": "" }, "require": { @@ -4100,7 +4303,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v8.0.3" + "source": "https://github.com/symfony/config/tree/v8.0.4" }, "funding": [ { @@ -4120,20 +4323,20 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:52:06+00:00" + "time": "2026-01-13T13:06:50+00:00" }, { "name": "symfony/dependency-injection", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "8db0d4c1dd4c533a29210c68074999ba45ad6d3e" + "reference": "40a6c455ade7e3bf25900d6b746d40cfa2573e26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8db0d4c1dd4c533a29210c68074999ba45ad6d3e", - "reference": "8db0d4c1dd4c533a29210c68074999ba45ad6d3e", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/40a6c455ade7e3bf25900d6b746d40cfa2573e26", + "reference": "40a6c455ade7e3bf25900d6b746d40cfa2573e26", "shasum": "" }, "require": { @@ -4181,7 +4384,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v8.0.3" + "source": "https://github.com/symfony/dependency-injection/tree/v8.0.5" }, "funding": [ { @@ -4201,7 +4404,7 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:52:06+00:00" + "time": "2026-01-27T16:18:07+00:00" }, { "name": "symfony/deprecation-contracts", @@ -4272,16 +4475,16 @@ }, { "name": "symfony/error-handler", - "version": "v8.0.0", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "d77ec7dda0c274178745d152e82baf7ea827fd73" + "reference": "7620b97ec0ab1d2d6c7fb737aa55da411bea776a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/d77ec7dda0c274178745d152e82baf7ea827fd73", - "reference": "d77ec7dda0c274178745d152e82baf7ea827fd73", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/7620b97ec0ab1d2d6c7fb737aa55da411bea776a", + "reference": "7620b97ec0ab1d2d6c7fb737aa55da411bea776a", "shasum": "" }, "require": { @@ -4329,7 +4532,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v8.0.0" + "source": "https://github.com/symfony/error-handler/tree/v8.0.4" }, "funding": [ { @@ -4349,20 +4552,20 @@ "type": "tidelift" } ], - "time": "2025-11-05T14:36:47+00:00" + "time": "2026-01-23T11:07:10+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v8.0.0", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "573f95783a2ec6e38752979db139f09fec033f03" + "reference": "99301401da182b6cfaa4700dbe9987bb75474b47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03", - "reference": "573f95783a2ec6e38752979db139f09fec033f03", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47", + "reference": "99301401da182b6cfaa4700dbe9987bb75474b47", "shasum": "" }, "require": { @@ -4414,7 +4617,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4" }, "funding": [ { @@ -4434,7 +4637,7 @@ "type": "tidelift" } ], - "time": "2025-10-30T14:17:19+00:00" + "time": "2026-01-05T11:45:55+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -4584,16 +4787,16 @@ }, { "name": "symfony/finder", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12" + "reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12", - "reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12", + "url": "https://api.github.com/repos/symfony/finder/zipball/8bd576e97c67d45941365bf824e18dc8538e6eb0", + "reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0", "shasum": "" }, "require": { @@ -4628,7 +4831,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.0.3" + "source": "https://github.com/symfony/finder/tree/v8.0.5" }, "funding": [ { @@ -4648,20 +4851,20 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:52:06+00:00" + "time": "2026-01-26T15:08:38+00:00" }, { "name": "symfony/framework-bundle", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "738a92519fbc3ac37192b28052574bf2d1e8f63a" + "reference": "e2f9469e7a802dd7c0d193792afc494d68177c54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/738a92519fbc3ac37192b28052574bf2d1e8f63a", - "reference": "738a92519fbc3ac37192b28052574bf2d1e8f63a", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/e2f9469e7a802dd7c0d193792afc494d68177c54", + "reference": "e2f9469e7a802dd7c0d193792afc494d68177c54", "shasum": "" }, "require": { @@ -4669,8 +4872,8 @@ "ext-xml": "*", "php": ">=8.4", "symfony/cache": "^7.4|^8.0", - "symfony/config": "^7.4.3|^8.0.3", - "symfony/dependency-injection": "^7.4|^8.0", + "symfony/config": "^7.4.4|^8.0.4", + "symfony/dependency-injection": "^7.4.4|^8.0.4", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^7.4|^8.0", "symfony/event-dispatcher": "^7.4|^8.0", @@ -4684,8 +4887,8 @@ }, "conflict": { "doctrine/persistence": "<1.3", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", + "phpdocumentor/reflection-docblock": "<5.2|>=6", + "phpdocumentor/type-resolver": "<1.5.1", "symfony/console": "<7.4", "symfony/form": "<7.4", "symfony/json-streamer": "<7.4", @@ -4699,7 +4902,7 @@ "require-dev": { "doctrine/persistence": "^1.3|^2|^3", "dragonmantank/cron-expression": "^3.1", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", "symfony/asset": "^7.4|^8.0", @@ -4768,7 +4971,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v8.0.3" + "source": "https://github.com/symfony/framework-bundle/tree/v8.0.5" }, "funding": [ { @@ -4788,20 +4991,20 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:52:06+00:00" + "time": "2026-01-27T09:06:10+00:00" }, { "name": "symfony/http-foundation", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "514ec3aa7982f296b0ad0825f75b6be5779ae9e7" + "reference": "e3422806e6f6760dbed0ddbc0a7fbfb6b5ce96bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/514ec3aa7982f296b0ad0825f75b6be5779ae9e7", - "reference": "514ec3aa7982f296b0ad0825f75b6be5779ae9e7", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e3422806e6f6760dbed0ddbc0a7fbfb6b5ce96bb", + "reference": "e3422806e6f6760dbed0ddbc0a7fbfb6b5ce96bb", "shasum": "" }, "require": { @@ -4848,7 +5051,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v8.0.3" + "source": "https://github.com/symfony/http-foundation/tree/v8.0.5" }, "funding": [ { @@ -4868,20 +5071,20 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:52:06+00:00" + "time": "2026-01-27T16:18:07+00:00" }, { "name": "symfony/http-kernel", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "e6dfb348eb1dd4df14c39e6dc7e283bab4199fd9" + "reference": "20c1c5e41fc53928dbb670088f544f2d460d497d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e6dfb348eb1dd4df14c39e6dc7e283bab4199fd9", - "reference": "e6dfb348eb1dd4df14c39e6dc7e283bab4199fd9", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/20c1c5e41fc53928dbb670088f544f2d460d497d", + "reference": "20c1c5e41fc53928dbb670088f544f2d460d497d", "shasum": "" }, "require": { @@ -4952,7 +5155,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v8.0.3" + "source": "https://github.com/symfony/http-kernel/tree/v8.0.5" }, "funding": [ { @@ -4972,20 +5175,20 @@ "type": "tidelift" } ], - "time": "2025-12-31T09:29:34+00:00" + "time": "2026-01-28T10:46:31+00:00" }, { "name": "symfony/intl", - "version": "v8.0.1", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "f9eca217ae8f2be0b3ad80723d6a3b518b90cd66" + "reference": "8d049269c2accca0b02e5f9de39f3ee92ebc4468" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/f9eca217ae8f2be0b3ad80723d6a3b518b90cd66", - "reference": "f9eca217ae8f2be0b3ad80723d6a3b518b90cd66", + "url": "https://api.github.com/repos/symfony/intl/zipball/8d049269c2accca0b02e5f9de39f3ee92ebc4468", + "reference": "8d049269c2accca0b02e5f9de39f3ee92ebc4468", "shasum": "" }, "require": { @@ -5041,7 +5244,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v8.0.1" + "source": "https://github.com/symfony/intl/tree/v8.0.4" }, "funding": [ { @@ -5061,7 +5264,7 @@ "type": "tidelift" } ], - "time": "2025-12-01T09:13:36+00:00" + "time": "2026-01-12T12:37:40+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5473,16 +5676,16 @@ }, { "name": "symfony/routing", - "version": "v8.0.3", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "3827ac6e03dcd86e430fb6ae6056acf5b51aece3" + "reference": "4a2bc08d1c35307239329f434d45c2bfe8241fa9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3827ac6e03dcd86e430fb6ae6056acf5b51aece3", - "reference": "3827ac6e03dcd86e430fb6ae6056acf5b51aece3", + "url": "https://api.github.com/repos/symfony/routing/zipball/4a2bc08d1c35307239329f434d45c2bfe8241fa9", + "reference": "4a2bc08d1c35307239329f434d45c2bfe8241fa9", "shasum": "" }, "require": { @@ -5529,7 +5732,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v8.0.3" + "source": "https://github.com/symfony/routing/tree/v8.0.4" }, "funding": [ { @@ -5549,7 +5752,7 @@ "type": "tidelift" } ], - "time": "2025-12-19T10:01:18+00:00" + "time": "2026-01-12T12:37:40+00:00" }, { "name": "symfony/service-contracts", @@ -5640,16 +5843,16 @@ }, { "name": "symfony/translation", - "version": "v8.0.3", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d" + "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/60a8f11f0e15c48f2cc47c4da53873bb5b62135d", - "reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d", + "url": "https://api.github.com/repos/symfony/translation/zipball/db70c8ce7db74fd2da7b1d268db46b2a8ce32c10", + "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10", "shasum": "" }, "require": { @@ -5709,7 +5912,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.3" + "source": "https://github.com/symfony/translation/tree/v8.0.4" }, "funding": [ { @@ -5729,7 +5932,7 @@ "type": "tidelift" } ], - "time": "2025-12-21T10:59:45+00:00" + "time": "2026-01-13T13:06:50+00:00" }, { "name": "symfony/translation-contracts", @@ -5815,16 +6018,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v8.0.3", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "2a2978a44127bae9aaee0ed5319954eb492d81c3" + "reference": "3e60c35cb47b1077524c066ec277eaf92cdc2393" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/2a2978a44127bae9aaee0ed5319954eb492d81c3", - "reference": "2a2978a44127bae9aaee0ed5319954eb492d81c3", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/3e60c35cb47b1077524c066ec277eaf92cdc2393", + "reference": "3e60c35cb47b1077524c066ec277eaf92cdc2393", "shasum": "" }, "require": { @@ -5833,13 +6036,14 @@ "twig/twig": "^3.21" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0" + "phpdocumentor/reflection-docblock": "<5.2|>=6", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/form": "<7.4.4|>8.0,<8.0.4" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3|^4", "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "phpdocumentor/reflection-docblock": "^5.2", "symfony/asset": "^7.4|^8.0", "symfony/asset-mapper": "^7.4|^8.0", "symfony/console": "^7.4|^8.0", @@ -5847,7 +6051,7 @@ "symfony/emoji": "^7.4|^8.0", "symfony/expression-language": "^7.4|^8.0", "symfony/finder": "^7.4|^8.0", - "symfony/form": "^7.4.1|^8.0.1", + "symfony/form": "^7.4.4|^8.0.4", "symfony/html-sanitizer": "^7.4|^8.0", "symfony/http-foundation": "^7.4|^8.0", "symfony/http-kernel": "^7.4|^8.0", @@ -5897,7 +6101,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v8.0.3" + "source": "https://github.com/symfony/twig-bridge/tree/v8.0.5" }, "funding": [ { @@ -5917,20 +6121,20 @@ "type": "tidelift" } ], - "time": "2025-12-16T08:10:18+00:00" + "time": "2026-01-27T09:06:10+00:00" }, { "name": "symfony/twig-bundle", - "version": "v8.0.3", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "58c54c97af6a3fdb7ea9a3931ea1c4b8bd282b2f" + "reference": "5a68f2e0e06996514bf04900c3982b93b42487af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/58c54c97af6a3fdb7ea9a3931ea1c4b8bd282b2f", - "reference": "58c54c97af6a3fdb7ea9a3931ea1c4b8bd282b2f", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/5a68f2e0e06996514bf04900c3982b93b42487af", + "reference": "5a68f2e0e06996514bf04900c3982b93b42487af", "shasum": "" }, "require": { @@ -5981,7 +6185,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v8.0.3" + "source": "https://github.com/symfony/twig-bundle/tree/v8.0.4" }, "funding": [ { @@ -6001,20 +6205,20 @@ "type": "tidelift" } ], - "time": "2025-12-19T10:01:18+00:00" + "time": "2026-01-06T12:43:21+00:00" }, { "name": "symfony/var-dumper", - "version": "v8.0.3", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3bc368228532ad538cc216768caa8968be95a8d6" + "reference": "326e0406fc315eca57ef5740fa4a280b7a068c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3bc368228532ad538cc216768caa8968be95a8d6", - "reference": "3bc368228532ad538cc216768caa8968be95a8d6", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/326e0406fc315eca57ef5740fa4a280b7a068c82", + "reference": "326e0406fc315eca57ef5740fa4a280b7a068c82", "shasum": "" }, "require": { @@ -6068,7 +6272,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v8.0.3" + "source": "https://github.com/symfony/var-dumper/tree/v8.0.4" }, "funding": [ { @@ -6088,7 +6292,7 @@ "type": "tidelift" } ], - "time": "2025-12-18T11:23:51+00:00" + "time": "2026-01-01T23:07:29+00:00" }, { "name": "symfony/var-exporter", @@ -6363,16 +6567,16 @@ }, { "name": "twig/extra-bundle", - "version": "v3.22.2", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e" + "reference": "7a27e784dc56eddfef5e9295829b290ce06f1682" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e", - "reference": "09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/7a27e784dc56eddfef5e9295829b290ce06f1682", + "reference": "7a27e784dc56eddfef5e9295829b290ce06f1682", "shasum": "" }, "require": { @@ -6421,7 +6625,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.22.2" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.23.0" }, "funding": [ { @@ -6433,20 +6637,20 @@ "type": "tidelift" } ], - "time": "2025-12-05T08:51:53+00:00" + "time": "2025-12-18T20:46:15+00:00" }, { "name": "twig/intl-extra", - "version": "v3.22.1", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1" + "reference": "32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/93ac31e53cdd3f2e541f42690cd0c54ca8138ab1", - "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f", + "reference": "32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f", "shasum": "" }, "require": { @@ -6485,7 +6689,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.22.1" + "source": "https://github.com/twigphp/intl-extra/tree/v3.23.0" }, "funding": [ { @@ -6497,20 +6701,20 @@ "type": "tidelift" } ], - "time": "2025-11-02T11:00:49+00:00" + "time": "2026-01-17T13:57:47+00:00" }, { "name": "twig/twig", - "version": "v3.22.2", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2" + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/946ddeafa3c9f4ce279d1f34051af041db0e16f2", - "reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", "shasum": "" }, "require": { @@ -6564,7 +6768,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.22.2" + "source": "https://github.com/twigphp/Twig/tree/v3.23.0" }, "funding": [ { @@ -6576,7 +6780,7 @@ "type": "tidelift" } ], - "time": "2025-12-14T11:28:47+00:00" + "time": "2026-01-23T21:00:41+00:00" }, { "name": "voku/portable-ascii", diff --git a/kodorvan/constructor/system/localizations/english.php b/kodorvan/constructor/system/localizations/english.php index 7b3a1cb..6e727d8 100644 --- a/kodorvan/constructor/system/localizations/english.php +++ b/kodorvan/constructor/system/localizations/english.php @@ -17,16 +17,12 @@ return [ 'account_authorized_settings' => 'Access to settings', 'account_authorized_system_settings' => 'System access to the system settings', - // Language setting - 'settings_select_language_title' => 'Select language', - 'settings_select_language_description' => 'The selected language will be writed in your account settings', - 'settings_language_update_success' => 'Language replaced:', + // Settings: language + 'settings_language_title' => 'Select language', + 'settings_language_description' => 'The selected language will be used in the system interface generation', + 'settings_language_update_success' => 'Language replaced', 'settings_language_update_fail' => 'Failed to replace language', - - // Language selection - 'select_language_title' => 'Select language', - 'select_language_description' => 'The selected language will be used in the current process', - 'select_language_button_add' => 'Add a language', + 'settings_language_button_add' => 'Add a language', // Authorization 'not_authorized_system' => 'You do not have access to the system', diff --git a/kodorvan/constructor/system/localizations/russian.php b/kodorvan/constructor/system/localizations/russian.php index 825a4a2..0539024 100644 --- a/kodorvan/constructor/system/localizations/russian.php +++ b/kodorvan/constructor/system/localizations/russian.php @@ -9,9 +9,8 @@ return [ // Главное меню 'menu_title' => 'Главное меню', - 'menu_description_guest' => "*Создайте ваш первый проект* и получите *ориентировочную стоимость* всего за 2 минуты\n\nПосле расчёта *сформируйте заявку* к проджект\-менеджеру для более глубокого анализа и составлении ТЗ\n\nПри желании этот этап можно пропустить сразу *связавшись с оператором* _\(график работы указан в его профиле\)_", - 'menu_description_partner' => "Надеемся, что наше сотрудничество оставляет сугубо *положительные эмоции* и способствует *развитию обоих сторон*\n\n*Благодарим за выбор нашей команды*", - 'menu_experiment' => "Чат\-робот находится в *экспериментальном* режиме\n_Просьба сообщать при обнаружении любых проблем, спасибо_", + 'menu_description_guest' => "🔥 *Создайте ваш первый проект* и получите *ориентировочную стоимость* всего за 2 минуты", + 'menu_description_partner' => "*Благодарю за выбор нашей команды*. Теперь Вы один из наших %d партнёров!", 'menu_update' => 'Последнее обновление', 'menu_button_project_new' => 'Создать', 'menu_button_projects' => 'Проекты', @@ -23,16 +22,12 @@ return [ 'account_authorized_settings' => 'Доступ к изменению настроек', 'account_authorized_system_settings' => 'Системный доступ к системным настройкам', - // Настройки языка - 'settings_select_language_title' => 'Выбери язык', - 'settings_select_language_description' => 'Выбранный язык будет записан в настройки аккаунта', - 'settings_language_update_success' => 'Язык заменён:', + // Настройки: язык + 'settings_language_title' => 'Выбери язык', + 'settings_language_description' => 'Выбранный язык будет использоваться для генерации системного отображения', + 'settings_language_update_success' => 'Язык заменён', 'settings_language_update_fail' => 'Не удалось заменить язык', - - // Выбор языка - 'select_language_title' => 'Выбери язык', - 'select_language_description' => 'Выбранный язык будет использован в текущем процессе', - 'select_language_button_add' => 'Добавить язык', + 'settings_language_button_add' => 'Добавить язык', // Авторизация 'not_authorized_system' => 'У тебя нет доступа к системе', diff --git a/kodorvan/constructor/system/models/account.php b/kodorvan/constructor/system/models/account.php index 09211c4..7b74e2a 100644 --- a/kodorvan/constructor/system/models/account.php +++ b/kodorvan/constructor/system/models/account.php @@ -30,7 +30,7 @@ use mirzaev\record\interfaces\record as record_interface, use svoboda\time\statement as svoboda; // Framework for Telegram -use Zanzara\Telegram\Type\User as telegram_user; +use SergiX44\Nutgram\Telegram\Types\User\User as telegram_user; // Built-in libraries use Exception as exception, @@ -51,7 +51,7 @@ final class account extends core implements record_interface /** * File * - * @var string $database Path to the database file + * @var string $file Path to the database file */ protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'accounts.baza'; @@ -107,26 +107,26 @@ final class account extends core implements record_interface public function initialize(telegram_user $telegram): ?static { // Searching for the account in the database - $account = $this->database->read(filter: fn(record $record) => $record->identifier_telegram === $telegram->getId(), amount: 1)[0] ?? null; + $account = $this->database->read(filter: fn(record $record) => $record->identifier_telegram === $telegram->id, amount: 1)[0] ?? null; if ($account instanceof record) { // Found the account record if ( - $account->domain !== (string) $telegram->getUsername() || - $account->name_first !== (string) $telegram->getFirstName() || - $account->name_second !== (string) $telegram->getLastName() + $account->domain !== (string) $telegram->username || + $account->name_first !== (string) $telegram->first_name || + $account->name_second !== (string) $telegram->last_name ) { // The telegram account was updated // Updating the account in the database $updated = $this->database->read( - filter: fn(record $record) => $record->identifier_telegram === $telegram->getId(), + filter: fn(record $record) => $record->identifier_telegram === $telegram->id, update: function (record &$record) use ($telegram) { // Writing new values into the record - $record->domain = (string) $telegram->getUsername(); - $record->name_first = (string) $telegram->getFirstName(); - $record->name_second = (string) $telegram->getLastName(); + $record->domain = (string) $telegram->username; + $record->name_first = (string) $telegram->first_name; + $record->name_second = (string) $telegram->last_name; $record->updated = svoboda::timestamp(); }, amount: 1 @@ -166,7 +166,7 @@ final class account extends core implements record_interface // Registered the account // Searching for the registered account in the database - $registered = $this->database->read(filter: fn(record $record) => $record->identifier_telegram === $telegram->getId(), amount: 1)[0] ?? null; + $registered = $this->database->read(filter: fn(record $record) => $record->identifier_telegram === $telegram->id, amount: 1)[0] ?? null; if ($registered instanceof record) { // Found the registered account @@ -207,12 +207,12 @@ final class account extends core implements record_interface { // Creating the record $record = $this->write( - telegram_identifier: (int) $telegram->getId(), - name_first: (string) $telegram->getFirstName(), - name_second: (string) $telegram->getLastName(), - domain: (string) $telegram->getUsername(), - language: (string) $telegram->getLanguageCode(), - robot: (bool) $telegram->isBot() + telegram_identifier: (int) $telegram->id, + name_first: (string) $telegram->first_name, + name_second: (string) $telegram->last_name, + domain: (string) $telegram->username, + language: (string) $telegram->language_code, + robot: (bool) $telegram->is_bot ); if ($record instanceof record) { @@ -396,4 +396,55 @@ final class account extends core implements record_interface // Exit (success/fail) return $projects; } + + /** + * Partners + * + * Search for accounts that have at least one project in development + * + * @param int $amount Maximum amount + * + * @return array Partners accounts without duplicates + */ + public static function partners(int $amount = PHP_INT_MAX): array + { + try { + // Search for projects + $projects = new project()->database->read( + filter: fn(record $record) => + $record->active === 1 + && match (project_status::{$record->status}) { + project_status::developing, project_status::developed, project_status::launched => true, + default => false + }, + amount: $amount + ); + + // Declaring the registry of partners accounts + $partners = []; + + foreach ($projects as $project) { + // Iterating over projects + + if (isset($partners[$project->account])) { + // The partner account is already was in the partners accounts registry + + // Skipping the iteration + continue; + } + + // Searching the partner account and writing into the partners accounts registry + $partners[$project->account] = new account()->read(filter: fn(record $record) => $record->identifier === $project->account); + } + + // Exit (success) + return $partners; + } catch (exception $exception) { + // Writing the exception into the errors output buffer + error_log((string) $exception); + } + + // Exit (fail) + return []; + } } diff --git a/kodorvan/constructor/system/models/authorizations.php b/kodorvan/constructor/system/models/authorizations.php index ef7858e..ae19b69 100644 --- a/kodorvan/constructor/system/models/authorizations.php +++ b/kodorvan/constructor/system/models/authorizations.php @@ -21,9 +21,6 @@ use mirzaev\record\interfaces\record as record_interface, // Svoboda time use svoboda\time\statement as svoboda; -// Framework for Telegram -use Zanzara\Telegram\Type\User as telegram; - // Built-in libraries use Exception as exception, RuntimeException as exception_runtime; @@ -43,7 +40,7 @@ final class authorizations extends core implements record_interface /** * File * - * @var string $database Path to the database file + * @var string $file Path to the database file */ protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'authorizations.baza'; diff --git a/kodorvan/constructor/system/models/core.php b/kodorvan/constructor/system/models/core.php index 8606197..22401f7 100644 --- a/kodorvan/constructor/system/models/core.php +++ b/kodorvan/constructor/system/models/core.php @@ -41,4 +41,3 @@ class core extends model { } } - diff --git a/kodorvan/constructor/system/models/localization.php b/kodorvan/constructor/system/models/localization.php new file mode 100644 index 0000000..ea7cada --- /dev/null +++ b/kodorvan/constructor/system/models/localization.php @@ -0,0 +1,201 @@ + + */ +final class localization extends core implements array_access +{ + /** + * File + * + * @var string $file Path to the localization file + */ + protected string $file; + + /** + * Language + * + * @var language $language The localization language + */ + public readonly language $language; + + /** + * Registry + * + * @var array $registry The localization records + */ + protected array $registry; + + /** + * Constructor + * + * @method language $language The language + * + * @throws exception_runtime If failed to initialize the localization file + * + * @return void + */ + public function __construct(language $language) + { + // Initializing the localization language + $this->language = $language; + + // Initializing the path to the localization file + $this->file = LOCALIZATIONS . DIRECTORY_SEPARATOR . strtolower($this->language->label()) . '.php'; + + if (file_exists($this->file) && is_readable($this->file)) { + // Found the localization file + + // Initializing the localization registry + $this->registry = require($this->file); + } else { + // Not found the localization file + + // Exit (fail) + throw new exception_runtime('Failed to initialize the localization file'); + } + } + + /** + * Write as array + * + * @param mixed $offset The record name + * @param mixed $value The record value + * + * @return void + */ + public function offsetSet(mixed $offset, mixed $value): void + { + if (is_null($offset)) { + // Not received name of the localization record + + // Exit (fail) + throw new exception_logic('Failed to initialized the localization record name'); + } else { + // Received name of the localization record + + // Writing the record into into the registry + $this->registry[$offset] = $value; + } + } + + /** + * Read as from array + * + * @param mixed $offset The record name + * + * @return mixed The record value + */ + public function offsetGet(mixed $offset): mixed + { + // Reading the record from the registry and exit (success) + return $this->registry[$offset] ?? null; + } + + /** + * Check for initializing as array + * + * @param mixed $offset The record name + * + * @return bool Is the record initialized? + */ + public function offsetExists(mixed $offset): bool + { + // Checking the record existance in the registry and exit (success) + return isset($this->registry[$offset]); + } + + /** + * Delete as from array + * + * @param mixed $offset The record name + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + // Deleting the record from the registry and exit (succes) + unset($this->registry[$offset]); + } + + /** + * Write + * + * @param string $name The record name + * @param mixed $value The record value + * + * @return void + */ + public function __set(string $name, mixed $value = null): void + { + // Writing the record into the registry + $this->registry[$name] = $value; + } + + /** + * Read + * + * @param string $name The record name + * + * @return mixed The record value + */ + public function __get(string $name): mixed + { + // Reading the record from the registry and exit (success) + return $this->registry[$name]; + } + + /** + * Check for initializing + * + * @param string $name The record name + * + * @return bool Is the record initialized? + */ + public function __isset(string $name): bool + { + // Check for initializing of the property and exit (success) + return isset($this->registry[$name]); + } + + /** + * Delete + * + * @param string $name The record name + * + * @return void + */ + public function __unset(string $name): void + { + // Deleting the record from the registry and exit (success) + unset($this->registry[$name]); + } +} diff --git a/kodorvan/constructor/system/models/project.php b/kodorvan/constructor/system/models/project.php index f3080df..41cc090 100644 --- a/kodorvan/constructor/system/models/project.php +++ b/kodorvan/constructor/system/models/project.php @@ -42,7 +42,7 @@ final class project extends core implements record_interface /** * File * - * @var string $database Path to the database file + * @var string $file Path to the database file */ protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'project.baza'; diff --git a/kodorvan/constructor/system/models/project/enumerations/status.php b/kodorvan/constructor/system/models/project/enumerations/status.php index 860b599..8a7dc9e 100644 --- a/kodorvan/constructor/system/models/project/enumerations/status.php +++ b/kodorvan/constructor/system/models/project/enumerations/status.php @@ -21,6 +21,9 @@ enum status case creating; case calculated; case requested; + + case invoiced; + case developing; case developed; case launched; diff --git a/kodorvan/constructor/system/models/settings.php b/kodorvan/constructor/system/models/settings.php index 98a8bc5..74eb3ae 100644 --- a/kodorvan/constructor/system/models/settings.php +++ b/kodorvan/constructor/system/models/settings.php @@ -40,7 +40,7 @@ final class settings extends core implements record_interface /** * File * - * @var string $database Path to the database file + * @var string $file Path to the database file */ protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'settings.baza'; diff --git a/kodorvan/constructor/system/models/telegram/commands.php b/kodorvan/constructor/system/models/telegram/commands.php index c286fb9..f3aeb70 100644 --- a/kodorvan/constructor/system/models/telegram/commands.php +++ b/kodorvan/constructor/system/models/telegram/commands.php @@ -31,127 +31,6 @@ use Zanzara\Context as context, */ final class commands extends core { - /** - * Start - * - * Responce for command: "/start" - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function start(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing the language - $language = $context->get('language'); - - if ($language instanceof language) { - // Initialized the language - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Initializing the message title text - $title = '📋 *' . $localization['menu_title'] . '*'; - - // Initializing the keyboard array - /* $keyboard = []; - - foreach (project) */ - - // Calculating amount of projects - $projects = count($account->projects()); - - // Initializing the message description text - $description = $projects > 0 ? $localization['menu_description_partner'] : ('🔥 ' . $localization['menu_description_guest']); - - // Initializing the message experiment text - $experiment = '⚠️ ' . $localization['menu_experiment']; - - // Initializing the message last update text - exec(command: 'git log --oneline $(git describe --tags --abbrev=0 @^ --always)..@ -1 --format="%at" | xargs -I{} date -d @{} "+%Y.%m.%d %H:%M"', output: $git); - $update = empty($git[0]) ? '' : "\n\n🔏 *" . $localization['menu_update'] . ':* ' . unmarkdown($git[0]); - - // Sending the message - $context->sendMessage( - << [ - 'inline_keyboard' => [ - [ - [ - 'text' => '📂 ' . $localization['menu_button_project_new'], - 'callback_data' => 'project_create' - ], - [ - 'text' => '🗂 ' . $localization['menu_button_projects'] . ': ' . $projects, - 'callback_data' => 'projects' - ] - ], - [ - [ - 'text' => '📡 ' . $localization['menu_button_operator'], - 'callback_data' => 'operator' - ] - ] - ], - 'disable_notification' => true, - 'remove_keyboard' => true - ], - ] - )->then(function (message $message) use ($context) { - // Sended the message - - }); - } 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 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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } - /** * Account * @@ -239,135 +118,4 @@ final class commands extends core }); } } - - /** - * 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 account) { - // 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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // 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 account) { - // 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) { - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') - ->then(function (message $message) use ($context) { - // Ending the conversation process - $context->endConversation(); - }); - } - } } diff --git a/kodorvan/constructor/system/models/telegram/commands/language.php b/kodorvan/constructor/system/models/telegram/commands/language.php new file mode 100644 index 0000000..1a8c608 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/commands/language.php @@ -0,0 +1,172 @@ + + */ +final class language extends command +{ + /** + * Command + * + * @var string $name Name of the command + */ + protected string $command = 'language'; + + /** + * Description + * + * @var string $description + */ + protected ?string $description = 'System language'; + + /** + * Localizations + * + * Descriptions of the command + * + * @var array $localizedDescriptions + */ + protected array $localizedDescriptions = [ + 'ru' => 'Язык системы', + '*' => 'System language' + ]; + + /** + * Handle + * + * Processing the command + * + * @param telegram $robot The chat-robot instance + * + * @return void + */ + public function handle(telegram $robot): void + { + // Initializing the language + $language = $robot->get('language') ?? LANGUAGE_DEFAULT; + + // Initializing the localization + $localization = $robot->get('localization') ?? new localization($language); + + $this::menu( + robot: $robot, + prefix: 'settings_language_', + title: "🌏 *$localization->settings_language_title*", + description: $localization->settings_language_description, + language: $language + ); + } + + /** + * Menu + * + * Generate and send the language selection menu + * + * @param telegram $robot The chat-robot instance + * @param string|null $prefix The process prefix + * @param string|null $title The menu message title + * @param string|null $description The menu message description (main content) + * @param array $exclude Languages that will be excluded ['ru', 'en'...] + * @param type $language The menu message language + * + * @return void + */ + public static function menu(telegram $robot, ?string $prefix = null, ?string $title = null, ?string $description = null, array $exclude = [], type $language = LANGUAGE_DEFAULT): void + { + // Initializing the menu message localization + $localization = $robot->get('localization') ?? new localization($language); + + // Initializing the keyboard + $keyboard = keyboard::make(); + + // Initializing the row + $row = []; + + // Initializing the maximum amount of buttons in a row + $length = 4; + + // Initializing buffer of languages + $languages = type::cases(); + + // Deleting the actual language from buffer of languages + unset($languages[array_search($language, $languages, strict: true)]); + + // Sorting buffer of languages by the actual language + $languages = [$language, ...$languages]; + + foreach ($languages as $language) { + // Iterating over languages + + // Skipping excluded languages + if (array_search($language->name, $exclude, strict: true) !== false) continue; + + // Writing the language choose button into the buffer of generated keyboard with languages + $row[] = button::make( + text: ($language->flag() ? $language->flag() . ' ' : '') . $language->label($language), + callback_data: $prefix . $language->name + ); + + if (count($row) >= $length) { + // Reached the limit of buttons in a row + + // Writing the row into the keyboard + $keyboard->addRow(...$row); + + // Reinitializing the row + $row = []; + } + } + + if (count($row) / $length < 1) { + // The row was not writed + + // Writing the row into the keyboard + $keyboard->addRow(...$row); + } + + // Writing the row into the keyboard + $keyboard->addRow(button::make( + text: '🗂 ' . $localization->settings_language_button_add, + url: PROJECT_REPOSITORY_LANGUAGE_ADD + )); + + // Sending the message + $robot->sendMessage( + text: ($title ?? "🌏 *$localization->settings_language_title*") . "\n\n" . ($description ?? $localization->settings_language_description), + parse_mode: mode::MARKDOWN, + disable_notification: true, + reply_markup: $keyboard, + ); + } +} diff --git a/kodorvan/constructor/system/models/telegram/commands/society.php b/kodorvan/constructor/system/models/telegram/commands/society.php new file mode 100644 index 0000000..889ab11 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/commands/society.php @@ -0,0 +1,79 @@ + + */ +final class society extends command +{ + /** + * Command + * + * @var string $name Name of the command + */ + protected string $command = 'society'; + + /** + * Description + * + * @var string $description + */ + protected ?string $description = 'thing about it'; + + /** + * Localizations + * + * Descriptions of the command + * + * @var array $localizedDescriptions + */ + protected array $localizedDescriptions = [ + '*' => 'thing about it' + ]; + + /** + * Handle + * + * Processing the command + * + * @param telegram $robot The chat-robot instance + * + * @return void + */ + public function handle(telegram $robot): void + { + $robot->sendPhoto( + photo: input::make(STORAGE . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'mushroom.jpg'), + caption: $robot->get('localization')['why_so_shroomious'] ?? 'why so shroomious', + disable_notification: true, + parse_mode: mode::MARKDOWN + ); + } +} diff --git a/kodorvan/constructor/system/models/telegram/commands/start.php b/kodorvan/constructor/system/models/telegram/commands/start.php index 3ce2c0d..6079bea 100644 --- a/kodorvan/constructor/system/models/telegram/commands/start.php +++ b/kodorvan/constructor/system/models/telegram/commands/start.php @@ -8,6 +8,7 @@ namespace kodorvan\constructor\models\telegram\commands; use kodorvan\constructor\models\core, kodorvan\constructor\models\account, kodorvan\constructor\models\settings, + kodorvan\constructor\models\localization, kodorvan\constructor\models\telegram\processes\language\select as process_language_select; // Library for languages support @@ -17,7 +18,13 @@ use mirzaev\languages\language; use function mirzaev\unmarkdown; // Framework for Telegram -use Telegram\Bot\Commands\Command as command; +use SergiX44\Nutgram\Nutgram as telegram, + SergiX44\Nutgram\Telegram\Properties\ParseMode as mode, + SergiX44\Nutgram\Telegram\Types\Message\Message as message, + SergiX44\Nutgram\Handlers\Type\Command as command, + SergiX44\Nutgram\Telegram\Types\Internal\InputFile as input, + SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup as keyboard, + SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton as button; /** * Command: start @@ -30,18 +37,96 @@ use Telegram\Bot\Commands\Command as command; final class start extends command { /** - * Start + * Command * * @var string $name Name of the command */ - protected string $name = 'start'; + protected string $command = 'start'; - protected string $description = 'Start Command to get you started'; + /** + * Description + * + * @var string $description + */ + protected ?string $description = 'Main menu'; - public function handle() + /** + * Localizations + * + * Descriptions of the command + * + * @var array $localizedDescriptions + */ + protected array $localizedDescriptions = [ + 'ru' => 'Главное меню', + '*' => 'Main menu' + ]; + + /** + * Handle + * + * Processing the command + * + * @param telegram $robot The chat-robot instance + * + * @return void + */ + public function handle(telegram $robot): void { - $this->replyWithMessage([ - 'text' => 'Hey, there! Welcome to our bot!', - ]); + // Initializing the language + $language = $robot->get('language') ?? LANGUAGE_DEFAULT; + + // Initializing the menu message localization + $localization = $robot->get('localization') ?? new localization($language); + + // Initializing the account + $account = $robot->get('account'); + + // Initializing the message last update text + exec(command: 'git log --oneline $(git describe --tags --abbrev=0 @^ --always)..@ -1 --format="%at" | xargs -I{} date -d @{} "+%Y.%m.%d %H:%M"', output: $git); + $update = empty($git[0]) ? '' : "🔏 *$localization->menu_update:* " . unmarkdown($git[0]); + + // Calculating amount of projects + $projects = count($account->projects()); + + // Calculating amount of partners + $partners = count(account::partners()); + + // Initializing the keyboard + $keyboard = keyboard::make(); + + // Writing the row into the keyboard + $keyboard->addRow( + button::make( + text: "📂 $localization->menu_button_project_new", + callback_data: 'project_create' + ), + button::make( + text: "🗂 $localization->menu_button_projects: $projects", + callback_data: 'projects' + ), + ); + + // Writing the row into the keyboard + $keyboard->addRow( + button::make( + text: "📡 $localization->menu_button_operator", + callback_data: 'operator' + ) + ); + + $robot->sendMessage( + text: implode( + "\n\n", + [ + "📋 *$localization->menu_title*", + $projects > 0 ? printf($localization->menu_description_partner, $partners) : $localization->menu_description_guest, + $update + ] + ), + parse_mode: mode::MARKDOWN, + disable_notification: true, + reply_markup: $keyboard + ); } } diff --git a/kodorvan/constructor/system/models/telegram/middlewares.php b/kodorvan/constructor/system/models/telegram/middlewares.php deleted file mode 100644 index 4a45a88..0000000 --- a/kodorvan/constructor/system/models/telegram/middlewares.php +++ /dev/null @@ -1,469 +0,0 @@ - - */ -final class middlewares extends core -{ - /** - * Account (middleware) - * - * Initialize or registrate the account and write it into the `account` variable inside the `$context` - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function account(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the telegram account - $telegram = $context->getEffectiveUser(); - - // Initializing the account - $account = new account()->initialize($telegram); - - if ($account instanceof account) { - // Initialized the account - - // Writing the account into the context variable - $context->set('account', $account); - - // Continuation of the process - $next($context); - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Authorizations (middleware) - * - * Initialize the account authorizations and write them into the `authorizations` variable inside the `$context` - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function authorizations(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing the account authorizations - $authorizations = $account->authorizations(); - - if ($authorizations instanceof authorizations) { - // Initialized the account authorizations - - // Writing the account authorizations into the context variable - $context->set('authorizations', $authorizations); - - // Continuation of the process - $next($context); - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize your Telegram account authorizations*') - ->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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Language (middleware) - * - * Implement the account language - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function language(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - if ($account->language instanceof language) { - // Initialized the language parameter - - try { - // Writing the account language into the context variable - $context->set('language', $account->language); - } catch (error $error) { - // Not initialized the language - - // Writing the default language into the context variable - $context->set('language', LANGUAGE_DEFAULT ?? language::en); - } - } else { - // Not initialized the language parameter - - // Writing the default language into the context variable - $context->set('language', LANGUAGE_DEFAULT ?? language::en); - } - - // Continuation of the process - $next($context); - } else { - // Not initialized the account - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Localization (middleware) - * - * Implement the account language and initialize the localization file - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function localization(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing the language - $language = $context->get('language'); - - if ($language instanceof language) { - // Initialized the language - - // Initializing path to the localization file - $file = LOCALIZATIONS . DIRECTORY_SEPARATOR . strtolower($language->label()) . '.php'; - - if (file_exists($file) && is_readable($file)) { - // Found the localization file - - // Initializing localization - $localization = require($file); - - if (is_array($localization)) { - // Initialized the localization - - // Writing localization into the context variable - $context->set('localization', $localization); - - // Continuation of the process - $next($context); - } else { - // Not initialized the 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 found the localization file - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize the localization file*') - ->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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * Settings (middleware) - * - * Check the account for access to the settings - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function settings(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing the account authorizations - $authorizations = $context->get('authorizations'); - - if ($authorizations instanceof authorizations) { - // Initialized the account authorizations - - if ($authorizations->settings) { - // Authorized the account to the settings - - // Continuation of the process - $next($context); - } else { - // Not authorized the account to the settings - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Sending the message - $context->sendMessage('⛔ *' . $localization['not_authorized_settings'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - - // Stopping the process - $context->set('stop', 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 authorizations - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize your Telegram account authorizations*') - ->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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - - /** - * System settings (middleware) - * - * Check the account for access to the system settings - * - * @param context $context - * @param node $next - * - * @return void - */ - public static function system_settings(context $context, node $next): void - { - // Is the process stopped? - if ($context->get('stop')) return; - - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing the account authorizations - $authorizations = $context->get('authorizations'); - - if ($authorizations instanceof authorizations) { - // Initialized the account authorizations - - if ($authorizations->system_settings) { - // Authorized the account to the system settings - - // Continuation of the process - $next($context); - } else { - // Not authorized the account to the system settings - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Sending the message - $context->sendMessage('⛔ *' . $localization['not_authorized_system_settings'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - - // Stopping the process - $context->set('stop', 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 your Telegram account authorizations*') - ->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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } -} - diff --git a/kodorvan/constructor/system/models/telegram/middlewares/account.php b/kodorvan/constructor/system/models/telegram/middlewares/account.php new file mode 100644 index 0000000..124e5d1 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/account.php @@ -0,0 +1,77 @@ + + */ +final class account extends core +{ + /** + * Account + * + * Initialize or registrate the account and write it into the `account` variable inside the `$robot` + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the telegram account + $telegram = $robot->user(); + + // Initializing the account + $account = new model()->initialize(telegram: $telegram); + + if ($account instanceof model) { + // Initialized the account + + // Writing the account into the robot variable + $robot->set('account', $account); + + // Continuation of the process + $next($robot); + } else { + // Not initialized the account + + // Sending the message + $robot->sendMessage( + text: '⚠️ *Failed to initialize your Telegram account*', + parse_mode: mode::MARKDOWN + ); + + // Ending the conversation process + $robot->endConversation(); + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/middlewares/authorizations.php b/kodorvan/constructor/system/models/telegram/middlewares/authorizations.php new file mode 100644 index 0000000..4fd3998 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/authorizations.php @@ -0,0 +1,81 @@ + + */ +final class authorizations extends core +{ + /** + * Authorizations + * + * Initialize the account authorizations and write them into the `authorizations` variable inside the `$robot` + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + // Initializing the account authorizations + $authorizations = $account->authorizations(); + + if ($authorizations instanceof model) { + // Initialized the account authorizations + + // Writing the account authorizations into the robot variable + $robot->set('authorizations', $authorizations); + + // Continuation of the process + $next($robot); + } else { + // Not initialized the account authorizations + + // Sending the message + $robot->sendMessage( + text: '⚠️ *Failed to initialize your Telegram account authorizations*', + parse_mode: mode::MARKDOWN + ); + + // Ending the conversation process + $robot->endConversation(); + } + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/middlewares/language.php b/kodorvan/constructor/system/models/telegram/middlewares/language.php new file mode 100644 index 0000000..c61ebeb --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/language.php @@ -0,0 +1,79 @@ + + */ +final class language extends core +{ + /** + * Language + * + * Implement the account language + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + if ($account->language instanceof type) { + // Initialized the language parameter + + try { + // Writing the account language into the robot variable + $robot->set('language', $account->language); + } catch (error $error) { + // Not initialized the language + + // Writing the default language into the robot variable + $robot->set('language', LANGUAGE_DEFAULT ?? type::en); + } + } else { + // Not initialized the language parameter + + // Writing the default language into the robot variable + $robot->set('language', LANGUAGE_DEFAULT ?? type::en); + } + + // Continuation of the process + $next($robot); + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/middlewares/localization.php b/kodorvan/constructor/system/models/telegram/middlewares/localization.php new file mode 100644 index 0000000..568b5d7 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/localization.php @@ -0,0 +1,91 @@ + + */ +final class localization extends core +{ + /** + * Localization + * + * Implement the account language and initialize the localization file + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + // Initializing the language + $language = $robot->get('language'); + + if ($language instanceof language) { + // Initialized the language + + try { + // Initializing the localization + $localization = new model($language); + + // Writing localization into the robot variable + $robot->set('localization', $localization); + + // Continuation of the process + $next($robot); + } catch (exception $exception) { + // Not initialized the localization + + // Writing the exception into the errors output buffer + error_log((string) $exception); + + // Sending the message + $robot->sendMessage( + text: '⚠️ *Failed to initialize the localization*', + parse_mode: mode::MARKDOWN + ); + + // Ending the conversation process + $robot->endConversation(); + } + } + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/middlewares/settings.php b/kodorvan/constructor/system/models/telegram/middlewares/settings.php new file mode 100644 index 0000000..6ebeee7 --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/settings.php @@ -0,0 +1,92 @@ + + */ +final class settings extends core +{ + /** + * Settings + * + * Implement the account language + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + // Initializing the account authorizations + $authorizations = $robot->get('authorizations'); + + if ($authorizations instanceof authorizations) { + // Initialized the account authorizations + + if ($authorizations->settings) { + // Authorized the account to the settings + + // Continuation of the process + $next($robot); + } else { + // Not authorized the account to the settings + + // Initializing localization + $localization = $robot->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $robot->sendMessage( + text: '⛔ *' . $localization['not_authorized_settings'] . '*', + parse_mode: mode::MARKDOWN + ); + + // Ending the conversation process + $robot->endConversation(); + + // Stopping the process + $robot->set('stop', true); + } + } + } + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/middlewares/system/settings.php b/kodorvan/constructor/system/models/telegram/middlewares/system/settings.php new file mode 100644 index 0000000..8a6169f --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/middlewares/system/settings.php @@ -0,0 +1,92 @@ + + */ +final class settings extends core +{ + /** + * System settings (middleware) + * + * Check the account for access to the system settings + * + * @param telegram $robot + * @param $next + * + * @return void + */ + public function __invoke(telegram $robot, $next): void + { + // Is the process stopped? + if ($robot->get('stop')) return; + + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + // Initializing the account authorizations + $authorizations = $robot->get('authorizations'); + + if ($authorizations instanceof authorizations) { + // Initialized the account authorizations + + if ($authorizations->system_settings) { + // Authorized the account to the system settings + + // Continuation of the process + $next($robot); + } else { + // Not authorized the account to the system settings + + // Initializing localization + $localization = $robot->get('localization'); + + if ($localization) { + // Initialized localization + + // Sending the message + $robot->sendMessage( + text: '⛔ *' . $localization['not_authorized_system_settings'] . '*', + parse_mode: mode::MARKDOWN + ); + + // Ending the conversation process + $robot->endConversation(); + + // Stopping the process + $robot->set('stop', true); + } + } + } + } + } +} diff --git a/kodorvan/constructor/system/models/telegram/processes/language/select.php b/kodorvan/constructor/system/models/telegram/processes/language/select.php deleted file mode 100644 index 01f0f3d..0000000 --- a/kodorvan/constructor/system/models/telegram/processes/language/select.php +++ /dev/null @@ -1,152 +0,0 @@ - - */ -final class select extends core -{ - /** - * Language - * - * Send the language choose menu - * - * @param context $context Request data from Telegram - * @param string $prefix Prefix for 'callback_data' (`$prefix . $language->name`) - * @param string $title Title of the message - * @param string $description Description of the message - * @param array $exclude Languages that will be excluded ['ru', 'en'...] - * - * @return void - */ - public static function menu(context $context, string $prefix, string $title, string $description, array $exclude = []): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof record) { - // Initialized the account - - // Initializing language - $language = $context->get('language'); - - if ($language) { - // Initialized language - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Declaring the buffer of generated keyboard with languages - $keyboard = []; - - // Initializing the iterator of rows - $row = 0; - - // Initializing buffer of languages - $languages = language::cases(); - - // Deleting the actual language from buffer of languages - unset($languages[array_search($language, $languages, strict: true)]); - - // Sorting buffer of languages by the actual language - $languages = [$language, ...$languages]; - - foreach ($languages as $language) { - // Iterating over languages - - // Skipping excluded languages - if (array_search($language->name, $exclude, strict: true) !== false) continue; - - // Initializing the row - $keyboard[$row] ??= []; - - // Writing the language choose button into the buffer of generated keyboard with languages - $keyboard[$row][] = [ - 'text' => ($language->flag() ? $language->flag() . ' ' : '') . $language->label($language), - 'callback_data' => $prefix . $language->name - ]; - - // When reaching 4 buttons in a row, move to the next row - if (count($keyboard[$row]) === 4) ++$row; - } - - // Writing the button for helping lozalizing - $keyboard[$row === 0 && empty($keyboard[0]) ? 0 : ++$row] = [ - [ - 'text' => '🗂 ' . $localization['select_language_button_add'], - 'url' => 'https://git.svoboda.works/kodorvan\constructor/src/branch/stable/kodorvan/neurobot/system/localizations' - ] - ]; - - // Sending the message - $context->sendMessage( - $title ?? '🌏 *' . $localization['select_language_title'] . "*\n" . ($description ?? $localization['select_language_description']), - [ - 'reply_markup' => [ - 'inline_keyboard' => $keyboard, - '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 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 your Telegram account*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } -} diff --git a/kodorvan/constructor/system/models/telegram/processes/project/create.php b/kodorvan/constructor/system/models/telegram/processes/project/create.php deleted file mode 100644 index fe17b58..0000000 --- a/kodorvan/constructor/system/models/telegram/processes/project/create.php +++ /dev/null @@ -1,894 +0,0 @@ - - */ -final class create extends core -{ - /** - * Start - * - * Starting the account localization creating process - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function start(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // 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 - - // Searching for the project - $project = $account->projects(status: project_status::creation, amount: 1)[0] ?? null; - - if ($project instanceof project) { - // Found the project - - // Sending the project creation menu - static::menu($context); - } else { - // Not found the project - - // Initializing buffer of languages - $languages = language::cases(); - - // Deleting the actual language from buffer of languages - unset($languages[array_search($language, $languages, strict: true)]); - - // Sorting buffer of languages by the actual language - $languages = [$language, ...$languages]; - - // Initializing the account model - $model_account = new account; - - // Initializing the account localizations - $existed = $model_account->localization->database->read( - filter: fn(record $localization) => $localization->account === $account->identifier, - amount: ACCOUNT_LOCALIZATION_CREATE_ACCOUNT_LOCALIZATIONS_AMOUNT - ); - - if (count($existed) !== count(language::cases())) { - // Not all languages in the registry have localizations created (expected) - - // Declaring the buffer of languages to exclude - $exclude = []; - - // Initializing languages to exclude - foreach ($existed as $record) $exclude[] = $record->language; - - if (!empty($exclude)) { - // Initialized languages to exclude - - // Deleting excluded languages - $languages = array_filter($languages, fn(language $language) => array_search($language->name, $exclude, strict: true) === false); - } - - // Initializing the account localization create buffer - $process = [ - 'language' => array_values($languages)[0], - 'name' => null, - ]; - - // Writing to the telegram user buffer - $context->setUserDataItem(static::PROCESS, $process) - ->then(function () use ($context, $account, $localization) { - // Writed to the telegram user buffer - - // Sending the message - $context->sendMessage('📂 *' . $localization['account_localization_create_started'] . '*') - ->then(function (message $message) use ($context, $account, $localization) { - // Sended the message - - // Sending the account localization create menu - static::menu($context); - }); - }); - } else { - // All languages in the registry have localizations created (expected) - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_every_language_created'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } - } 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 language - - // Sending the message - $context->sendMessage('⚠️ *Failed to initialize language*') - ->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(); - }); - } - } - - /** - * Cancel - * - * Ending the account localization create process - * without creating the localization record in the database - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function cancel(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Reading from the telegram user buffer - $context->getUserDataItem(static::PROCESS) - ->then(function (?array $process) use ($context, $localization) { - // Readed from the telegram user buffer - - if ($process) { - // Found started account localization create process - - // Deleting in the telegram user buffer - $context->deleteUserDataItem(static::PROCESS) - ->then(function () use ($context, $localization) { - // Deleted in the telegram user buffer - - // Sending the message - $context->sendMessage('🗑 *' . $localization['account_localization_create_canceled'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - }); - } else { - // Not found started account localization create process - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - } - }); - } 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(); - }); - } - } - - /** - * End - * - * Ending the account localization create process - * and creating the localization record in the database - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function end(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // 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 - - // Reading from the telegram user buffer - $context->getUserDataItem(static::PROCESS) - ->then(function (?array $process) use ($context, $account, $language, $localization) { - // Readed from the telegram user buffer - - if ($process) { - // Found started account localization create process - - // Initializing the account model - $model_account = new account; - - // Creating the account localization - $created_localization = $model_account->localization->create( - account: $account->identifier, - language: $process['language'], - name: $process['name'] - ); - - if ($created_localization) { - // Created the account localization - - // Sending the message - $context->sendMessage('✏️ *' . $localization['account_localization_create_created'] . '*') - ->then(function (message $message) use ($context, $account, $language, $localization) { - // Sended the message - - // Deleting from the telegram user buffer - $context->deleteUserDataItem(static::PROCESS) - ->then(function () use ($context, $localization) { - // Deleted from the telegram user buffer - - // Sending the message - $context->sendMessage('✅ *' . $localization['account_localization_create_completed'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - }); - }); - } else { - // Not created the account localization - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_created'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not found started account localization create process - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - } - }); - } 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(); - }); - } - } - - /** - * Menu - * - * Sends the account localization create menu with parameters: language, name - * When all parameters was initialized then sends the complete button - * - * @param context $context Request data from Telegram - * - * @return void - */ - protected static function menu(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing language - $language = $context->get('language'); - - if ($language) { - // Initialized language - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Reading from the telegram user buffer - $context->getUserDataItem(static::PROCESS) - ->then(function (?array $process) use ($context, $account, $language, $localization) { - // Readed from the telegram user buffer - - if ($process) { - // Found started account localization create process - - // Initializing the buffer of generated keyboard with languages - $keyboard = [ - [ - [ - 'text' => empty($process['language']) ? '🟢 ' . $localization['account_localization_create_button_language'] : '🟢 ' . $localization['account_localization_create_button_language'] . ': ' . $process['language']->flag() . ' ' . $process['language']->label($language), - 'callback_data' => 'account_localization_create_language' - ] - ], - [ - [ - 'text' => empty($process['name']) ? '🔴 ' . $localization['account_localization_create_button_name'] : '🟢 ' . $localization['account_localization_create_button_name'] . ': ' . $process['name'], - 'callback_data' => 'account_localization_create_name' - ] - ], - ]; - - // Initializing the index of last row - $last = count($keyboard); - - // Initializing the last row - $keyboard[$last] ??= []; - - // Initializing the button for canceling the generation process - $keyboard[$last][] = [ - 'text' => '❎ ' . $localization['account_localization_create_button_cancel'], - 'callback_data' => 'account_localization_create_cancel' - ]; - - if ( - !empty($process['language']) && - !empty($process['name']) - ) { - // Initialized all requeired parameters - - // Initializing the button for completing the generation process - $keyboard[$last][] = [ - 'text' => '✅ ' . $localization['account_localization_create_button_confirm'], - 'callback_data' => 'account_localization_create_end' - ]; - } - - // Ending the conversation process - $context->endConversation() - ->then(function () use ($context, $localization, $keyboard) { - // Deinitialized the conversation process - - // Sending the message - $context->sendMessage( - '📀 *' . $localization['account_localization_create_generation'] . '*', - [ - 'reply_markup' => [ - 'inline_keyboard' => $keyboard, - 'disable_notification' => true, - 'remove_keyboard' => true - ], - ] - ); - }); - } else { - // Not found started account localization create process - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - } - }); - } 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(); - }); - } - } - - /** - * Language - * - * Write language into the account localization create buffer - * - * @param context $context Request data from Telegram - * @param language $new The language - * - * @return void - */ - public static function language(context $context, language $new): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // 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 - - // Reading from the telegram user buffer - $context->getUserDataItem(static::PROCESS) - ->then(function (?array $process) use ($context, $account, $language, $localization, $new) { - // Readed from the telegram user buffer - - if ($process) { - // Found started account localization create process - - try { - // Initializing the old language - $old = $process['language']; - - // Writing into the account localization create process buffer - $process['language'] = $new; - - // Writing to the telegram user buffer - $context->setUserDataItem(static::PROCESS, $process) - ->then(function () use ($context, $account, $language, $localization, $new, $old) { - // Writed to the telegram user buffer - - // Sending the message - $context->sendMessage('✅ *' . $localization['account_localization_create_language_update_success'] . '* ' . ($old->flag() ? $old->flag() . ' ' : '') . $old->label($language) . ' → *' . ($new->flag() ? $new->flag() . ' ' : '') . $new->label($language) . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Sending the account localization create menu - static::menu($context); - }); - }); - } catch (error $error) { - // Failed to send the message about language update - - // Sending the message - $context->sendMessage('❎ *' . $localization['account_localization_create_language_update_fail']) - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Not found started account localization create process - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - } - }); - } 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(); - }); - } - } - - /** - * Name - * - * Write name into the account localization create buffer - * - * @param context $context Request data from Telegram - * - * @return void - */ - public static function name(context $context): void - { - // Initializing the account - $account = $context->get('account'); - - if ($account instanceof account) { - // Initialized the account - - // Initializing localization - $localization = $context->get('localization'); - - if ($localization) { - // Initialized localization - - // Reading from the telegram user buffer - $context->getUserDataItem(static::PROCESS) - ->then(function (?array $process) use ($context, $account, $localization) { - // Readed from the telegram user buffer - - if ($process) { - // Found started account localization create process - - // Initializing the new name - $new = $context->getMessage()->getText(); - - if (!empty($new)) { - // Initialized the new name - - if (mb_strlen($new) >= 2) { - // Passed minimum length check - - if (mb_strlen($new) <= 128) { - // Passed maximum length check - - // Search for restricted characters - preg_match_all('/[\W\d]/u', $new, $matches); - - // Declaring the buffer of found restricted characters - $characters = []; - - foreach ($matches[0] as $match) { - // Iterating over found restricted characters - - if (match ($match) { - ' ', '-' => false, - default => true - }) { - // Found a restricted character - - // Writing into the buffer of found restricted characters - $characters[] = $match; - } - } - - if (empty($characters)) { - // Not found restricted characters - - try { - // Initializing the old name - $old = empty($process['name']) ? '_' . $localization['empty'] . '_' : $process['name']; - - // Writing into the account localization create process buffer - $process['name'] = $new; - - // Writing to the telegram user buffer - $context->setUserDataItem(static::PROCESS, $process) - ->then(function () use ($context, $account, $localization, $new, $old) { - // Writed to the telegram user buffer - - // Escaping characters for markdown - $escaped = str_replace('-', '\\-', $new); - - // Sending the message - $context->sendMessage('✅ *' . $localization['account_localization_create_name_update_success'] . "* $old → *$escaped*") - ->then(function (message $message) use ($context) { - // Sended the message - - // Sending the account localization create menu - static::menu($context); - }); - }); - } catch (error $error) { - // Failed to send the message about name update - - // Sending the message - $context->sendMessage('❎ *' . $localization['account_localization_create_name_update_fail']) - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - }); - } - } else { - // Found restricted characters - - // Initializing title of the message - $title = '⚠️ *' . $localization['account_localization_create_name_request_restricted_characters_title'] . '*'; - - // Initializing description of the message - $description = '*' . $localization['account_localization_create_name_request_restricted_characters_description'] . '* \\' . implode(', \\', $characters); - - // Sending the message - $context->sendMessage( - <<then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Requesting to enter name again - button_account_localization_create::name($context); - }); - } - } else { - // Not passed maximum length check - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_name_request_too_long'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Requesting to enter name again - button_account_localization_create::name($context); - }); - } - } else { - // Not passed minimum length check - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_name_request_too_short'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Requesting to enter name again - button_account_localization_create::name($context); - }); - } - } else { - // Failed to initialize the new name - - // Sending the message - $context->sendMessage('📄 *' . $localization['account_localization_create_name_request_not_acceptable'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Requesting to enter name again - button_account_localization_create::name($context); - }); - } - } else { - // Not found started account localization create process - - // Sending the message - $context->sendMessage('⚠️ *' . $localization['account_localization_create_not_started'] . '*') - ->then(function (message $message) use ($context) { - // Sended the message - - // Ending the conversation process - $context->endConversation(); - - // Sending the account localizations menu - telegram_account::localizations($context); - }); - } - }); - } 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/kodorvan/constructor/system/models/telegram/settings.php b/kodorvan/constructor/system/models/telegram/settings.php new file mode 100644 index 0000000..2b26abf --- /dev/null +++ b/kodorvan/constructor/system/models/telegram/settings.php @@ -0,0 +1,123 @@ + + */ +final class settings extends core +{ + /** + * Language + * + * Write the language into the account and the robot instance + * + * @param telegram $robot The chat-robot instance + * @param language $language The language + * + * @return void + */ + public static function language(telegram $robot, language $language = LANGUAGE_DEFAULT): void + { + // Initializing the account + $account = $robot->get('account'); + + if ($account instanceof account) { + // Initialized the account + + // Initializing the menu message localization + $localization = new localization($language); + + if ($localization instanceof localization) { + // Initialized the localization + + // Initializing the account old language + $from = $account->language; + + // Writing the language into the account + $account->language = $language; + + // Serializing the account + $account->serialize(); + + // Writing the account into the database; + $updated = $account->update(); + + // Deserializing the account + $account->deserialize(); + + if ($updated instanceof account) { + // Writed the account into the database + + // Writing the account into the robot instance + $robot->set('account', $account); + + try { + // Initializing the account new language + $to = $account->language; + + // Sending the message + $robot->sendMessage( + text: "✅ *$localization->settings_language_update_success:* " . trim($from->flag() . ' ' . $from->label($to)) . ' → *' . trim($to->flag() . ' ' . $to->label($to)) . '*', + parse_mode: mode::MARKDOWN, + disable_notification: true + ); + + // Sending the message + $robot->answerCallbackQuery( + text: $to->label($to), + show_alert: false + ); + } catch (error $error) { + // Failed to send the message about language update + + // Writing into the errors output buffer + error_log((string) $error); + + // Sending the message + $robot->sendMessage( + text: "❎ *$localization->settings_language_update_fail*", + parse_mode: mode::MARKDOWN, + disable_notification: true + ); + + // Ending the conversation process + $robot->endConversation(); + } + } + } + } + } +} diff --git a/kodorvan/constructor/system/public/telegram/constructor/install.php b/kodorvan/constructor/system/public/telegram/constructor/install.php index f781124..fa8463b 100644 --- a/kodorvan/constructor/system/public/telegram/constructor/install.php +++ b/kodorvan/constructor/system/public/telegram/constructor/install.php @@ -18,7 +18,10 @@ use mirzaev\minimal\core, mirzaev\minimal\route; // Framework for Telegram -use Telegram\Bot\BotsManager as telegram; +/* use Telegram\Bot\BotsManager as telegram; */ +use SergiX44\Nutgram\Nutgram as telegram, + SergiX44\Nutgram\RunningMode\Webhook as webhook, + SergiX44\Nutgram\Telegram\Types\Internal\InputFile as input; // Enabling debugging /* ini_set('error_reporting', E_ALL); @@ -55,7 +58,19 @@ define('TELEGRAM', require(SETTINGS . DIRECTORY_SEPARATOR . 'telegram.php')); // Initializing dependencies require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; -// Initializing the robots manager settings +// Initializing the robot +$robot = new telegram(TELEGRAM['constructor']['key']); + +$robot->setWebhook( + url: 'https://' . PROJECT_DOMAIN . '/telegram/constructor/webhook.php', + certificate: new input(resource: PROJECT_CERTIFICATE), + ip_address: SERVER_IP_ADDRESS, + max_connections: 10, + drop_pending_updates: false, + secret_token: 'bebra228' +); + +/* // Initializing the robots manager settings $settings = [ 'bots' => [ 'constructor' => [ @@ -78,6 +93,8 @@ $updates = $telegram->bot('constructor')->setWebhook([ 'url' => 'https://' . PROJECT_DOMAIN . '/telegram/constructor/webhook.php', 'certificate' => PROJECT_CERTIFICATE ]); + */ + /* // Initializing the updates listener $robot->onUpdate(function (context $context): void {}); diff --git a/kodorvan/constructor/system/public/telegram/constructor/webhook.php b/kodorvan/constructor/system/public/telegram/constructor/webhook.php index 282089a..2caf4f5 100644 --- a/kodorvan/constructor/system/public/telegram/constructor/webhook.php +++ b/kodorvan/constructor/system/public/telegram/constructor/webhook.php @@ -6,9 +6,15 @@ namespace kodorvan\constructor; // Files of the project use kodorvan\constructor\models\account, - kodorvan\constructor\models\telegram\middlewares, - kodorvan\constructor\models\telegram\commands\start, - kodorvan\constructor\models\telegram\settings; + kodorvan\constructor\models\telegram\settings, + kodorvan\constructor\models\telegram\commands\start as command_start, + kodorvan\constructor\models\telegram\commands\society as command_society, + kodorvan\constructor\models\telegram\commands\language as command_language, + kodorvan\constructor\models\telegram\middlewares\account as middleware_account, + kodorvan\constructor\models\telegram\middlewares\language as middleware_language, + kodorvan\constructor\models\telegram\middlewares\localization as middleware_localization, + kodorvan\constructor\models\telegram\middlewares\settings as middleware_settings, + kodorvan\constructor\models\telegram\middlewares\authorizations as middleware_authorizations; // Library for languages support use mirzaev\languages\language; @@ -18,7 +24,9 @@ use mirzaev\minimal\core, mirzaev\minimal\route; // Framework for Telegram -use Telegram\Bot\BotsManager as telegram; +/* use Telegram\Bot\BotsManager as telegram; */ +use SergiX44\Nutgram\Nutgram as telegram, + SergiX44\Nutgram\RunningMode\Webhook as webhook; // Enabling debugging /* ini_set('error_reporting', E_ALL); @@ -55,55 +63,38 @@ define('TELEGRAM', require(SETTINGS . DIRECTORY_SEPARATOR . 'telegram.php')); // Initializing dependencies require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; -// Initializing the robots manager settings -$settings = [ - 'bots' => [ - 'constructor' => [ - 'token' => TELEGRAM['constructor']['key'], - 'certificate_path' => PROJECT_CERTIFICATE, - 'webhook_url' => 'https://' . PROJECT_DOMAIN . ':443/telegram/constructor.php', - 'commands' => [ - start::class, - ] - ], - 'async_requests' => true, - 'base_bot_url' => 'https://' . PROJECT_DOMAIN . '/telegram', - ] -]; +// Initializing the robot +$robot = new telegram(TELEGRAM['constructor']['key']); -// Initializing the robots manager -$telegram = new telegram($settings); +$webhook = new webhook(secretToken: 'bebra228'); +$webhook->setSafeMode(true); -var_dump($updates = $telegram->bot('constructor')->getWebhookUpdate()); +$robot->setRunningMode($webhook); -/* // Initializing the updates listener -$robot->onUpdate(function (context $context): void {}); +$robot->middleware(middleware_account::class); +$robot->middleware(middleware_language::class); +$robot->middleware(middleware_localization::class); +$robot->middleware(middleware_authorizations::class); -// Initializing the robot middlewares -$robot->middleware([middlewares::class, 'account']); -$robot->middleware([middlewares::class, 'language']); -$robot->middleware([middlewares::class, 'localization']); -$robot->middleware([middlewares::class, 'authorizations']); // Initializing the robot commands handlers -$robot->onCommand('start', [commands::class, 'start']); +$robot->registerCommand(command_start::class); -$robot->onCommand('start telegram voronka', [commands::class, 'start']); -$robot->onCommand('start parser', [commands::class, 'start']); -$robot->onCommand('start calculator', [commands::class, 'start']); +$robot->onCommand('start telegram voronka', command_start::class); +$robot->onCommand('start parser', command_start::class); +$robot->onCommand('start calculator', command_start::class); -$robot->onCommand('language', [commands::class, 'language'])->middleware([middlewares::class, 'settings']); -$robot->onCommand('society', [commands::class, 'society']); +$robot->registerCommand(command_language::class)->middleware(middleware_settings::class); +$robot->registerCommand(command_society::class); // Initializing the robot settings language buttons handlers foreach (language::cases() as $language) { // Iterating over languages // Initializing language buttons - $robot->onCbQueryData(["settings_language_$language->name"], fn(context $context) => settings::language($context, $language)); + $robot->onCallbackQueryData("settings_language_$language->name", fn(telegram $robot) => settings::language(robot: $robot, language: $language)); }; -$robot->onCbQueryData('project_create', ['process_project_create', 'name']); +/* $robot->onCbQueryData('project_create', ['process_project_create', 'name']); */ -// Starting chat-robot -$robot->run(); */ +$robot->run(); diff --git a/kodorvan/constructor/system/settings/system.php.sample b/kodorvan/constructor/system/settings/system.php.sample index 0a94fea..bc6ecdf 100644 --- a/kodorvan/constructor/system/settings/system.php.sample +++ b/kodorvan/constructor/system/settings/system.php.sample @@ -6,8 +6,16 @@ use mirzaev\languages\language; // Initializing dependencies require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; -define('PROJECT_NAME', ''); -define('PROJECT_DOMAIN', ''); +define('SERVER_IP_ADDRESS', '5.140.110.25'); + +define('PROJECT_CREATOR', 'kodorvan'); +define('PROJECT_NAME', 'constructor'); +define('PROJECT_DOMAIN', 'constructor.kodorvan.tech'); +define('PROJECT_CERTIFICATE', SETTINGS . DIRECTORY_SEPARATOR . 'certificate' . DIRECTORY_SEPARATOR . 'public.pem'); +define('REPOSITORY', 'https://git.svoboda.works'); +define('PROJECT_REPOSITORY', REPOSITORY . '/' . PROJECT_CREATOR . '/' . PROJECT_NAME); +define('PROJECT_REPOSITORY_LANGUAGE_ADD', PROJECT_REPOSITORY . '/src/branch/stable/' . PROJECT_CREATOR . '/' . PROJECT_NAME . '/system/localizations'); +/* define('PROJECT_CERTIFICATE', SETTINGS . DIRECTORY_SEPARATOR . 'cert.pem'); */ define('LANGUAGE_DEFAULT', language::en); diff --git a/kodorvan/constructor/system/storage/images/mushroom.jpg b/kodorvan/constructor/system/storage/images/mushroom.jpg index 5d8741d..402059e 100644 Binary files a/kodorvan/constructor/system/storage/images/mushroom.jpg and b/kodorvan/constructor/system/storage/images/mushroom.jpg differ diff --git a/logs/.gitignore b/logs/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore