diff --git a/.github/workflows/validate-test.yml b/.github/workflows/validate-test.yml new file mode 100644 index 0000000..51dd783 --- /dev/null +++ b/.github/workflows/validate-test.yml @@ -0,0 +1,60 @@ +name: PHP validate and Unit Test + +on: + push: + pull_request: + +concurrency: + group: test + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + + - name: Create Environments + run: echo "${{ secrets.TEST_ENV_VARIABLES }}" > .env + + - name: Install and update Composer packages + run: composer run-script install-dependencies + + - name: Run test suite + run: composer run-script phpunit-test + + validate: + runs-on: ubuntu-latest + + steps: + - name: Setup PHP + uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e + with: + php-version: '8.3' + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Validate PHP version + run: php -v + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + + - name: Install and update Composer packages + run: composer install --ignore-platform-reqs + + - name: Run PHP mess detector + run: composer run-script mess-detect diff --git a/.gitignore b/.gitignore index 5e0346b..1d2e37f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ /example.php /.telegram-bot /.phpunit.result.cache + +/.phpunit.cache diff --git a/README.md b/README.md index 95da6cb..298a16d 100644 --- a/README.md +++ b/README.md @@ -210,14 +210,14 @@ use TelegramBot\Entities\WebAppData; class MainPlugin extends \TelegramBot\Plugin { public function onMessage(int $update_id, Message $message): \Generator { - if ($message->getText() === '/start') { + if ($message->getText(false) === '/start') { yield \TelegramBot\Request::sendMessage([ 'chat_id' => $message->getChat()->getId(), 'text' => 'Hello, ' . $message->getFrom()->getFirstName(), ]); } - if ($message->getText() === '/ping') { + if ($message->getText(false) === '/ping') { yield \TelegramBot\Request::sendMessage([ 'chat_id' => $message->getChat()->getId(), 'text' => 'pong', diff --git a/composer.json b/composer.json index a44119f..b7a89b8 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,9 @@ "minimum-stability": "dev", "prefer-stable": true, "scripts": { - "test": "phpunit --colors=always --configuration phpunit.xml" + "install-dependencies": "composer install --ignore-platform-reqs", + "phpunit-test": "vendor/bin/phpunit --colors=always --configuration phpunit.xml", + "mess-detect": "vendor/bin/phpmd ./src text phpmd.xml" }, "require": { "php": ">=8.2", @@ -40,6 +42,7 @@ }, "require-dev": { "fakerphp/faker": "^1.23", + "phpmd/phpmd": "^2.15", "phpunit/phpunit": "^11.2", "psr/log": "^1.1|^2.0|^3.0" }, diff --git a/composer.lock b/composer.lock index 4d8d20d..d0c56a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c60c31b1ce6f99912fe735d08a25eb0b", + "content-hash": "366417527e10fdd8dd5b96f9e81c63c3", "packages": [ { "name": "guzzlehttp/guzzle", @@ -678,6 +678,143 @@ } ], "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.4", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "04229f163664973f68f38f6f73d917799168ef24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24", + "reference": "04229f163664973f68f38f6f73d917799168ef24", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-27T13:40:54+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, { "name": "fakerphp/faker", "version": "v1.23.1", @@ -859,6 +996,69 @@ }, "time": "2024-03-05T20:51:40+00:00" }, + { + "name": "pdepend/pdepend", + "version": "2.16.2", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58", + "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/polyfill-mbstring": "^1.19" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0|^1.2.3", + "gregwar/rst": "^1.0", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "keywords": [ + "PHP Depend", + "PHP_Depend", + "dev", + "pdepend" + ], + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.16.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2023-12-17T18:09:59+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.4", @@ -977,18 +1177,101 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpmd/phpmd", + "version": "2.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0", + "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.16.1", + "php": ">=5.3.9" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", + "gregwar/rst": "^1.0", + "mikey179/vfsstream": "^1.6.8", + "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "dev", + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.15.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2023-12-11T08:22:20+00:00" + }, { "name": "phpunit/php-code-coverage", - "version": "11.0.3", + "version": "11.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92" + "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92", - "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4dc2b7a606073f0fb80da09842ffb068b627c38f", + "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f", "shasum": "" }, "require": { @@ -1045,7 +1328,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.4" }, "funding": [ { @@ -1053,7 +1336,7 @@ "type": "github" } ], - "time": "2024-03-12T15:35:40+00:00" + "time": "2024-06-29T08:26:25+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2426,6 +2709,545 @@ ], "time": "2024-02-02T06:10:47+00:00" }, + { + "name": "symfony/config", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", + "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:57:53+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v7.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "6e108cded928bdafaf1da3fabe30dd5af20e36b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6e108cded928bdafaf1da3fabe30dd5af20e36b9", + "reference": "6e108cded928bdafaf1da3fabe30dd5af20e36b9", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^3.5", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v7.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-28T10:03:55+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c", + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-28T10:03:55+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.30.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T15:07:36+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.30.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-19T12:30:46+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "b80a669a2264609f07f1667f891dbfca25eba44c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c", + "reference": "b80a669a2264609f07f1667f891dbfca25eba44c", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-28T08:00:31+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.3", diff --git a/phpmd.xml b/phpmd.xml new file mode 100644 index 0000000..d9a2af4 --- /dev/null +++ b/phpmd.xml @@ -0,0 +1,49 @@ + + + + PHP detect mess used rules + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CrashPad.php b/src/CrashPad.php index bc6d5d7..0c69e37 100644 --- a/src/CrashPad.php +++ b/src/CrashPad.php @@ -4,6 +4,7 @@ namespace TelegramBot; use Exception; +use RuntimeException; use Throwable; /** @@ -30,7 +31,7 @@ public static function enableCrashHandler(): void } if (!defined('DEBUG_MODE')) { - throw new \RuntimeException( + throw new RuntimeException( 'Something went wrong, Unfortunately, we can not handle this error.', 0, $throwable ); } @@ -72,7 +73,7 @@ public static function setDebugMode(int $admin_id = -1): void public static function sendCrash(int $chat_id, Exception|Throwable $exception, string|null $update = null): bool { if ($chat_id === -1) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'The given `chat_id` is not valid. given: %s', $chat_id )); @@ -82,8 +83,10 @@ public static function sendCrash(int $chat_id, Exception|Throwable $exception, s Telegram::tryAutoloadEnv(); } - if (($token = self::loadToken()) === null) { - throw new \RuntimeException( + $token = self::loadToken(); + + if ($token === null) { + throw new RuntimeException( 'The token is not set. Please set the token using `Telegram::setToken()` method.' ); } @@ -179,7 +182,9 @@ public static function clearCrashLogs(): void */ protected static function loadToken(): string|null { - if (($token = Telegram::getApiToken()) !== false) { + $token = Telegram::getApiToken(); + + if ($token !== false) { return $token; } diff --git a/src/Entities/Chat.php b/src/Entities/Chat.php index 1968621..cb0caf3 100644 --- a/src/Entities/Chat.php +++ b/src/Entities/Chat.php @@ -40,11 +40,11 @@ public function __construct($data) { parent::__construct($data); - $id = $this->getId(); + $_id = $this->getId(); $type = $this->getType(); if (!$type) { - $id > 0 && $this->type = 'private'; - $id < 0 && $this->type = 'group'; + $_id > 0 && $this->type = 'private'; + $_id < 0 && $this->type = 'group'; } } diff --git a/src/Entities/Keyboard.php b/src/Entities/Keyboard.php index 4c04c7b..079cbf6 100644 --- a/src/Entities/Keyboard.php +++ b/src/Entities/Keyboard.php @@ -3,6 +3,7 @@ namespace TelegramBot\Entities; +use ReflectionClass; use TelegramBot\Entity; /** @@ -71,7 +72,7 @@ public function setKeyboard(array $rows): array $this->addRow($row); } - return $this->getRawData(); + return $this->getRawData(true); } /** @@ -90,7 +91,7 @@ public function addRow(array $row): Keyboard $new_row = []; foreach ($row as $button) { - $new_row[] = $button->getRawData(); + $new_row[] = $button->getRawData(true); } $this->raw_data[$keyboard_type][] = $new_row; @@ -105,7 +106,7 @@ public function addRow(array $row): Keyboard */ public function getType(): string { - $reflection = new \ReflectionClass(static::class); + $reflection = new ReflectionClass(static::class); $class_name = $reflection->getShortName(); diff --git a/src/Entities/Message.php b/src/Entities/Message.php index 0139ad3..8441dd7 100644 --- a/src/Entities/Message.php +++ b/src/Entities/Message.php @@ -85,11 +85,12 @@ class Message extends Entity * * @return string|null */ - public function getText(bool $without_cmd = false): ?string + public function getText(bool $without_cmd): ?string { $text = $this->getProperty('text'); + $command = $this->getFullCommand(); - if ($without_cmd && $command = $this->getFullCommand()) { + if ($without_cmd && $command) { if (strlen($command) + 1 < strlen($text)) { return substr($text, strlen($command) + 1); } @@ -201,7 +202,9 @@ public function getType(): string */ public function getCommand(): ?string { - if ($command = $this->getProperty('command')) { + $command = $this->getProperty('command'); + + if ($command) { return $command; } diff --git a/src/Entities/Payments/PreCheckoutQuery.php b/src/Entities/Payments/PreCheckoutQuery.php index 2511046..819d3a0 100644 --- a/src/Entities/Payments/PreCheckoutQuery.php +++ b/src/Entities/Payments/PreCheckoutQuery.php @@ -33,11 +33,11 @@ class PreCheckoutQuery extends Entity * * @return Response */ - public function answer(bool $ok, array $data = []): Response + public function answer(bool $_ok, array $data = []): Response { return Request::answerPreCheckoutQuery(array_merge([ 'pre_checkout_query_id' => $this->getId(), - 'ok' => $ok, + 'ok' => $_ok, ], $data)); } diff --git a/src/Entities/Payments/ShippingQuery.php b/src/Entities/Payments/ShippingQuery.php index fefcb82..7213146 100644 --- a/src/Entities/Payments/ShippingQuery.php +++ b/src/Entities/Payments/ShippingQuery.php @@ -30,11 +30,11 @@ class ShippingQuery extends Entity * * @return Response */ - public function answer(bool $ok, array $data = []): Response + public function answer(bool $_ok, array $data = []): Response { return Request::answerShippingQuery(array_merge([ 'shipping_query_id' => $this->getId(), - 'ok' => $ok, + 'ok' => $_ok, ], $data)); } diff --git a/src/Entities/Response.php b/src/Entities/Response.php index 29dbe72..22e7387 100644 --- a/src/Entities/Response.php +++ b/src/Entities/Response.php @@ -2,6 +2,7 @@ namespace TelegramBot\Entities; +use InvalidArgumentException; use TelegramBot\Entity; /** @@ -43,12 +44,11 @@ public function __construct(array $data) $this->response = $data; $is_ok = (bool)($data['ok'] ?? false); - $result = $data['result'] ?? null; if ($is_ok) { foreach ($this->requiredFields as $field) { if (!isset($data[$field])) { - throw new \InvalidArgumentException("The field '{$field}' is required."); + throw new InvalidArgumentException("The field '{$field}' is required."); } } } @@ -74,7 +74,7 @@ public function isOk(): bool * @param bool $return * @return bool|string */ - public function printError(bool $return = false): bool|string + public function printError(bool $return): bool|string { $error = sprintf('Error N: %s, Description: %s', $this->getErrorCode(), $this->getDescription()); diff --git a/src/Entities/UserProfilePhotos.php b/src/Entities/UserProfilePhotos.php index b97e5bd..4123052 100644 --- a/src/Entities/UserProfilePhotos.php +++ b/src/Entities/UserProfilePhotos.php @@ -25,8 +25,9 @@ class UserProfilePhotos extends Entity public function getPhotos(): array { $all_photos = []; + $these_photos = $this->getProperty('photos'); - if ($these_photos = $this->getProperty('photos')) { + if ($these_photos) { foreach ($these_photos as $photos) { $all_photos[] = array_map(function ($photo) { return new PhotoSize($photo); diff --git a/src/Entity.php b/src/Entity.php index a20f795..45a73b3 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -3,6 +3,8 @@ namespace TelegramBot; +use BadMethodCallException; + /** * Entity class * @@ -90,7 +92,7 @@ public static function escapeMarkdownV2(string $string): string { * @param bool $associated * @return array|string */ - public function getRawData(bool $associated = true): array|string { + public function getRawData(bool $associated): array|string { return $associated ? $this->raw_data : json_encode($this->raw_data); } @@ -169,7 +171,7 @@ public function __call(string $name, array $arguments): mixed { return $this; } - throw new \BadMethodCallException(`Method {$name} does not exist`); + throw new BadMethodCallException(`Method {$name} does not exist`); } } diff --git a/src/Request.php b/src/Request.php index b4a528e..eddd810 100644 --- a/src/Request.php +++ b/src/Request.php @@ -174,13 +174,6 @@ class Request { */ private static string $api_base_uri = 'https://api.telegram.org'; - /** - * URI of the Telegram API for downloading files (relative to $api_base_url or absolute) - * - * @var string - */ - private static string $api_base_download_uri = '/file/bot{API_KEY}'; - /** * The current action that is being executed * @@ -349,15 +342,9 @@ private static function setUpRequestParams(array $data): array { } } - if ($item instanceof Entity) { - $item = $item->getRawData(); - } - - if (is_array($item)) { - $item = json_encode($item); - } + $itemObject = self::getItemEncode($item); - $options['query'][$key] = $item; + $options['query'][$key] = $itemObject; } unset($item); @@ -377,4 +364,21 @@ private static function getClient(): Client { return new Client(); } + /** + * get the item encoded + * @param $item + * @return string + */ + private static function getItemEncode($item): string { + if ($item instanceof Entity) { + $item = $item->getRawData(true); + } + + if (is_array($item)) { + $item = json_encode($item); + } + + return $item; + } + } diff --git a/src/Telegram.php b/src/Telegram.php index 16eb9e5..7918f9b 100644 --- a/src/Telegram.php +++ b/src/Telegram.php @@ -160,21 +160,7 @@ public static function processUpdate(string $input, string|null $apiKey = null): ); } - if ($apiKey !== null && self::validateWebData($apiKey, $input)) { - if (Toolkit::isUrlEncode($input)) { - $web_data = Toolkit::urlDecode($input); - } - - if (Toolkit::isJson($input)) { - $web_data = json_decode($input, true); - } - - if (!empty($web_data) && is_array($web_data)) { - $input = json_encode([ - 'web_app_data' => $web_data, - ]); - } - } + $input = self::handleInputEncoding($apiKey, $input); if (!Toolkit::isJson($input)) { throw new TelegramException(sprintf( @@ -235,4 +221,35 @@ public static function getApiToken(): string|false return self::$api_key !== null ? (self::validateToken(self::$api_key) ? self::$api_key : false) : false; } + /** + * Handle input encoding + * from web data + * @param $apiKey + * @param $input + * @return string + */ + private static function handleInputEncoding($apiKey, $input): string + { + if ($apiKey !== null && self::validateWebData($apiKey, $input)) { + + $web_data = []; + if (Toolkit::isUrlEncode($input)) { + $web_data = Toolkit::urlDecode($input); + } + + if (Toolkit::isJson($input)) { + $web_data = json_decode($input, true); + } + + + if (!empty($web_data) && is_array($web_data)) { + $input = json_encode([ + 'web_app_data' => $web_data, + ]); + } + } + + return $input; + } + } diff --git a/src/TelegramLog.php b/src/TelegramLog.php index 6b958bd..636984b 100644 --- a/src/TelegramLog.php +++ b/src/TelegramLog.php @@ -79,7 +79,9 @@ public static function initialize(LoggerInterface $logger = null, LoggerInterfac */ public static function getDebugLogTempStream() { - if ((self::$debug_log_temp_stream_handle === null) && $temp_stream_handle = fopen('php://temp', 'wb+')) { + $temp_stream_handle = fopen('php://temp', 'wb+'); + + if ((self::$debug_log_temp_stream_handle === null) && $temp_stream_handle) { self::$debug_log_temp_stream_handle = $temp_stream_handle; } diff --git a/src/Traits/HandlerTrait.php b/src/Traits/HandlerTrait.php index 412fa4c..84a536d 100644 --- a/src/Traits/HandlerTrait.php +++ b/src/Traits/HandlerTrait.php @@ -15,9 +15,12 @@ trait HandlerTrait { + /** + * @TODO @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function __process(Update $update): void { // TODO: Implement __process() method. } -} \ No newline at end of file +} diff --git a/src/Traits/PluginTrait.php b/src/Traits/PluginTrait.php index c94069a..278d06c 100644 --- a/src/Traits/PluginTrait.php +++ b/src/Traits/PluginTrait.php @@ -53,7 +53,9 @@ public function __execute(UpdateHandler $receiver, Update $update): void { } $type = $this->__identify($update); - if (method_exists($this, ($method = 'on' . $type)) && $type !== null) { + $method = 'on' . $type; + + if (method_exists($this, $method) && $type !== null) { $this->__checkExit($this->__callEvent($method, $update)); } } @@ -110,4 +112,4 @@ private function __callEvent(string $method, Update $update): \Generator { }; } -} \ No newline at end of file +} diff --git a/src/UpdateHandler.php b/src/UpdateHandler.php index 66eb046..eed9c38 100644 --- a/src/UpdateHandler.php +++ b/src/UpdateHandler.php @@ -2,6 +2,8 @@ namespace TelegramBot; +use InvalidArgumentException; +use RuntimeException; use TelegramBot\Entities\Update; use TelegramBot\Exception\InvalidBotTokenException; use TelegramBot\Interfaces\HandlerInterface; @@ -71,6 +73,8 @@ public function __construct(string $api_token = '') { * @param ?Update $update The custom to work with * @param array $config The configuration of the receiver * @return void + + * @TODO @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public static function resolveOn(Plugin $plugin, Update $update = null, array $config = []): void { // TODO: Implement resolveOn() method. @@ -89,12 +93,11 @@ public function addPlugins(Plugin|array $plugins): UpdateHandler { foreach ($plugins as $plugin) { if (!is_subclass_of($plugin, Plugin::class)) { - throw new \RuntimeException( + throw new RuntimeException( sprintf('The plugin %s must be an instance of %s', get_class($plugin), Plugin::class) ); } - $reflection = Toolkit::reflectionClass($plugin); $this->plugins[] = [ 'class' => $plugin, 'initialized' => is_object($plugin), @@ -137,10 +140,10 @@ private function isFiltered(Update $update): bool { } elseif (is_bool($value)) { return $value; } - throw new \InvalidArgumentException('The value of the filter must be a callable or a boolean'); + throw new InvalidArgumentException('The value of the filter must be a callable or a boolean'); } } - throw new \InvalidArgumentException('Invalid filter'); + throw new InvalidArgumentException('Invalid filter'); } return false; @@ -168,7 +171,7 @@ public function resolve(Update|null $update = null, array $config = []): void { } if (!method_exists($this, '__process')) { - throw new \RuntimeException('The method __process does not exist'); + throw new RuntimeException('The method __process does not exist'); } if (is_array($config)) { @@ -202,7 +205,7 @@ private function loadPlugins(array $plugins): void { foreach ($plugins as $plugin) { if (!is_subclass_of($plugin['class'], Plugin::class)) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'The plugin %s must be an instance of %s', get_class($plugin['class']), Plugin::class )); @@ -210,7 +213,7 @@ private function loadPlugins(array $plugins): void { } if (!$update instanceof Update) { - throw new \InvalidArgumentException(sprintf( + throw new InvalidArgumentException(sprintf( 'The update must be an instance of %s. %s given', Update::class, gettype($update) )); @@ -250,4 +253,4 @@ public function stop(): void { $this->active_spreader = false; } -} \ No newline at end of file +} diff --git a/src/Util/Toolkit.php b/src/Util/Toolkit.php index 7c0f1c4..d74d8bc 100644 --- a/src/Util/Toolkit.php +++ b/src/Util/Toolkit.php @@ -2,6 +2,10 @@ namespace TelegramBot\Util; +use ReflectionClass; +use ReflectionException; +use RuntimeException; + /** * Toolkit class * @@ -75,15 +79,15 @@ public static function isJson(?string $string): bool * Ignored reflection class * * @param class-string|object $reflectionClass - * @return \ReflectionClass + * @return ReflectionClass */ - public static function reflectionClass(string|object $reflectionClass): \ReflectionClass + public static function reflectionClass(string|object $reflectionClass): ReflectionClass { try { - return new \ReflectionClass($reflectionClass); - } catch (\ReflectionException $e) { - throw new \RuntimeException($e->getMessage(), $e->getCode(), $e); + return new ReflectionClass($reflectionClass); + } catch (ReflectionException $e) { + throw new RuntimeException($e->getMessage(), $e->getCode(), $e); } } -} \ No newline at end of file +} diff --git a/tests/CrashTest.php b/tests/CrashTest.php index da7a26c..de747ad 100644 --- a/tests/CrashTest.php +++ b/tests/CrashTest.php @@ -16,15 +16,16 @@ public function test_crash(): void { $plugin = new class($this) extends Plugin { public function __construct(TestCase $testCase) { - Telegram::setAdminId(259760855); - $testCase->assertEquals(259760855, Telegram::getAdminId()); + TelegramTest::loadEnvironment(); + Telegram::setAdminId((int)$_ENV['TEST_USER_ID']); + $testCase->assertEquals((int)$_ENV['TEST_USER_ID'], Telegram::getAdminId()); } public function __process(Update $update): void { CrashPad::sendCrash( Telegram::getAdminId(), new \Exception('test'), - json_encode($update->getRawData(), JSON_PRETTY_PRINT) + json_encode($update->getRawData(true), JSON_PRETTY_PRINT) ); CrashPad::clearCrashLogs(); } diff --git a/tests/Examples/EchoBot/Plugins/MainPlugin.php b/tests/Examples/EchoBot/Plugins/MainPlugin.php index fd9cde0..3c99b8a 100644 --- a/tests/Examples/EchoBot/Plugins/MainPlugin.php +++ b/tests/Examples/EchoBot/Plugins/MainPlugin.php @@ -9,9 +9,10 @@ class MainPlugin extends \TelegramBot\Plugin { public function onMessage(int $update_id, Message $message): \Generator { - Assert::assertEquals('Hello World!', $message->getText()); + Assert::assertEquals('Hello World!', $message->getText(false)); Assert::assertEquals(1, $update_id); yield; } } + diff --git a/tests/HandlerTest.php b/tests/HandlerTest.php index 957807f..34220f0 100644 --- a/tests/HandlerTest.php +++ b/tests/HandlerTest.php @@ -13,9 +13,10 @@ class HandlerTest extends \PHPUnit\Framework\TestCase { public function test_echo_bot(): void { + TelegramTest::loadEnvironment(); (new Handler())->resolve(Telegram::processUpdate( '{"update_id":1,"message":{"message_id":1,"from":{"id":1,"is_bot":false,"first_name":"First","last_name":"Last","username":"username","language_code":"en"},"chat":{"id":1,"first_name":"First","last_name":"Last","username":"username","type":"private"},"date":1546300800,"text":"Hello World!"}}', - '1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + $_ENV['TELEGRAM_BOT_TOKEN'] )); $this->assertTrue(true); diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 9523ecc..58c8b00 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -45,7 +45,7 @@ public function test_send_message(): void Telegram::setToken($_ENV['TELEGRAM_BOT_TOKEN']); $response = Request::sendMessage([ - 'chat_id' => 259760855, + 'chat_id' => $_ENV['TEST_USER_ID'], 'text' => 'Hello World', ]); diff --git a/tests/WebhookTest.php b/tests/WebhookTest.php index 19190b3..c33a184 100644 --- a/tests/WebhookTest.php +++ b/tests/WebhookTest.php @@ -15,7 +15,7 @@ public function testAnonymousPlugins() { public function onMessage(int $update_id, Message $message): \Generator { Assert::assertEquals(1, $update_id); - Assert::assertEquals('Hello World!', $message->getText()); + Assert::assertEquals('Hello World!', $message->getText(false)); yield; } @@ -26,7 +26,7 @@ public function onMessage(int $update_id, Message $message): \Generator { (new UpdateHandler())->addPlugins($plugin)->resolve(new Update([ 'update_id' => 1, - 'message' => $message->getRawData(), + 'message' => $message->getRawData(true), ])); } @@ -46,10 +46,11 @@ public function __process(Update $update): void { $handler->resolve(new Update([ 'update_id' => 1, - 'message' => DummyUpdate::message()->getRawData(), + 'message' => DummyUpdate::message()->getRawData(true), ])); $this->assertTrue(true); } } +