Compare commits
No commits in common. "7c9ee60103dee70b37104af3d1fa8ed6901ba411" and "cd908d33eeb023b1816b904ca0a895d6524d5626" have entirely different histories.
7c9ee60103
...
cd908d33ee
|
@ -11,7 +11,6 @@
|
||||||
"doctrine/doctrine-bundle": "^2.8",
|
"doctrine/doctrine-bundle": "^2.8",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.2",
|
"doctrine/doctrine-migrations-bundle": "^3.2",
|
||||||
"doctrine/orm": "^2.14",
|
"doctrine/orm": "^2.14",
|
||||||
"jms/serializer-bundle": "^5.2",
|
|
||||||
"phpdocumentor/reflection-docblock": "^5.3",
|
"phpdocumentor/reflection-docblock": "^5.3",
|
||||||
"phpstan/phpdoc-parser": "^1.16",
|
"phpstan/phpdoc-parser": "^1.16",
|
||||||
"sensio/framework-extra-bundle": "^6.1",
|
"sensio/framework-extra-bundle": "^6.1",
|
||||||
|
@ -42,8 +41,7 @@
|
||||||
"symfony/web-link": "6.2.*",
|
"symfony/web-link": "6.2.*",
|
||||||
"symfony/yaml": "6.2.*",
|
"symfony/yaml": "6.2.*",
|
||||||
"twig/extra-bundle": "^2.12|^3.0",
|
"twig/extra-bundle": "^2.12|^3.0",
|
||||||
"twig/twig": "^2.12|^3.0",
|
"twig/twig": "^2.12|^3.0"
|
||||||
"unreal4u/telegram-api": "*"
|
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
|
707
composer.lock
generated
707
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3e4ae473183073d1dd231517f5734c3e",
|
"content-hash": "75085b03a22620e56812fd6d68ace9bb",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "doctrine/annotations",
|
"name": "doctrine/annotations",
|
||||||
|
@ -1457,562 +1457,6 @@
|
||||||
],
|
],
|
||||||
"time": "2023-01-14T14:17:03+00:00"
|
"time": "2023-01-14T14:17:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "guzzlehttp/guzzle",
|
|
||||||
"version": "6.5.8",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/guzzle.git",
|
|
||||||
"reference": "a52f0440530b54fa079ce76e8c5d196a42cad981"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981",
|
|
||||||
"reference": "a52f0440530b54fa079ce76e8c5d196a42cad981",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-json": "*",
|
|
||||||
"guzzlehttp/promises": "^1.0",
|
|
||||||
"guzzlehttp/psr7": "^1.9",
|
|
||||||
"php": ">=5.5",
|
|
||||||
"symfony/polyfill-intl-idn": "^1.17"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
|
||||||
"psr/log": "^1.1"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"psr/log": "Required for using the Log middleware"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "6.5-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Graham Campbell",
|
|
||||||
"email": "hello@gjcampbell.co.uk",
|
|
||||||
"homepage": "https://github.com/GrahamCampbell"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jeremy Lindblom",
|
|
||||||
"email": "jeremeamia@gmail.com",
|
|
||||||
"homepage": "https://github.com/jeremeamia"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "George Mponos",
|
|
||||||
"email": "gmponos@gmail.com",
|
|
||||||
"homepage": "https://github.com/gmponos"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Nyholm",
|
|
||||||
"email": "tobias.nyholm@gmail.com",
|
|
||||||
"homepage": "https://github.com/Nyholm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com",
|
|
||||||
"homepage": "https://github.com/sagikazarmark"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Schultze",
|
|
||||||
"email": "webmaster@tubo-world.de",
|
|
||||||
"homepage": "https://github.com/Tobion"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle is a PHP HTTP client library",
|
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"keywords": [
|
|
||||||
"client",
|
|
||||||
"curl",
|
|
||||||
"framework",
|
|
||||||
"http",
|
|
||||||
"http client",
|
|
||||||
"rest",
|
|
||||||
"web service"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
|
||||||
"source": "https://github.com/guzzle/guzzle/tree/6.5.8"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://github.com/GrahamCampbell",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/Nyholm",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2022-06-20T22:16:07+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "guzzlehttp/promises",
|
|
||||||
"version": "1.5.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/promises.git",
|
|
||||||
"reference": "b94b2807d85443f9719887892882d0329d1e2598"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
|
|
||||||
"reference": "b94b2807d85443f9719887892882d0329d1e2598",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.5"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/phpunit-bridge": "^4.4 || ^5.1"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.5-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\Promise\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Graham Campbell",
|
|
||||||
"email": "hello@gjcampbell.co.uk",
|
|
||||||
"homepage": "https://github.com/GrahamCampbell"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Nyholm",
|
|
||||||
"email": "tobias.nyholm@gmail.com",
|
|
||||||
"homepage": "https://github.com/Nyholm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Schultze",
|
|
||||||
"email": "webmaster@tubo-world.de",
|
|
||||||
"homepage": "https://github.com/Tobion"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle promises library",
|
|
||||||
"keywords": [
|
|
||||||
"promise"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/promises/issues",
|
|
||||||
"source": "https://github.com/guzzle/promises/tree/1.5.2"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://github.com/GrahamCampbell",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/Nyholm",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2022-08-28T14:55:35+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "guzzlehttp/psr7",
|
|
||||||
"version": "1.9.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/psr7.git",
|
|
||||||
"reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
|
|
||||||
"reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.4.0",
|
|
||||||
"psr/http-message": "~1.0",
|
|
||||||
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
|
|
||||||
},
|
|
||||||
"provide": {
|
|
||||||
"psr/http-message-implementation": "1.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-zlib": "*",
|
|
||||||
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.9-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\Psr7\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Graham Campbell",
|
|
||||||
"email": "hello@gjcampbell.co.uk",
|
|
||||||
"homepage": "https://github.com/GrahamCampbell"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "George Mponos",
|
|
||||||
"email": "gmponos@gmail.com",
|
|
||||||
"homepage": "https://github.com/gmponos"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Nyholm",
|
|
||||||
"email": "tobias.nyholm@gmail.com",
|
|
||||||
"homepage": "https://github.com/Nyholm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com",
|
|
||||||
"homepage": "https://github.com/sagikazarmark"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Schultze",
|
|
||||||
"email": "webmaster@tubo-world.de",
|
|
||||||
"homepage": "https://github.com/Tobion"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PSR-7 message implementation that also provides common utility methods",
|
|
||||||
"keywords": [
|
|
||||||
"http",
|
|
||||||
"message",
|
|
||||||
"psr-7",
|
|
||||||
"request",
|
|
||||||
"response",
|
|
||||||
"stream",
|
|
||||||
"uri",
|
|
||||||
"url"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/psr7/issues",
|
|
||||||
"source": "https://github.com/guzzle/psr7/tree/1.9.0"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://github.com/GrahamCampbell",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/Nyholm",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2022-06-20T21:43:03+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "jms/metadata",
|
|
||||||
"version": "2.8.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/schmittjoh/metadata.git",
|
|
||||||
"reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/schmittjoh/metadata/zipball/7ca240dcac0c655eb15933ee55736ccd2ea0d7a6",
|
|
||||||
"reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.2|^8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/cache": "^1.0",
|
|
||||||
"doctrine/coding-standard": "^8.0",
|
|
||||||
"mikey179/vfsstream": "^1.6.7",
|
|
||||||
"phpunit/phpunit": "^8.5|^9.0",
|
|
||||||
"psr/container": "^1.0|^2.0",
|
|
||||||
"symfony/cache": "^3.1|^4.0|^5.0",
|
|
||||||
"symfony/dependency-injection": "^3.1|^4.0|^5.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Metadata\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Johannes M. Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Asmir Mustafic",
|
|
||||||
"email": "goetas@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Class/method/property metadata management in PHP",
|
|
||||||
"keywords": [
|
|
||||||
"annotations",
|
|
||||||
"metadata",
|
|
||||||
"xml",
|
|
||||||
"yaml"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/schmittjoh/metadata/issues",
|
|
||||||
"source": "https://github.com/schmittjoh/metadata/tree/2.8.0"
|
|
||||||
},
|
|
||||||
"time": "2023-02-15T13:44:18+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "jms/serializer",
|
|
||||||
"version": "3.23.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/schmittjoh/serializer.git",
|
|
||||||
"reference": "ac0b16ee5317d1aacc41deb91c6c325eae97c176"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ac0b16ee5317d1aacc41deb91c6c325eae97c176",
|
|
||||||
"reference": "ac0b16ee5317d1aacc41deb91c6c325eae97c176",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"doctrine/annotations": "^1.13 || ^2.0",
|
|
||||||
"doctrine/instantiator": "^1.0.3",
|
|
||||||
"doctrine/lexer": "^1.1 || ^2",
|
|
||||||
"jms/metadata": "^2.6",
|
|
||||||
"php": "^7.2||^8.0",
|
|
||||||
"phpstan/phpdoc-parser": "^0.4 || ^0.5 || ^1.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/coding-standard": "^8.1",
|
|
||||||
"doctrine/orm": "~2.1",
|
|
||||||
"doctrine/persistence": "^1.3.3|^2.0|^3.0",
|
|
||||||
"doctrine/phpcr-odm": "^1.3|^2.0",
|
|
||||||
"ext-pdo_sqlite": "*",
|
|
||||||
"jackalope/jackalope-doctrine-dbal": "^1.1.5",
|
|
||||||
"ocramius/proxy-manager": "^1.0|^2.0",
|
|
||||||
"phpbench/phpbench": "^1.0",
|
|
||||||
"phpstan/phpstan": "^1.0.2",
|
|
||||||
"phpunit/phpunit": "^8.5.21||^9.0",
|
|
||||||
"psr/container": "^1.0|^2.0",
|
|
||||||
"symfony/dependency-injection": "^3.0|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/expression-language": "^3.2|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/filesystem": "^3.0|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/form": "^3.0|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/translation": "^3.0|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/uid": "^5.1|^6.0",
|
|
||||||
"symfony/validator": "^3.1.9|^4.0|^5.0|^6.0",
|
|
||||||
"symfony/yaml": "^3.3|^4.0|^5.0|^6.0",
|
|
||||||
"twig/twig": "~1.34|~2.4|^3.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.",
|
|
||||||
"symfony/cache": "Required if you like to use cache functionality.",
|
|
||||||
"symfony/uid": "Required if you'd like to serialize UID objects.",
|
|
||||||
"symfony/yaml": "Required if you'd like to use the YAML metadata format."
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"JMS\\Serializer\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Johannes M. Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Asmir Mustafic",
|
|
||||||
"email": "goetas@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Library for (de-)serializing data of any complexity; supports XML, and JSON.",
|
|
||||||
"homepage": "http://jmsyst.com/libs/serializer",
|
|
||||||
"keywords": [
|
|
||||||
"deserialization",
|
|
||||||
"jaxb",
|
|
||||||
"json",
|
|
||||||
"serialization",
|
|
||||||
"xml"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/schmittjoh/serializer/issues",
|
|
||||||
"source": "https://github.com/schmittjoh/serializer/tree/3.23.0"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://github.com/goetas",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2023-02-17T17:40:48+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "jms/serializer-bundle",
|
|
||||||
"version": "5.2.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/schmittjoh/JMSSerializerBundle.git",
|
|
||||||
"reference": "c772704a0b3cb772fa391ff5ac7d36fd6cecebf4"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/c772704a0b3cb772fa391ff5ac7d36fd6cecebf4",
|
|
||||||
"reference": "c772704a0b3cb772fa391ff5ac7d36fd6cecebf4",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"jms/metadata": "^2.5",
|
|
||||||
"jms/serializer": "^3.20",
|
|
||||||
"php": "^7.2 || ^8.0",
|
|
||||||
"symfony/dependency-injection": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/framework-bundle": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/coding-standard": "^8.1",
|
|
||||||
"doctrine/orm": "^2.4",
|
|
||||||
"phpunit/phpunit": "^8.0 || ^9.0",
|
|
||||||
"symfony/expression-language": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/finder": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/form": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/stopwatch": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/templating": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/twig-bundle": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/uid": "^5.1 || ^6.0",
|
|
||||||
"symfony/validator": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/expression-language": "Required for opcache preloading ^3.4 || ^4.0 || ^5.0 || ^6.0",
|
|
||||||
"symfony/finder": "Required for cache warmup, supported versions ^3.4 || ^4.0 || ^5.0 || ^6.0"
|
|
||||||
},
|
|
||||||
"type": "symfony-bundle",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "5.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"JMS\\SerializerBundle\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Johannes M. Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Asmir Mustafic",
|
|
||||||
"email": "goetas@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Allows you to easily serialize, and deserialize data of any complexity",
|
|
||||||
"homepage": "http://jmsyst.com/bundles/JMSSerializerBundle",
|
|
||||||
"keywords": [
|
|
||||||
"deserialization",
|
|
||||||
"json",
|
|
||||||
"serialization",
|
|
||||||
"xml"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/schmittjoh/JMSSerializerBundle/issues",
|
|
||||||
"source": "https://github.com/schmittjoh/JMSSerializerBundle/tree/5.2.1"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://github.com/goetas",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2023-02-05T11:03:45+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
|
@ -2476,59 +1920,6 @@
|
||||||
},
|
},
|
||||||
"time": "2019-01-08T18:20:26+00:00"
|
"time": "2019-01-08T18:20:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "psr/http-message",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-fig/http-message.git",
|
|
||||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
|
||||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.0.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Psr\\Http\\Message\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "PHP-FIG",
|
|
||||||
"homepage": "http://www.php-fig.org/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Common interface for HTTP messages",
|
|
||||||
"homepage": "https://github.com/php-fig/http-message",
|
|
||||||
"keywords": [
|
|
||||||
"http",
|
|
||||||
"http-message",
|
|
||||||
"psr",
|
|
||||||
"psr-7",
|
|
||||||
"request",
|
|
||||||
"response"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/php-fig/http-message/tree/master"
|
|
||||||
},
|
|
||||||
"time": "2016-08-06T14:39:51+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "psr/link",
|
"name": "psr/link",
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
@ -2635,50 +2026,6 @@
|
||||||
},
|
},
|
||||||
"time": "2021-07-14T16:46:02+00:00"
|
"time": "2021-07-14T16:46:02+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "ralouphie/getallheaders",
|
|
||||||
"version": "3.0.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
|
||||||
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
|
||||||
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.6"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"php-coveralls/php-coveralls": "^2.1",
|
|
||||||
"phpunit/phpunit": "^5 || ^6.5"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/getallheaders.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Ralph Khattar",
|
|
||||||
"email": "ralph.khattar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A polyfill for getallheaders.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/ralouphie/getallheaders/issues",
|
|
||||||
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
|
|
||||||
},
|
|
||||||
"time": "2019-03-08T08:55:37+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "sensio/framework-extra-bundle",
|
"name": "sensio/framework-extra-bundle",
|
||||||
"version": "v6.2.10",
|
"version": "v6.2.10",
|
||||||
|
@ -7869,58 +7216,6 @@
|
||||||
],
|
],
|
||||||
"time": "2023-02-08T07:49:20+00:00"
|
"time": "2023-02-08T07:49:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "unreal4u/telegram-api",
|
|
||||||
"version": "v1.1.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/unreal4u/telegram-api.git",
|
|
||||||
"reference": "501a02062942fb533bbcdf6f9f538368208db65a"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/unreal4u/telegram-api/zipball/501a02062942fb533bbcdf6f9f538368208db65a",
|
|
||||||
"reference": "501a02062942fb533bbcdf6f9f538368208db65a",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"guzzlehttp/guzzle": "~6.0",
|
|
||||||
"php": ">=7.0.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpmd/phpmd": "@stable",
|
|
||||||
"phpunit/phpunit": "@stable",
|
|
||||||
"squizlabs/php_codesniffer": "@stable"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"unreal4u\\": "src"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Camilo Sperberg",
|
|
||||||
"email": "me@unreal4u.com",
|
|
||||||
"homepage": "https://github.com/unreal4u/telegram-api/graphs/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Complete implementation used to communicate with the open-source Telegram API",
|
|
||||||
"keywords": [
|
|
||||||
"api",
|
|
||||||
"telegram",
|
|
||||||
"telegram bot"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/unreal4u/telegram-api/issues",
|
|
||||||
"source": "https://github.com/unreal4u/telegram-api/tree/master"
|
|
||||||
},
|
|
||||||
"time": "2016-01-26T21:46:33+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "webmozart/assert",
|
"name": "webmozart/assert",
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
|
|
|
@ -12,5 +12,4 @@ return [
|
||||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
|
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
|
||||||
JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
jms_serializer:
|
|
||||||
visitors:
|
|
||||||
xml_serialization:
|
|
||||||
format_output: '%kernel.debug%'
|
|
||||||
# metadata:
|
|
||||||
# auto_detection: false
|
|
||||||
# directories:
|
|
||||||
# any-name:
|
|
||||||
# namespace_prefix: "My\\FooBundle"
|
|
||||||
# path: "@MyFooBundle/Resources/config/serializer"
|
|
||||||
# another-name:
|
|
||||||
# namespace_prefix: "My\\BarBundle"
|
|
||||||
# path: "@MyBarBundle/Resources/config/serializer"
|
|
||||||
|
|
||||||
when@prod:
|
|
||||||
jms_serializer:
|
|
||||||
visitors:
|
|
||||||
json_serialization:
|
|
||||||
options:
|
|
||||||
- JSON_UNESCAPED_SLASHES
|
|
||||||
- JSON_PRESERVE_ZERO_FRACTION
|
|
||||||
|
|
||||||
when@dev:
|
|
||||||
jms_serializer:
|
|
||||||
visitors:
|
|
||||||
json_serialization:
|
|
||||||
options:
|
|
||||||
- JSON_PRETTY_PRINT
|
|
||||||
- JSON_UNESCAPED_SLASHES
|
|
||||||
- JSON_PRESERVE_ZERO_FRACTION
|
|
|
@ -10,14 +10,6 @@ services:
|
||||||
_defaults:
|
_defaults:
|
||||||
autowire: true # Automatically injects dependencies in your services.
|
autowire: true # Automatically injects dependencies in your services.
|
||||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||||
bind:
|
|
||||||
# TODO: fix retrieval
|
|
||||||
# Telegram Bot API
|
|
||||||
$telegramToken: ''
|
|
||||||
# Point API
|
|
||||||
$pointApiDelay: ''
|
|
||||||
$pointAppUserId: ''
|
|
||||||
$pointApiClient: '@app.point.http_client'
|
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
# makes classes in src/ available to be used as services
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
# this creates a service per class whose id is the fully-qualified class name
|
||||||
|
@ -28,10 +20,5 @@ services:
|
||||||
- '../src/Entity/'
|
- '../src/Entity/'
|
||||||
- '../src/Kernel.php'
|
- '../src/Kernel.php'
|
||||||
|
|
||||||
# HTTP client for Point API
|
# add more service definitions when explicit configuration is needed
|
||||||
Symfony\Component\HttpClient\HttpClient:
|
# please note that last definitions always *replace* previous ones
|
||||||
alias: 'app.point.http_client'
|
|
||||||
factory: [null, 'create']
|
|
||||||
arguments:
|
|
||||||
base_uri: '%point_base_url%'
|
|
||||||
timeout: 5.0
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Command;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Service\Telegram\MessageSender;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\{InputArgument, InputInterface, InputOption};
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use function Skobkin\Bundle\PointToolsBundle\Command\mb_strlen;
|
||||||
|
use function Skobkin\Bundle\PointToolsBundle\Command\mb_substr;
|
||||||
|
|
||||||
|
class TelegramSendMessageCommand extends Command
|
||||||
|
{
|
||||||
|
/** @var MessageSender */
|
||||||
|
private $messenger;
|
||||||
|
|
||||||
|
public function __construct(MessageSender $messenger)
|
||||||
|
{
|
||||||
|
$this->messenger = $messenger;
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('telegram:send-message')
|
||||||
|
->setDescription('Send message via Telegram')
|
||||||
|
->addOption('chat-id', 'c', InputOption::VALUE_OPTIONAL, 'ID of the chat')
|
||||||
|
->addOption('stdin', 'i', InputOption::VALUE_NONE, 'Read message from stdin instead of option')
|
||||||
|
->addArgument('message', InputArgument::OPTIONAL, 'Text of the message')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$output->writeln('Sending message...');
|
||||||
|
|
||||||
|
if ($input->getOption('stdin')) {
|
||||||
|
$message = file_get_contents('php://stdin');
|
||||||
|
} elseif (null !== $input->getArgument('message')) {
|
||||||
|
$message = $input->getArgument('message');
|
||||||
|
} else {
|
||||||
|
$output->writeln('<error>Either \'--stdin\' option or \'message\' argument should be specified.</error>');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mb_strlen($message) > 4096) {
|
||||||
|
$output->writeln('<comment>Message is too long (>4096). Cutting the tail...</comment>');
|
||||||
|
$message = mb_substr($message, 0, 4090).PHP_EOL.'...';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->messenger->sendMessageToChat(
|
||||||
|
(int) $input->getOption('chat-id'),
|
||||||
|
$message
|
||||||
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$output->writeln('Error: '.$e->getMessage());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
91
old/src/PointToolsBundle/Command/TelegramWebHookCommand.php
Normal file
91
old/src/PointToolsBundle/Command/TelegramWebHookCommand.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Command;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\{InputArgument, InputInterface};
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use unreal4u\TelegramAPI\Telegram\Methods\{DeleteWebhook, SetWebhook};
|
||||||
|
use unreal4u\TelegramAPI\TgLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets or deletes Telegram bot Web-Hook
|
||||||
|
* @see https://core.telegram.org/bots/api#setwebhook
|
||||||
|
*/
|
||||||
|
class TelegramWebHookCommand extends Command
|
||||||
|
{
|
||||||
|
private const MODE_SET = 'set';
|
||||||
|
private const MODE_DELETE = 'delete';
|
||||||
|
|
||||||
|
/** @var TgLog */
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
/** @var UrlGeneratorInterface */
|
||||||
|
private $router;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $token;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $maxConnections;
|
||||||
|
|
||||||
|
public function __construct(TgLog $client, UrlGeneratorInterface $router, string $telegramToken, int $telegramWebhookMaxConnections)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->client = $client;
|
||||||
|
$this->router = $router;
|
||||||
|
$this->token = $telegramToken;
|
||||||
|
$this->maxConnections = $telegramWebhookMaxConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('telegram:webhook')
|
||||||
|
->setDescription('Set webhook')
|
||||||
|
->addArgument('mode', InputArgument::REQUIRED, 'Command mode (set or delete)')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
if (self::MODE_SET === strtolower($input->getArgument('mode'))) {
|
||||||
|
|
||||||
|
$url = $this->router->generate(
|
||||||
|
'telegram_webhook',
|
||||||
|
['token' => $this->token],
|
||||||
|
UrlGeneratorInterface::ABSOLUTE_URL
|
||||||
|
);
|
||||||
|
|
||||||
|
$output->writeln('Setting webhook: '.$url);
|
||||||
|
|
||||||
|
$setWebHook = new SetWebhook();
|
||||||
|
$setWebHook->url = $url;
|
||||||
|
$setWebHook->max_connections = $this->maxConnections;
|
||||||
|
|
||||||
|
$this->client->performApiRequest($setWebHook);
|
||||||
|
|
||||||
|
$output->writeln('Done');
|
||||||
|
} elseif (self::MODE_DELETE === strtolower($input->getArgument('mode'))) {
|
||||||
|
$output->writeln('Deleting webhook');
|
||||||
|
|
||||||
|
$deleteWebHook = new DeleteWebhook();
|
||||||
|
|
||||||
|
$this->client->performApiRequest($deleteWebHook);
|
||||||
|
|
||||||
|
$output->writeln('Done');
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Mode must be exactly one of: %s', implode(', ', [self::MODE_SET, self::MODE_DELETE])));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,40 +1,77 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Command;
|
namespace src\PointToolsBundle\Command;
|
||||||
|
|
||||||
use App\Repository\UserRepository;
|
|
||||||
use App\Entity\{Subscription, User};
|
|
||||||
use App\Exception\Api\UserNotFoundException;
|
|
||||||
use App\Service\Api\UserApi;
|
|
||||||
use App\Service\SubscriptionsManager;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use src\PointToolsBundle\Entity\User;
|
||||||
|
use src\PointToolsBundle\Service\SubscriptionsManager;
|
||||||
|
use src\PointToolsBundle\Entity\{Subscription};
|
||||||
|
use src\PointToolsBundle\Exception\Api\UserNotFoundException;
|
||||||
|
use src\PointToolsBundle\Repository\UserRepository;
|
||||||
|
use src\PointToolsBundle\Service\{Api\UserApi};
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\{InputInterface, InputOption};
|
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
|
use Symfony\Component\Console\Input\{InputInterface, InputOption};
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
|
|
||||||
#[AsCommand(name: 'app:subscriptions:update', description: 'Update subscriptions of users subscribed to service')]
|
/**
|
||||||
|
* @todo https://symfony.com/doc/current/console/lockable_trait.html
|
||||||
|
*/
|
||||||
class UpdateSubscriptionsCommand extends Command
|
class UpdateSubscriptionsCommand extends Command
|
||||||
{
|
{
|
||||||
|
/** @var EntityManagerInterface */
|
||||||
|
private $em;
|
||||||
|
|
||||||
|
/** @var LoggerInterface */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var UserRepository */
|
||||||
|
private $userRepo;
|
||||||
|
|
||||||
|
/** @var InputInterface */
|
||||||
|
private $input;
|
||||||
|
|
||||||
|
/** @var UserApi */
|
||||||
|
private $api;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $apiDelay = 500000;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $appUserId;
|
||||||
|
|
||||||
|
/** @var SubscriptionsManager */
|
||||||
|
private $subscriptionManager;
|
||||||
|
|
||||||
|
/** @var ProgressBar */
|
||||||
|
private $progress;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
private readonly LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
private readonly UserRepository $userRepo,
|
UserRepository $userRepo,
|
||||||
private readonly UserApi $api,
|
UserApi $api,
|
||||||
private readonly SubscriptionsManager $subscriptionManager,
|
SubscriptionsManager $subscriptionManager,
|
||||||
private readonly int $pointApiDelay,
|
int $apiDelay,
|
||||||
private readonly int $pointAppUserId,
|
int $appUserId
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->em = $em;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->userRepo = $userRepo;
|
||||||
|
$this->api = $api;
|
||||||
|
$this->subscriptionManager = $subscriptionManager;
|
||||||
|
$this->apiDelay = $apiDelay;
|
||||||
|
$this->appUserId = $appUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
|
->setName('point:update:subscriptions')
|
||||||
|
->setDescription('Update subscriptions of users subscribed to service')
|
||||||
->addOption(
|
->addOption(
|
||||||
'all-users',
|
'all-users',
|
||||||
null,
|
null,
|
||||||
|
@ -50,46 +87,46 @@ class UpdateSubscriptionsCommand extends Command
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$io = new SymfonyStyle($input, $output);
|
$this->input = $input;
|
||||||
|
|
||||||
$this->logger->debug('UpdateSubscriptionsCommand started.');
|
$this->logger->debug('UpdateSubscriptionsCommand started.');
|
||||||
|
|
||||||
$progress = $io->createProgressBar();
|
$this->progress = new ProgressBar($output);
|
||||||
$progress->setFormat(ProgressBar::FORMAT_DEBUG);
|
$this->progress->setFormat('debug');
|
||||||
|
|
||||||
if (!$input->getOption('check-only')) { // Beginning transaction for all changes
|
if (!$input->getOption('check-only')) { // Beginning transaction for all changes
|
||||||
$this->em->beginTransaction();
|
$this->em->beginTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$usersForUpdate = $this->getUsersForUpdate($input);
|
$usersForUpdate = $this->getUsersForUpdate();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]);
|
$this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]);
|
||||||
|
|
||||||
return Command::FAILURE;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 === count($usersForUpdate)) {
|
if (0 === count($usersForUpdate)) {
|
||||||
$this->logger->info('No local subscribers. Finishing.');
|
$this->logger->info('No local subscribers. Finishing.');
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->info('Processing users subscribers');
|
$this->logger->info('Processing users subscribers');
|
||||||
$progress->start(count($usersForUpdate));
|
$this->progress->start(count($usersForUpdate));
|
||||||
|
|
||||||
foreach ($usersForUpdate as $user) {
|
foreach ($usersForUpdate as $user) {
|
||||||
usleep($this->pointApiDelay);
|
usleep($this->apiDelay);
|
||||||
|
|
||||||
$progress->advance();
|
$this->progress->advance();
|
||||||
$this->logger->info('Processing @'.$user->getLogin());
|
$this->logger->info('Processing @'.$user->getLogin());
|
||||||
|
|
||||||
$this->updateUser($user);
|
$this->updateUser($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
$progress->finish();
|
$this->progress->finish();
|
||||||
|
|
||||||
// Flushing all changes at once to the database
|
// Flushing all changes at once to the database
|
||||||
if (!$input->getOption('check-only')) {
|
if (!$input->getOption('check-only')) {
|
||||||
|
@ -99,7 +136,7 @@ class UpdateSubscriptionsCommand extends Command
|
||||||
|
|
||||||
$this->logger->debug('Finished');
|
$this->logger->debug('Finished');
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateUser(User $user): void
|
private function updateUser(User $user): void
|
||||||
|
@ -146,18 +183,18 @@ class UpdateSubscriptionsCommand extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getUsersForUpdate(InputInterface $input): array
|
private function getUsersForUpdate(): array
|
||||||
{
|
{
|
||||||
$usersForUpdate = [];
|
$usersForUpdate = [];
|
||||||
|
|
||||||
if ($input->getOption('all-users')) {
|
if ($this->input->getOption('all-users')) {
|
||||||
$usersForUpdate = $this->userRepo->findBy(['removed' => false]);
|
$usersForUpdate = $this->userRepo->findBy(['removed' => false]);
|
||||||
} else {
|
} else {
|
||||||
/** @var User $serviceUser */
|
/** @var User $serviceUser */
|
||||||
try {
|
try {
|
||||||
$serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->pointAppUserId);
|
$serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->appUserId);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $this->pointAppUserId]);
|
$this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $this->appUserId]);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +203,7 @@ class UpdateSubscriptionsCommand extends Command
|
||||||
$this->logger->warning('Service user not found or marked as removed. Falling back to API.');
|
$this->logger->warning('Service user not found or marked as removed. Falling back to API.');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$serviceUser = $this->api->getUserById($this->pointAppUserId);
|
$serviceUser = $this->api->getUserById($this->appUserId);
|
||||||
} catch (UserNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
throw new \RuntimeException('Service user not found in the database and could not be retrieved from API.');
|
throw new \RuntimeException('Service user not found in the database and could not be retrieved from API.');
|
||||||
}
|
}
|
||||||
|
@ -175,7 +212,7 @@ class UpdateSubscriptionsCommand extends Command
|
||||||
$this->logger->info('Getting service subscribers');
|
$this->logger->info('Getting service subscribers');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$usersForUpdate = $this->api->getUserSubscribersById($this->pointAppUserId);
|
$usersForUpdate = $this->api->getUserSubscribersById($this->appUserId);
|
||||||
} catch (UserNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
$this->logger->critical('Service user deleted or API response is invalid');
|
$this->logger->critical('Service user deleted or API response is invalid');
|
||||||
|
|
|
@ -1,40 +1,66 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Command;
|
namespace src\PointToolsBundle\Command;
|
||||||
|
|
||||||
use App\Entity\User;
|
|
||||||
use App\Exception\Api\ForbiddenException;
|
|
||||||
use App\Exception\Api\UserNotFoundException;
|
|
||||||
use App\Repository\UserRepository;
|
|
||||||
use App\Service\Api\UserApi;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use src\PointToolsBundle\Entity\User;
|
||||||
|
use src\PointToolsBundle\Exception\Api\ForbiddenException;
|
||||||
|
use src\PointToolsBundle\Entity\{Subscription};
|
||||||
|
use src\PointToolsBundle\Exception\Api\{UserNotFoundException};
|
||||||
|
use src\PointToolsBundle\Repository\UserRepository;
|
||||||
|
use src\PointToolsBundle\Service\Api\UserApi;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\{InputInterface, InputOption};
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
|
|
||||||
#[AsCommand(name: 'app:privacy:update', description: 'Check removed users status and restore if user was deleted by error.')]
|
|
||||||
class UpdateUsersPrivacyCommand extends Command
|
class UpdateUsersPrivacyCommand extends Command
|
||||||
{
|
{
|
||||||
public function __construct(
|
/** @var EntityManagerInterface */
|
||||||
private readonly EntityManagerInterface $em,
|
private $em;
|
||||||
private readonly LoggerInterface $logger,
|
|
||||||
private readonly UserRepository $userRepo,
|
/** @var LoggerInterface */
|
||||||
private readonly UserApi $api,
|
private $logger;
|
||||||
private readonly int $pointApiDelay,
|
|
||||||
private readonly int $pointAppUserId,
|
/** @var UserRepository */
|
||||||
) {
|
private $userRepo;
|
||||||
|
|
||||||
|
/** @var InputInterface */
|
||||||
|
private $input;
|
||||||
|
|
||||||
|
/** @var UserApi */
|
||||||
|
private $api;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $apiDelay = 500000;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $appUserId;
|
||||||
|
|
||||||
|
/** @var ProgressBar */
|
||||||
|
private $progress;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em, LoggerInterface $logger, UserRepository $userRepo, UserApi $api, int $apiDelay, int $appUserId)
|
||||||
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->em = $em;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->userRepo = $userRepo;
|
||||||
|
$this->api = $api;
|
||||||
|
$this->apiDelay = $apiDelay;
|
||||||
|
$this->appUserId = $appUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
|
->setName('point:update:privacy')
|
||||||
|
->setDescription('Update users privacy')
|
||||||
->addOption(
|
->addOption(
|
||||||
'all-users',
|
'all-users',
|
||||||
null,
|
null,
|
||||||
|
@ -44,43 +70,47 @@ class UpdateUsersPrivacyCommand extends Command
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$io = new SymfonyStyle($input, $output);
|
$this->input = $input;
|
||||||
|
|
||||||
$this->logger->debug(static::class.' started.');
|
$this->logger->debug(static::class.' started.');
|
||||||
|
|
||||||
$progress = $io->createProgressBar();
|
$this->progress = new ProgressBar($output);
|
||||||
$progress->setFormat(ProgressBar::FORMAT_DEBUG);
|
$this->progress->setFormat('debug');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$usersForUpdate = $this->getUsersForUpdate($input);
|
/** @var User[] $usersForUpdate */
|
||||||
|
$usersForUpdate = $this->getUsersForUpdate();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]);
|
$this->logger->error('Error while getting service subscribers', ['exception' => get_class($e), 'message' => $e->getMessage()]);
|
||||||
|
|
||||||
return Command::FAILURE;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->info('Processing users privacy.');
|
$this->logger->info('Processing users privacy.');
|
||||||
|
|
||||||
$progress->start(count($usersForUpdate));
|
$this->progress->start(count($usersForUpdate));
|
||||||
|
|
||||||
foreach ($usersForUpdate as $user) {
|
foreach ($usersForUpdate as $idx => $user) {
|
||||||
usleep($this->pointApiDelay);
|
usleep($this->apiDelay);
|
||||||
|
|
||||||
$progress->advance();
|
$this->progress->advance();
|
||||||
$this->logger->info('Processing @'.$user->getLogin());
|
$this->logger->info('Processing @'.$user->getLogin());
|
||||||
|
|
||||||
$this->updateUser($user);
|
$this->updateUser($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
$progress->finish();
|
$this->progress->finish();
|
||||||
|
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
|
||||||
$this->logger->debug('Finished');
|
$this->logger->debug('Finished');
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateUser(User $user): void
|
private function updateUser(User $user): void
|
||||||
|
@ -120,18 +150,17 @@ class UpdateUsersPrivacyCommand extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return User[] */
|
private function getUsersForUpdate(): array
|
||||||
private function getUsersForUpdate(InputInterface $input): array
|
|
||||||
{
|
{
|
||||||
if ($input->getOption('all-users')) {
|
if ($this->input->getOption('all-users')) {
|
||||||
return $this->userRepo->findBy(['removed' => false]);
|
return $this->userRepo->findBy(['removed' => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var User $serviceUser */
|
/** @var User $serviceUser */
|
||||||
try {
|
try {
|
||||||
$serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->pointAppUserId);
|
$serviceUser = $this->userRepo->findActiveUserWithSubscribers($this->appUserId);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $this->pointAppUserId]);
|
$this->logger->error('Error while getting active user with subscribers', ['app_user_id' => $this->appUserId]);
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +169,7 @@ class UpdateUsersPrivacyCommand extends Command
|
||||||
$this->logger->warning('Service user not found or marked as removed. Falling back to API.');
|
$this->logger->warning('Service user not found or marked as removed. Falling back to API.');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$serviceUser = $this->api->getUserById($this->pointAppUserId);
|
$serviceUser = $this->api->getUserById($this->appUserId);
|
||||||
} catch (UserNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
throw new \RuntimeException('Service user not found in the database and could not be retrieved from API.');
|
throw new \RuntimeException('Service user not found in the database and could not be retrieved from API.');
|
||||||
}
|
}
|
||||||
|
@ -149,7 +178,7 @@ class UpdateUsersPrivacyCommand extends Command
|
||||||
$this->logger->info('Getting service subscribers');
|
$this->logger->info('Getting service subscribers');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->api->getUserSubscribersById($this->pointAppUserId);
|
return $this->api->getUserSubscribersById($this->appUserId);
|
||||||
} catch (UserNotFoundException $e) {
|
} catch (UserNotFoundException $e) {
|
||||||
$this->logger->critical('Service user deleted or API response is invalid');
|
$this->logger->critical('Service user deleted or API response is invalid');
|
||||||
|
|
||||||
|
@ -168,6 +197,7 @@ class UpdateUsersPrivacyCommand extends Command
|
||||||
|
|
||||||
$localSubscribers = [];
|
$localSubscribers = [];
|
||||||
|
|
||||||
|
/** @var Subscription $subscription */
|
||||||
foreach ($serviceUser->getSubscribers() as $subscription) {
|
foreach ($serviceUser->getSubscribers() as $subscription) {
|
||||||
$localSubscribers[] = $subscription->getSubscriber();
|
$localSubscribers[] = $subscription->getSubscriber();
|
||||||
}
|
}
|
8
old/src/PointToolsBundle/Exception/Api/ApiException.php
Normal file
8
old/src/PointToolsBundle/Exception/Api/ApiException.php
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
class ApiException extends \Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class ForbiddenException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class InvalidResponseException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
10
old/src/PointToolsBundle/Exception/Api/NetworkException.php
Normal file
10
old/src/PointToolsBundle/Exception/Api/NetworkException.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class NetworkException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
10
old/src/PointToolsBundle/Exception/Api/NotFoundException.php
Normal file
10
old/src/PointToolsBundle/Exception/Api/NotFoundException.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class NotFoundException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class ServerProblemException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\ApiException;
|
||||||
|
|
||||||
|
class UnauthorizedException extends ApiException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Exception\Api;
|
||||||
|
|
||||||
|
use src\PointToolsBundle\Exception\Api\NotFoundException;
|
||||||
|
|
||||||
|
class UserNotFoundException extends NotFoundException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $login;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @param int $userId
|
||||||
|
*/
|
||||||
|
public function __construct($message = 'User not found', $code = 0, \Exception $previous = null, $userId = null, $login = null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
|
||||||
|
$this->userId = $userId;
|
||||||
|
$this->login = $login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserId(): int
|
||||||
|
{
|
||||||
|
return $this->userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogin(): string
|
||||||
|
{
|
||||||
|
return $this->login;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception;
|
namespace src\PointToolsBundle\Exception;
|
||||||
|
|
||||||
class SubscriptionManagerException extends \Exception
|
class SubscriptionManagerException extends \Exception
|
||||||
{
|
{
|
202
old/src/PointToolsBundle/Service/Api/AbstractApi.php
Normal file
202
old/src/PointToolsBundle/Service/Api/AbstractApi.php
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Service\Api;
|
||||||
|
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use GuzzleHttp\Exception\TransferException;
|
||||||
|
use JMS\Serializer\{DeserializationContext, SerializerInterface};
|
||||||
|
use Psr\Http\Message\{ResponseInterface, StreamInterface};
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Exception\Api\{
|
||||||
|
src\PointToolsBundle\Exception\Api\ForbiddenException, src\PointToolsBundle\Exception\Api\NetworkException, src\PointToolsBundle\Exception\Api\NotFoundException, src\PointToolsBundle\Exception\Api\ServerProblemException, src\PointToolsBundle\Exception\Api\UnauthorizedException};
|
||||||
|
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||||
|
|
||||||
|
abstract class AbstractApi
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ClientInterface HTTP-client from Guzzle
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SerializerInterface
|
||||||
|
*/
|
||||||
|
protected $serializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Authentication token for API
|
||||||
|
*/
|
||||||
|
protected $authToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string CSRF-token for API
|
||||||
|
*/
|
||||||
|
protected $csRfToken;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct(ClientInterface $httpClient, SerializerInterface $serializer, LoggerInterface $logger)
|
||||||
|
{
|
||||||
|
$this->client = $httpClient;
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make GET request and return DTO objects
|
||||||
|
*
|
||||||
|
* @return array|object
|
||||||
|
*/
|
||||||
|
public function getGetJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
|
||||||
|
{
|
||||||
|
return $this->serializer->deserialize(
|
||||||
|
$this->getGetResponseBody($path, $parameters),
|
||||||
|
$type,
|
||||||
|
'json',
|
||||||
|
$context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make POST request and return DTO objects
|
||||||
|
*
|
||||||
|
* @return array|object
|
||||||
|
*/
|
||||||
|
public function getPostJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
|
||||||
|
{
|
||||||
|
return $this->serializer->deserialize(
|
||||||
|
$this->getPostResponseBody($path, $parameters),
|
||||||
|
$type,
|
||||||
|
'json',
|
||||||
|
$context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make GET request and return response body
|
||||||
|
*/
|
||||||
|
public function getGetResponseBody($path, array $parameters = []): StreamInterface
|
||||||
|
{
|
||||||
|
return $this->sendGetRequest($path, $parameters)->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make POST request and return response body
|
||||||
|
*/
|
||||||
|
public function getPostResponseBody(string $path, array $parameters = []): StreamInterface
|
||||||
|
{
|
||||||
|
return $this->sendPostRequest($path, $parameters)->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path Request path
|
||||||
|
* @param array $parameters Key => Value array of query parameters
|
||||||
|
*
|
||||||
|
* @return ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\NetworkException
|
||||||
|
*/
|
||||||
|
private function sendGetRequest(string $path, array $parameters = []): ResponseInterface
|
||||||
|
{
|
||||||
|
$this->logger->debug('Sending GET request', ['path' => $path, 'parameters' => $parameters]);
|
||||||
|
|
||||||
|
return $this->sendRequest('GET', $path, ['query' => $parameters]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path Request path
|
||||||
|
* @param array $parameters Key => Value array of request data
|
||||||
|
*
|
||||||
|
* @return ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\NetworkException
|
||||||
|
*/
|
||||||
|
private function sendPostRequest(string $path, array $parameters = []): ResponseInterface
|
||||||
|
{
|
||||||
|
$this->logger->debug('Sending POST request', ['path' => $path, 'parameters' => $parameters]);
|
||||||
|
|
||||||
|
return $this->sendRequest('POST', $path, ['form_params' => $parameters]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sendRequest(string $method, string $path, array $parameters): ResponseInterface
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$response = $this->client->request($method, $path, $parameters);
|
||||||
|
|
||||||
|
$this->checkResponse($response);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
} catch (TransferException $e) {
|
||||||
|
$this->processTransferException($e);
|
||||||
|
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\NetworkException('Request error', $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Exception $e
|
||||||
|
*
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\ForbiddenException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\NotFoundException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\ServerProblemException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\UnauthorizedException
|
||||||
|
* @todo refactor with $this->checkResponse()
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private function processTransferException(\Exception $e): void
|
||||||
|
{
|
||||||
|
switch ($e->getCode()) {
|
||||||
|
case SymfonyResponse::HTTP_UNAUTHORIZED:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\UnauthorizedException('Unauthorized', SymfonyResponse::HTTP_UNAUTHORIZED, $e);
|
||||||
|
case SymfonyResponse::HTTP_NOT_FOUND:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\NotFoundException('Resource not found', SymfonyResponse::HTTP_NOT_FOUND, $e);
|
||||||
|
case SymfonyResponse::HTTP_FORBIDDEN:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\ForbiddenException('Forbidden', SymfonyResponse::HTTP_FORBIDDEN, $e);
|
||||||
|
case SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR:
|
||||||
|
case SymfonyResponse::HTTP_NOT_IMPLEMENTED:
|
||||||
|
case SymfonyResponse::HTTP_BAD_GATEWAY:
|
||||||
|
case SymfonyResponse::HTTP_SERVICE_UNAVAILABLE:
|
||||||
|
case SymfonyResponse::HTTP_GATEWAY_TIMEOUT:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\ServerProblemException('Server error', SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\ForbiddenException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\NotFoundException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\ServerProblemException
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\UnauthorizedException
|
||||||
|
*/
|
||||||
|
private function checkResponse(ResponseInterface $response): void
|
||||||
|
{
|
||||||
|
$code = $response->getStatusCode();
|
||||||
|
$reason = $response->getReasonPhrase();
|
||||||
|
|
||||||
|
// @todo remove after fix
|
||||||
|
// Temporary fix until @arts fixes this bug
|
||||||
|
if ('{"error": "UserNotFound"}' === (string) $response->getBody()) {
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\NotFoundException('Not found', SymfonyResponse::HTTP_NOT_FOUND);
|
||||||
|
} elseif ('{"message": "Forbidden", "code": 403, "error": "Forbidden"}' === (string) $response->getBody()) {
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\ForbiddenException('Forbidden', SymfonyResponse::HTTP_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($code) {
|
||||||
|
case SymfonyResponse::HTTP_UNAUTHORIZED:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\UnauthorizedException($reason, $code);
|
||||||
|
case SymfonyResponse::HTTP_FORBIDDEN:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\ForbiddenException($reason, $code);
|
||||||
|
case SymfonyResponse::HTTP_NOT_FOUND:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\NotFoundException($reason, $code);
|
||||||
|
case SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR:
|
||||||
|
case SymfonyResponse::HTTP_NOT_IMPLEMENTED:
|
||||||
|
case SymfonyResponse::HTTP_BAD_GATEWAY:
|
||||||
|
case SymfonyResponse::HTTP_SERVICE_UNAVAILABLE:
|
||||||
|
case SymfonyResponse::HTTP_GATEWAY_TIMEOUT:
|
||||||
|
throw new \src\PointToolsBundle\Exception\Api\ServerProblemException($reason, $code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
old/src/PointToolsBundle/Service/Api/PostApi.php
Normal file
28
old/src/PointToolsBundle/Service/Api/PostApi.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace src\PointToolsBundle\Service\Api;
|
||||||
|
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use JMS\Serializer\SerializerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use src\PointToolsBundle\Service\Api\AbstractApi;
|
||||||
|
use src\PointToolsBundle\Service\Factory\Blogs\PostFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic Point.im user API functions from /api/post
|
||||||
|
*/
|
||||||
|
class PostApi extends AbstractApi
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PostFactory
|
||||||
|
*/
|
||||||
|
private $postFactory;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct(ClientInterface $httpClient, SerializerInterface $serializer, LoggerInterface $logger, PostFactory $postFactory)
|
||||||
|
{
|
||||||
|
parent::__construct($httpClient, $serializer, $logger);
|
||||||
|
|
||||||
|
$this->postFactory = $postFactory;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,36 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Service\Api;
|
namespace src\PointToolsBundle\Service\Api;
|
||||||
|
|
||||||
use App\DTO\Api\{Auth as AuthDTO, User as UserDTO};
|
use GuzzleHttp\ClientInterface;
|
||||||
use App\Entity\User;
|
use JMS\Serializer\{
|
||||||
use App\Exception\Api\{ForbiddenException,
|
DeserializationContext, SerializerInterface
|
||||||
InvalidResponseException,
|
|
||||||
NotFoundException,
|
|
||||||
UserNotFoundException
|
|
||||||
};
|
};
|
||||||
use App\Service\Factory\UserFactory;
|
|
||||||
use JMS\Serializer\{DeserializationContext, SerializerInterface};
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Skobkin\Bundle\PointToolsBundle\DTO\Api\{src\PointToolsBundle\DTO\Api\Auth, src\PointToolsBundle\DTO\Api\User as UserDTO};
|
||||||
|
use src\PointToolsBundle\Entity\User;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Exception\Api\{
|
||||||
|
src\PointToolsBundle\Exception\Api\ForbiddenException, src\PointToolsBundle\Exception\Api\InvalidResponseException, src\PointToolsBundle\Exception\Api\NotFoundException, src\PointToolsBundle\Exception\Api\UserNotFoundException};
|
||||||
|
use src\PointToolsBundle\Service\Api\AbstractApi;
|
||||||
|
use src\PointToolsBundle\Service\Factory\UserFactory;
|
||||||
|
|
||||||
/** Basic Point.im user API functions from /api/user/* */
|
/**
|
||||||
|
* Basic Point.im user API functions from /api/user/*
|
||||||
|
*/
|
||||||
class UserApi extends AbstractApi
|
class UserApi extends AbstractApi
|
||||||
{
|
{
|
||||||
private const PREFIX = '/api/user/';
|
private const PREFIX = '/api/user/';
|
||||||
|
|
||||||
public function __construct(
|
/**
|
||||||
HttpClientInterface $pointApiClient,
|
* @var UserFactory
|
||||||
SerializerInterface $serializer,
|
*/
|
||||||
LoggerInterface $logger,
|
private $userFactory;
|
||||||
private readonly UserFactory $userFactory,
|
|
||||||
) {
|
public function __construct(ClientInterface $httpClient, SerializerInterface $serializer, LoggerInterface $logger, UserFactory $userFactory)
|
||||||
parent::__construct($pointApiClient, $logger, $serializer);
|
{
|
||||||
|
parent::__construct($httpClient, $serializer, $logger);
|
||||||
|
|
||||||
|
$this->userFactory = $userFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isLoginAndPasswordValid(string $login, string $password): bool
|
public function isLoginAndPasswordValid(string $login, string $password): bool
|
||||||
|
@ -46,7 +50,7 @@ class UserApi extends AbstractApi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticate(string $login, string $password): AuthDTO
|
public function authenticate(string $login, string $password): \src\PointToolsBundle\DTO\Api\Auth
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to authenticate user via Point.im API', ['login' => $login]);
|
$this->logger->debug('Trying to authenticate user via Point.im API', ['login' => $login]);
|
||||||
|
|
||||||
|
@ -57,15 +61,17 @@ class UserApi extends AbstractApi
|
||||||
'login' => $login,
|
'login' => $login,
|
||||||
'password' => $password,
|
'password' => $password,
|
||||||
],
|
],
|
||||||
AuthDTO::class
|
\src\PointToolsBundle\DTO\Api\Auth::class
|
||||||
);
|
);
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new InvalidResponseException('API method not found', 0, $e);
|
throw new \src\PointToolsBundle\Exception\Api\InvalidResponseException('API method not found', 0, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @throws InvalidResponseException */
|
/**
|
||||||
public function logout(AuthDTO $auth): bool
|
* @throws \src\PointToolsBundle\Exception\Api\InvalidResponseException
|
||||||
|
*/
|
||||||
|
public function logout(\src\PointToolsBundle\DTO\Api\Auth $auth): bool
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to log user out via Point.im API');
|
$this->logger->debug('Trying to log user out via Point.im API');
|
||||||
|
|
||||||
|
@ -73,14 +79,20 @@ class UserApi extends AbstractApi
|
||||||
$this->getPostResponseBody('/api/logout', ['csrf_token' => $auth->getCsRfToken()]);
|
$this->getPostResponseBody('/api/logout', ['csrf_token' => $auth->getCsRfToken()]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new InvalidResponseException('API method not found', 0, $e);
|
throw new \src\PointToolsBundle\Exception\Api\InvalidResponseException('API method not found', 0, $e);
|
||||||
} catch (ForbiddenException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\ForbiddenException $e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return User[] */
|
/**
|
||||||
|
* Get user subscribers by user login
|
||||||
|
*
|
||||||
|
* @return User[]
|
||||||
|
*
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\UserNotFoundException
|
||||||
|
*/
|
||||||
public function getUserSubscribersByLogin(string $login): array
|
public function getUserSubscribersByLogin(string $login): array
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to get user subscribers by login', ['login' => $login]);
|
$this->logger->debug('Trying to get user subscribers by login', ['login' => $login]);
|
||||||
|
@ -90,16 +102,22 @@ class UserApi extends AbstractApi
|
||||||
self::PREFIX.urlencode($login).'/subscribers',
|
self::PREFIX.urlencode($login).'/subscribers',
|
||||||
[],
|
[],
|
||||||
'array<'.UserDTO::class.'>',
|
'array<'.UserDTO::class.'>',
|
||||||
DeserializationContext::create()->setGroups(['user_short']),
|
DeserializationContext::create()->setGroups(['user_short'])
|
||||||
);
|
);
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new UserNotFoundException('User not found', 0, $e, null, $login);
|
throw new \src\PointToolsBundle\Exception\Api\UserNotFoundException('User not found', 0, $e, null, $login);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->userFactory->findOrCreateFromDTOArray($usersList);
|
return $this->userFactory->findOrCreateFromDTOArray($usersList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return User[] */
|
/**
|
||||||
|
* Get user subscribers by user id
|
||||||
|
*
|
||||||
|
* @return User[]
|
||||||
|
*
|
||||||
|
* @throws \src\PointToolsBundle\Exception\Api\UserNotFoundException
|
||||||
|
*/
|
||||||
public function getUserSubscribersById(int $id): array
|
public function getUserSubscribersById(int $id): array
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to get user subscribers by id', ['id' => $id]);
|
$this->logger->debug('Trying to get user subscribers by id', ['id' => $id]);
|
||||||
|
@ -109,15 +127,18 @@ class UserApi extends AbstractApi
|
||||||
self::PREFIX.'id/'.$id.'/subscribers',
|
self::PREFIX.'id/'.$id.'/subscribers',
|
||||||
[],
|
[],
|
||||||
'array<'.UserDTO::class.'>',
|
'array<'.UserDTO::class.'>',
|
||||||
DeserializationContext::create()->setGroups(['user_short']),
|
DeserializationContext::create()->setGroups(['user_short'])
|
||||||
);
|
);
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new UserNotFoundException('User not found', 0, $e, $id);
|
throw new \src\PointToolsBundle\Exception\Api\UserNotFoundException('User not found', 0, $e, $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->userFactory->findOrCreateFromDTOArray($usersList);
|
return $this->userFactory->findOrCreateFromDTOArray($usersList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full user info by login
|
||||||
|
*/
|
||||||
public function getUserByLogin(string $login): User
|
public function getUserByLogin(string $login): User
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to get user by login', ['login' => $login]);
|
$this->logger->debug('Trying to get user by login', ['login' => $login]);
|
||||||
|
@ -128,15 +149,18 @@ class UserApi extends AbstractApi
|
||||||
self::PREFIX.'login/'.urlencode($login),
|
self::PREFIX.'login/'.urlencode($login),
|
||||||
[],
|
[],
|
||||||
UserDTO::class,
|
UserDTO::class,
|
||||||
DeserializationContext::create()->setGroups(['user_full']),
|
DeserializationContext::create()->setGroups(['user_full'])
|
||||||
);
|
);
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new UserNotFoundException('User not found', 0, $e, null, $login);
|
throw new \src\PointToolsBundle\Exception\Api\UserNotFoundException('User not found', 0, $e, null, $login);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->userFactory->findOrCreateFromDTO($userInfo);
|
return $this->userFactory->findOrCreateFromDTO($userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full user info by id
|
||||||
|
*/
|
||||||
public function getUserById(int $id): User
|
public function getUserById(int $id): User
|
||||||
{
|
{
|
||||||
$this->logger->debug('Trying to get user by id', ['id' => $id]);
|
$this->logger->debug('Trying to get user by id', ['id' => $id]);
|
||||||
|
@ -147,10 +171,10 @@ class UserApi extends AbstractApi
|
||||||
self::PREFIX.'id/'.$id,
|
self::PREFIX.'id/'.$id,
|
||||||
[],
|
[],
|
||||||
UserDTO::class,
|
UserDTO::class,
|
||||||
DeserializationContext::create()->setGroups(['user_full']),
|
DeserializationContext::create()->setGroups(['user_full'])
|
||||||
);
|
);
|
||||||
} catch (NotFoundException $e) {
|
} catch (\src\PointToolsBundle\Exception\Api\NotFoundException $e) {
|
||||||
throw new UserNotFoundException('User not found', 0, $e, $id);
|
throw new \src\PointToolsBundle\Exception\Api\UserNotFoundException('User not found', 0, $e, $id);
|
||||||
}
|
}
|
||||||
// Not catching ForbiddenException right now
|
// Not catching ForbiddenException right now
|
||||||
|
|
|
@ -18,11 +18,11 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
class RestoreRemovedUsersCommand extends Command
|
class RestoreRemovedUsersCommand extends Command
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly LoggerInterface $logger,
|
private readonly LoggerInterface $logger,
|
||||||
private readonly EntityManagerInterface $em,
|
private readonly EntityManagerInterface $em,
|
||||||
private readonly UserRepository $userRepo,
|
private readonly UserRepository $userRepo,
|
||||||
private readonly UserApi $userApi,
|
private readonly UserApi $userApi,
|
||||||
private readonly int $pointApiDelay,
|
private readonly int $apiDelay,
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class RestoreRemovedUsersCommand extends Command
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
foreach ($this->userRepo->findBy(['removed' => true]) as $removedUser) {
|
foreach ($this->userRepo->findBy(['removed' => true]) as $removedUser) {
|
||||||
\usleep($this->pointApiDelay);
|
\usleep($this->apiDelay);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$remoteUser = $this->userApi->getUserById($removedUser->getId());
|
$remoteUser = $this->userApi->getUserById($removedUser->getId());
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Command;
|
|
||||||
|
|
||||||
use App\Service\Telegram\MessageSender;
|
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
|
|
||||||
#[AsCommand(name: 'app:telegram:message', description: 'Send message via Telegram')]
|
|
||||||
class TelegramSendMessageCommand extends Command
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly MessageSender $messenger,
|
|
||||||
) {
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this
|
|
||||||
->addOption('chat-id', 'c', InputOption::VALUE_OPTIONAL, 'ID of the chat')
|
|
||||||
->addOption('stdin', 'i', InputOption::VALUE_NONE, 'Read message from stdin instead of option')
|
|
||||||
->addArgument('message', InputArgument::OPTIONAL, 'Text of the message')
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
||||||
{
|
|
||||||
$io = new SymfonyStyle($input, $output);
|
|
||||||
|
|
||||||
if ($input->getOption('stdin')) {
|
|
||||||
$message = \file_get_contents('php://stdin');
|
|
||||||
} elseif (null !== $input->getArgument('message')) {
|
|
||||||
$message = $input->getArgument('message');
|
|
||||||
} else {
|
|
||||||
$io->error('Either \'--stdin\' option or \'message\' argument should be specified.')
|
|
||||||
|
|
||||||
return Command::FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mb_strlen($message) > 4096) {
|
|
||||||
$io->comment('Message is too long (>4096). Cutting the tail...');
|
|
||||||
$message = \mb_substr($message, 0, 4090) . PHP_EOL . '...';
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->messenger->sendMessageToChat(
|
|
||||||
(int) $input->getOption('chat-id'),
|
|
||||||
$message
|
|
||||||
);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$io->error($e->getMessage());
|
|
||||||
|
|
||||||
return Command::FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Command::SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Command;
|
|
||||||
|
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
||||||
use unreal4u\Telegram\Methods\SetWebhook;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
use unreal4u\TgLog;
|
|
||||||
|
|
||||||
#[AsCommand(name: 'app:telegram:webhook', description: 'Set webhook')]
|
|
||||||
class TelegramWebhookCommand extends Command
|
|
||||||
{
|
|
||||||
private const MODE_SET = 'set';
|
|
||||||
private const MODE_DELETE = 'delete';
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
private readonly TgLog $client,
|
|
||||||
private readonly UrlGeneratorInterface $router,
|
|
||||||
private readonly string $telegramToken,
|
|
||||||
private readonly int $telegramWebhookMaxConnections,
|
|
||||||
) {
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this
|
|
||||||
->addArgument('mode', InputArgument::REQUIRED, 'Command mode (set or delete)')
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
||||||
{
|
|
||||||
$io = new SymfonyStyle($input, $output);
|
|
||||||
|
|
||||||
if (self::MODE_SET === strtolower($input->getArgument('mode'))) {
|
|
||||||
|
|
||||||
$url = $this->router->generate(
|
|
||||||
'telegram_webhook',
|
|
||||||
['token' => $this->telegramToken],
|
|
||||||
UrlGeneratorInterface::ABSOLUTE_URL
|
|
||||||
);
|
|
||||||
|
|
||||||
$io->info('Setting webhook: ' . $url);
|
|
||||||
|
|
||||||
$setWebHook = new SetWebhook();
|
|
||||||
$setWebHook->url = $url;
|
|
||||||
$setWebHook->max_connections = $this->telegramWebhookMaxConnections;
|
|
||||||
|
|
||||||
$this->client->performApiRequest($setWebHook);
|
|
||||||
|
|
||||||
$output->writeln('Done');
|
|
||||||
} elseif (self::MODE_DELETE === strtolower($input->getArgument('mode'))) {
|
|
||||||
$io->warning('Unsupported until moving to another library.');
|
|
||||||
} else {
|
|
||||||
throw new \InvalidArgumentException(sprintf('Mode must be exactly one of: %s', implode(', ', [self::MODE_SET, self::MODE_DELETE])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Command::SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class ApiException extends \Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class ForbiddenException extends ApiException
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
string $message = 'Forbidden',
|
|
||||||
int $code = 403,
|
|
||||||
?\Throwable $previous = null
|
|
||||||
) {
|
|
||||||
parent::__construct($message, $code, $previous);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class InvalidResponseException extends ApiException
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class NetworkException extends ApiException
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class NotFoundException extends ApiException
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
string $message = 'Resource not found',
|
|
||||||
int $code = 404,
|
|
||||||
?\Throwable $previous = null
|
|
||||||
) {
|
|
||||||
parent::__construct($message, $code, $previous);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class ServerProblemException extends ApiException
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
string $message = 'Server error',
|
|
||||||
int $code = 500,
|
|
||||||
?\Throwable $previous = null
|
|
||||||
) {
|
|
||||||
parent::__construct($message, $code, $previous);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class UnauthorizedException extends ApiException
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
string $message = 'Unauthorized',
|
|
||||||
int $code = 401,
|
|
||||||
?\Throwable $previous = null
|
|
||||||
) {
|
|
||||||
parent::__construct($message, $code, $previous);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Exception\Api;
|
|
||||||
|
|
||||||
class UserNotFoundException extends NotFoundException
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
$message = 'User not found',
|
|
||||||
$code = 0,
|
|
||||||
\Exception $previous = null,
|
|
||||||
private readonly ?int $userId = null,
|
|
||||||
private readonly ?string $login = null,
|
|
||||||
) {
|
|
||||||
parent::__construct($message, $code, $previous);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserId(): ?int
|
|
||||||
{
|
|
||||||
return $this->userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLogin(): ?string
|
|
||||||
{
|
|
||||||
return $this->login;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Service\Api;
|
|
||||||
|
|
||||||
use App\Exception\Api\{ApiException,
|
|
||||||
ForbiddenException,
|
|
||||||
NetworkException,
|
|
||||||
NotFoundException,
|
|
||||||
UnauthorizedException,
|
|
||||||
ServerProblemException};
|
|
||||||
use JMS\Serializer\SerializerInterface;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
|
||||||
|
|
||||||
class AbstractApi
|
|
||||||
{
|
|
||||||
protected HttpClientInterface $client;
|
|
||||||
// TODO: check if these are still needed
|
|
||||||
protected string $authToken;
|
|
||||||
protected string $csRfToken;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
HttpClientInterface $pointApiClient,
|
|
||||||
protected readonly LoggerInterface $logger,
|
|
||||||
private readonly SerializerInterface $serializer,
|
|
||||||
) {
|
|
||||||
$this->client = $pointApiClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make GET request and return DTO objects */
|
|
||||||
public function getGetJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null): array|object|null
|
|
||||||
{
|
|
||||||
return $this->serializer->deserialize(
|
|
||||||
$this->getGetResponseBody($path, $parameters),
|
|
||||||
$type,
|
|
||||||
'json',
|
|
||||||
$context
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make POST request and return DTO objects */
|
|
||||||
public function getPostJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null): array|object|null
|
|
||||||
{
|
|
||||||
return $this->serializer->deserialize(
|
|
||||||
$this->getPostResponseBody($path, $parameters),
|
|
||||||
$type,
|
|
||||||
'json',
|
|
||||||
$context
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make GET request and return response body */
|
|
||||||
public function getGetResponseBody($path, array $parameters = []): string
|
|
||||||
{
|
|
||||||
return $this->sendGetRequest($path, $parameters)->getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Make POST request and return response body */
|
|
||||||
public function getPostResponseBody(string $path, array $parameters = []): string
|
|
||||||
{
|
|
||||||
return $this->sendPostRequest($path, $parameters)->getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sendGetRequest(string $path, array $parameters = []): ResponseInterface
|
|
||||||
{
|
|
||||||
$this->logger->debug('Sending GET request', ['path' => $path, 'parameters' => $parameters]);
|
|
||||||
|
|
||||||
return $this->sendRequest('GET', $path, ['query' => $parameters]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sendPostRequest(string $path, array $parameters = []): ResponseInterface
|
|
||||||
{
|
|
||||||
$this->logger->debug('Sending POST request', ['path' => $path, 'parameters' => $parameters]);
|
|
||||||
|
|
||||||
return $this->sendRequest('POST', $path, ['form_params' => $parameters]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sendRequest(string $method, string $path, array $parameters): ResponseInterface
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$response = $this->client->request($method, $path, $parameters);
|
|
||||||
|
|
||||||
$this->checkResponse($response);
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
} catch (TransportExceptionInterface $e) {
|
|
||||||
$this->throwIfCodeMatches($e->getCode(), $e->getPrevious());
|
|
||||||
|
|
||||||
throw new NetworkException('Request error', $e->getCode(), $e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @throws ApiException */
|
|
||||||
private function checkResponse(ResponseInterface $response): void
|
|
||||||
{
|
|
||||||
$code = $response->getStatusCode();
|
|
||||||
|
|
||||||
// @todo remove after fix
|
|
||||||
// Temporary fix until @arts fixes this bug
|
|
||||||
if ('{"error": "UserNotFound"}' === $response->getContent()) {
|
|
||||||
throw new NotFoundException('Not found', SymfonyResponse::HTTP_NOT_FOUND);
|
|
||||||
} elseif ('{"message": "Forbidden", "code": 403, "error": "Forbidden"}' === (string) $response->getBody()) {
|
|
||||||
throw new ForbiddenException('Forbidden', SymfonyResponse::HTTP_FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->throwIfCodeMatches($code);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function throwIfCodeMatches(int $code, ?\Throwable $previous = null): void
|
|
||||||
{
|
|
||||||
$e = $this->matchException($code, $previous);
|
|
||||||
|
|
||||||
if ($e) {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function matchException(int $code, ?\Throwable $previous = null): ?ApiException
|
|
||||||
{
|
|
||||||
return match ($code) {
|
|
||||||
SymfonyResponse::HTTP_UNAUTHORIZED => new UnauthorizedException(previous: $previous),
|
|
||||||
SymfonyResponse::HTTP_NOT_FOUND => new NotFoundException(previous: $previous),
|
|
||||||
SymfonyResponse::HTTP_FORBIDDEN => new ForbiddenException(previous: $previous),
|
|
||||||
SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR,
|
|
||||||
SymfonyResponse::HTTP_NOT_IMPLEMENTED,
|
|
||||||
SymfonyResponse::HTTP_BAD_GATEWAY,
|
|
||||||
SymfonyResponse::HTTP_SERVICE_UNAVAILABLE,
|
|
||||||
SymfonyResponse::HTTP_GATEWAY_TIMEOUT => new ServerProblemException(previous: $previous),
|
|
||||||
default => null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Service\Api;
|
|
||||||
|
|
||||||
use JMS\Serializer\SerializerInterface;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use App\Service\Factory\Blogs\PostFactory;
|
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
||||||
|
|
||||||
/** Basic Point.im user API functions from /api/post */
|
|
||||||
class PostApi extends AbstractApi
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
HttpClientInterface $pointApiClient,
|
|
||||||
SerializerInterface $serializer,
|
|
||||||
LoggerInterface $logger,
|
|
||||||
private readonly PostFactory $postFactory
|
|
||||||
) {
|
|
||||||
parent::__construct($pointApiClient, $logger, $serializer);
|
|
||||||
}
|
|
||||||
}
|
|
12
symfony.lock
12
symfony.lock
|
@ -35,18 +35,6 @@
|
||||||
"migrations/.gitignore"
|
"migrations/.gitignore"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"jms/serializer-bundle": {
|
|
||||||
"version": "5.2",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes-contrib",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "4.0",
|
|
||||||
"ref": "cc04e10cf7171525b50c18b36004edf64cb478be"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/jms_serializer.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"phpunit/phpunit": {
|
"phpunit/phpunit": {
|
||||||
"version": "9.6",
|
"version": "9.6",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|
Loading…
Reference in a new issue