From ace47b2d70c9ac0907be13223d592d8f980dc46a Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Sat, 23 Mar 2024 15:40:09 +0100 Subject: [PATCH] add phpstan --- .github/workflows/build.yml | 42 +++++++++++++++++++++++++ .phpstan.neon | 5 +++ app/Blog/Presenters/HomePresenter.php | 17 ++++++---- app/Blog/Presenters/LayoutTemplate.php | 5 +-- app/Presenters/Error4xxPresenter.php | 26 +++++++++------- app/Presenters/Error5xxPresenter.php | 43 ++++++++++++-------------- composer.json | 14 +++++++++ 7 files changed, 109 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .phpstan.neon diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0a8dc5d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,42 @@ +name: "Build" + +on: + pull_request: + push: + branches: + - main + +env: + php-tools: "composer:v2" + +jobs: + phpstan: + name: PHPStan + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP with pecl extension + uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist + + - name: Run PHPStan + run: composer phpstan diff --git a/.phpstan.neon b/.phpstan.neon new file mode 100644 index 0000000..167ea06 --- /dev/null +++ b/.phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 8 + treatPhpDocTypesAsCertain: false + paths: + - app diff --git a/app/Blog/Presenters/HomePresenter.php b/app/Blog/Presenters/HomePresenter.php index 00c97e6..6efed6c 100644 --- a/app/Blog/Presenters/HomePresenter.php +++ b/app/Blog/Presenters/HomePresenter.php @@ -5,6 +5,7 @@ use Nette\Application\UI\Form; use Nette\Application\UI\Presenter; use Nette\DI\Attributes\Inject; +use Nette\Utils\ArrayHash; use OrmDemo\Blog\Model\Comments\Comment; use OrmDemo\Blog\Model\Posts\Post; use OrmDemo\Model\Orm; @@ -15,7 +16,7 @@ class HomePresenter extends Presenter #[Inject] public Orm $orm; - private Post $post; + private Post|null $post = null; public function renderDefault(): void @@ -34,6 +35,8 @@ public function actionDetail(int $id): void public function renderDetail(int $id): void { + if (!$this->post) $this->error(); + $template = $this->createTemplate(PostDetailTemplate::class); $template->post = $this->post; $this->sendTemplate($template); @@ -52,8 +55,10 @@ protected function createComponentAddCommentForm(): Form } - public function processAddCommentForm(Form $form, $values): void + public function processAddCommentForm(Form $form, ArrayHash $values): void { + if (!$this->post) $this->error(); + $comment = new Comment(); $comment->content = $values->content; $comment->name = $values->name; @@ -76,9 +81,7 @@ public function handleDeleteComment(int $commentId): void public function createComponentUpdateTagsForm(): Form { - if (!$this->post) { - $this->error(); - } + if (!$this->post) $this->error(); $form = new Form; $form->addCheckboxList('tags', 'Tags', $this->orm->tags->findAll()->fetchPairs('id', 'name')) @@ -90,8 +93,10 @@ public function createComponentUpdateTagsForm(): Form } - public function processUpdateTagsForm(Form $form, $values): void + public function processUpdateTagsForm(Form $form, ArrayHash $values): void { + if (!$this->post) $this->error(); + $this->post->tags->set($values->tags); $this->orm->posts->persistAndFlush($this->post); $this->redirect('this'); diff --git a/app/Blog/Presenters/LayoutTemplate.php b/app/Blog/Presenters/LayoutTemplate.php index 8d593ca..3f1757d 100644 --- a/app/Blog/Presenters/LayoutTemplate.php +++ b/app/Blog/Presenters/LayoutTemplate.php @@ -7,6 +7,7 @@ abstract class LayoutTemplate extends Template { - public string $basePath; - public array $flashes; + public string $basePath; + /** @var list<\stdClass> */ + public array $flashes; } diff --git a/app/Presenters/Error4xxPresenter.php b/app/Presenters/Error4xxPresenter.php index 1214d79..eac8aeb 100644 --- a/app/Presenters/Error4xxPresenter.php +++ b/app/Presenters/Error4xxPresenter.php @@ -10,18 +10,20 @@ */ final class Error4xxPresenter extends Nette\Application\UI\Presenter { - // allow access via all HTTP methods - public array $allowedMethods = []; + // allow access via all HTTP methods + /** @var list */ + public array $allowedMethods = []; - public function renderDefault(Nette\Application\BadRequestException $exception): void - { - // renders the appropriate error template based on the HTTP status code - $code = $exception->getCode(); - $file = is_file($file = __DIR__ . "/templates/Error/$code.latte") - ? $file - : __DIR__ . '/templates/Error/4xx.latte'; - $this->template->httpCode = $code; - $this->template->setFile($file); - } + public function renderDefault(Nette\Application\BadRequestException $exception): void + { + // renders the appropriate error template based on the HTTP status code + $code = $exception->getCode(); + $file = is_file($file = __DIR__ . "/templates/Error/$code.latte") + ? $file + : __DIR__ . '/templates/Error/4xx.latte'; + assert($this->template instanceof Nette\Bridges\ApplicationLatte\Template); + $this->template->httpCode = $code; + $this->template->setFile($file); + } } diff --git a/app/Presenters/Error5xxPresenter.php b/app/Presenters/Error5xxPresenter.php index 00f4bb6..72a4a95 100644 --- a/app/Presenters/Error5xxPresenter.php +++ b/app/Presenters/Error5xxPresenter.php @@ -13,27 +13,24 @@ */ final class Error5xxPresenter implements Nette\Application\IPresenter { - // allow access via all HTTP methods - public array $allowedMethods = []; - - - public function __construct( - private ILogger $logger, - ) { - } - - - public function run(Nette\Application\Request $request): Nette\Application\Response - { - // Log the exception - $exception = $request->getParameter('exception'); - $this->logger->log($exception, ILogger::EXCEPTION); - - // Display a generic error message to the user - return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void { - if (preg_match('#^text/html(?:;|$)#', (string) $httpResponse->getHeader('Content-Type'))) { - require __DIR__ . '/templates/Error/500.phtml'; - } - }); - } + public function __construct( + private ILogger $logger, + ) + { + } + + + public function run(Nette\Application\Request $request): Nette\Application\Response + { + // Log the exception + $exception = $request->getParameter('exception'); + $this->logger->log($exception, ILogger::EXCEPTION); + + // Display a generic error message to the user + return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void { + if (preg_match('#^text/html(?:;|$)#', (string)$httpResponse->getHeader('Content-Type'))) { + require __DIR__ . '/templates/Error/500.phtml'; + } + }); + } } diff --git a/composer.json b/composer.json index ee80caa..0672a50 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,23 @@ "nextras/migrations": "^3.3", "contributte/console": "^0.10" }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "nextras/orm-phpstan": "@dev", + "phpstan/phpstan-nette": "^1.2", + "phpstan/extension-installer": "^1.3" + }, "autoload": { "psr-4": { "OrmDemo\\": "app" } + }, + "scripts": { + "phpstan": "phpstan analyze -c .phpstan.neon" + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } } }