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",