diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4454cf9..4db8b93 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,5 +26,8 @@ jobs: cd ./src composer install --prefer-dist --no-progress + - name: Run codesniffer + run: make codesniffer + - name: Run phpstan run: make phpstan diff --git a/Makefile b/Makefile index fcf04b0..fe220ae 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,11 @@ +.PHONE codesniffer: +codesniffer: + cd ./src && composer codesniffer + +.PHONE codesnifferFix: +codesnifferFix: + cd ./src && composer codesnifferFix + .PHONE composerValidate: composerValidate: cd ./src && composer validate --strict @@ -8,4 +16,4 @@ dockerComposeUp: .PHONE phpstan: phpstan: - cd ./src && composer phpstan \ No newline at end of file + cd ./src && composer phpstan diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..12577da --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,387 @@ + + + ftipalek/wb-assignment coding standards. + + + + */vendor/* + */libs/* + */temp/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon index 7a9bac7..7b5adbf 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,10 +1,34 @@ parameters: + checkDynamicProperties: true + + checkMissingCallableSignature: true + + checkMissingOverrideMethodAttribute: true + + checkTooWideReturnTypesInProtectedAndPublicMethods: true + + checkUninitializedProperties: true + + fileExtensions: + - php + - phpt + level: 5 paths: - ./src/app - ./src/www + reportAnyTypeWideningInVarTag: true + + reportWrongPhpDocTypeInVarTag: true + + strictRules: + allRules: true + + universalObjectCratesClasses: + - Dibi\Row + includes: - ./src/vendor/phpstan/phpstan-deprecation-rules/rules.neon - ./src/vendor/phpstan/phpstan-dibi/extension.neon diff --git a/src/app/Bootstrap.php b/src/app/Bootstrap.php index a7a9306..f6db9ec 100644 --- a/src/app/Bootstrap.php +++ b/src/app/Bootstrap.php @@ -3,23 +3,26 @@ namespace WbAssignment; use Nette; -use Nette\Bootstrap\Configurator; class Bootstrap { - private Configurator $configurator; + + private Nette\Bootstrap\Configurator $configurator; + private string $rootDir; + public function __construct() { $this->rootDir = dirname(__DIR__); - $this->configurator = new Configurator; + $this->configurator = new Nette\Bootstrap\Configurator(); $this->configurator->setTempDirectory($this->rootDir . '/temp'); } + public function bootWebApplication(): Nette\DI\Container { $this->initializeEnvironment(); @@ -28,6 +31,7 @@ public function bootWebApplication(): Nette\DI\Container } + public function initializeEnvironment(): void { //$this->configurator->setDebugMode('secret@23.75.345.200'); // enable for your remote IP @@ -39,10 +43,12 @@ public function initializeEnvironment(): void } + private function setupContainer(): void { $configDir = $this->rootDir . '/config'; $this->configurator->addConfig($configDir . '/common.neon'); $this->configurator->addConfig($configDir . '/services.neon'); } + } diff --git a/src/app/Core/RouterFactory.php b/src/app/Core/RouterFactory.php index dd28f75..834d843 100644 --- a/src/app/Core/RouterFactory.php +++ b/src/app/Core/RouterFactory.php @@ -3,17 +3,20 @@ namespace WbAssignment\Core; use Nette; -use Nette\Application\Routers\RouteList; final class RouterFactory { + use Nette\StaticClass; - public static function createRouter(): RouteList + + + public static function createRouter(): Nette\Application\Routers\RouteList { - $router = new RouteList; + $router = new Nette\Application\Routers\RouteList(); $router->addRoute('/[/]', 'Home:default'); return $router; } + } diff --git a/src/app/Presentation/Error/Error4xx/Error4xxPresenter.php b/src/app/Presentation/Error/Error4xx/Error4xxPresenter.php index 80a65e5..a8f4c52 100644 --- a/src/app/Presentation/Error/Error4xx/Error4xxPresenter.php +++ b/src/app/Presentation/Error/Error4xx/Error4xxPresenter.php @@ -3,15 +3,15 @@ namespace WbAssignment\Presentation\Error\Error4xx; use Nette; -use Nette\Application\Attributes\Requires; /** * Handles 4xx HTTP error responses. */ -#[Requires(methods: '*', forward: true)] +#[Nette\Application\Attributes\Requires(methods: '*', forward: TRUE)] final class Error4xxPresenter extends Nette\Application\UI\Presenter { + public function renderDefault(Nette\Application\BadRequestException $exception): void { // renders the appropriate error template based on the HTTP status code @@ -22,4 +22,5 @@ public function renderDefault(Nette\Application\BadRequestException $exception): $this->template->httpCode = $code; $this->template->setFile($file); } + } diff --git a/src/app/Presentation/Error/Error5xx/Error5xxPresenter.php b/src/app/Presentation/Error/Error5xx/Error5xxPresenter.php index 6c5d6d4..e27efde 100644 --- a/src/app/Presentation/Error/Error5xx/Error5xxPresenter.php +++ b/src/app/Presentation/Error/Error5xx/Error5xxPresenter.php @@ -3,35 +3,35 @@ namespace WbAssignment\Presentation\Error\Error5xx; use Nette; -use Nette\Application\Attributes\Requires; -use Nette\Application\Responses; -use Nette\Http; -use Tracy\ILogger; +use Tracy; /** * Handles uncaught exceptions and errors, and logs them. */ -#[Requires(forward: true)] +#[Nette\Application\Attributes\Requires(forward: TRUE)] final class Error5xxPresenter implements Nette\Application\IPresenter { + public function __construct( - private ILogger $logger, - ) { - } + private Tracy\ILogger $logger, + ) {} + + #[\Override] public function run(Nette\Application\Request $request): Nette\Application\Response { // Log the exception $exception = $request->getParameter('exception'); - $this->logger->log($exception, ILogger::EXCEPTION); + $this->logger->log($exception, Tracy\ILogger::EXCEPTION); // Display a generic error message to the user - return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void { + return new Nette\Application\Responses\CallbackResponse(function (Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse): void { if (preg_match('#^text/html(?:;|$)#', (string) $httpResponse->getHeader('Content-Type'))) { require __DIR__ . '/500.phtml'; } }); } + } diff --git a/src/app/Presentation/Home/HomePresenter.php b/src/app/Presentation/Home/HomePresenter.php index 39939ca..8123d98 100644 --- a/src/app/Presentation/Home/HomePresenter.php +++ b/src/app/Presentation/Home/HomePresenter.php @@ -7,4 +7,5 @@ final class HomePresenter extends Nette\Application\UI\Presenter { + } diff --git a/src/composer.json b/src/composer.json index 8d231d4..35c65c0 100644 --- a/src/composer.json +++ b/src/composer.json @@ -27,7 +27,9 @@ "phpstan/phpstan-dibi": "^2.0", "phpstan/phpstan-nette": "^2", "phpstan/phpstan-strict-rules": "^2.0", + "slevomat/coding-standard": "^8.20", "spaze/phpstan-disallowed-calls": "^4.6", + "squizlabs/php_codesniffer": "^3.13", "symfony/thanks": "^1" }, "autoload": { @@ -36,6 +38,8 @@ } }, "scripts": { + "codesniffer": "vendor/bin/phpcs --standard=../phpcs.xml --extensions=php,phpt --colors -p -s ./app", + "codesnifferFix": "vendor/bin/phpcbf --standard=../phpcs.xml --extensions=php,phpt --colors -p -s ./app", "phpstan": "phpstan analyse -c ../phpstan.neon", "server": "cd ./www && php -S localhost:8005", "tester": "tester tests -s" @@ -43,6 +47,7 @@ "minimum-stability": "stable", "config": { "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, "symfony/thanks": true }, "platform": { diff --git a/src/composer.lock b/src/composer.lock index 0818168..54444a8 100644 --- a/src/composer.lock +++ b/src/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": "ba1c3e5390d38a49e86932890ac01656", + "content-hash": "7907fc5cc6bbb75089392d951175aaf4", "packages": [ { "name": "dibi/dibi", @@ -1512,6 +1512,102 @@ } ], "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.2", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "^2.2", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "opensource@frenck.dev", + "homepage": "https://frenck.dev", + "role": "Open source developer" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "security": "https://github.com/PHPCSStandards/composer-installer/security/policy", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-07-17T20:45:56+00:00" + }, { "name": "nette/tester", "version": "v2.5.6", @@ -1590,6 +1686,53 @@ }, "time": "2025-08-07T00:28:58+00:00" }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.2.0" + }, + "time": "2025-07-13T07:04:09+00:00" + }, { "name": "phpstan/phpstan", "version": "2.1.22", @@ -1857,6 +2000,71 @@ }, "time": "2025-07-21T12:19:29+00:00" }, + { + "name": "slevomat/coding-standard", + "version": "8.20.0", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b4f9f02edd4e6a586777f0cabe8d05574323f3eb", + "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.1.2", + "php": "^7.4 || ^8.0", + "phpstan/phpdoc-parser": "^2.2.0", + "squizlabs/php_codesniffer": "^3.13.2" + }, + "require-dev": { + "phing/phing": "3.0.1|3.1.0", + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/phpstan": "2.1.19", + "phpstan/phpstan-deprecation-rules": "2.0.3", + "phpstan/phpstan-phpunit": "2.0.7", + "phpstan/phpstan-strict-rules": "2.0.6", + "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.27|12.2.7" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.20.0" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2025-07-26T15:35:10+00:00" + }, { "name": "spaze/phpstan-disallowed-calls", "version": "v4.6.0", @@ -1925,6 +2133,90 @@ ], "time": "2025-07-11T18:17:33+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.13.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-06-17T22:17:01+00:00" + }, { "name": "symfony/thanks", "version": "v1.4.0",