From 96c8f3c40790dd87343aed8e52a672862ae89cca Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Mon, 30 May 2022 05:37:23 +0200 Subject: [PATCH] Add phpstan --- app/components/Chat/ChatControl.php | 7 +- app/helpers/formatting/Formatter.php | 2 +- app/model/TelegramNotifier.php | 4 +- app/model/orm/post/Post.php | 1 + app/presenters/BasePresenter.php | 11 +- app/presenters/MailPresenter.php | 22 ++-- app/presenters/MeetingPresenter.php | 16 +-- app/presenters/PagePresenter.php | 14 +-- app/presenters/PostPresenter.php | 14 +-- app/presenters/ProfilePresenter.php | 13 +- composer.json | 3 + composer.lock | 173 ++++++++++++++++++++++++++- phpstan.neon | 15 +++ 13 files changed, 234 insertions(+), 61 deletions(-) create mode 100644 phpstan.neon diff --git a/app/components/Chat/ChatControl.php b/app/components/Chat/ChatControl.php index 95cf437..336573b 100644 --- a/app/components/Chat/ChatControl.php +++ b/app/components/Chat/ChatControl.php @@ -75,11 +75,12 @@ public function chatFormSucceeded(Nette\Application\UI\Form $form): void { $chat = new Chat; $chat->content = $formatter->format($values->content); - $chat->ip = $this->request->remoteAddress; - $chat->user = $this->users->getById($presenter->getUser()->getIdentity()->id); + $chat->ip = $this->request->getRemoteAddress(); + $chat->user = $this->users->getById($presenter->getUser()->getIdentity()->getId()); $this->chats->persistAndFlush($chat); try { - $this->telegramNotifier->chatMessage($presenter->getUser()->getIdentity()->username, trim(preg_replace('/\{#([0-9]+)\}/', '', $values->content))); + $username = $presenter->getUser()->getIdentity()->getData()['username'] ?? throw new \Exception('Unexpected: missing username'); + $this->telegramNotifier->chatMessage($username, trim(preg_replace('/\{#([0-9]+)\}/', '', $values->content))); } catch (\Exception) { } if (!$presenter->isAjax()) { diff --git a/app/helpers/formatting/Formatter.php b/app/helpers/formatting/Formatter.php index f8f565d..d7c287a 100644 --- a/app/helpers/formatting/Formatter.php +++ b/app/helpers/formatting/Formatter.php @@ -196,7 +196,7 @@ public function replaceGalleries($text) { return $size; }; $text = preg_replace_callback('/(.+?)<\/gallery>/s', function($match) use ($imageSize) { - $temp = sha1(random_int(0, mt_getrandmax())); + $temp = sha1((string) random_int(0, mt_getrandmax())); $maxWidth = $maxHeight = 0; $images = preg_replace_callback('/!\[(.*?)\]\(([^"]+?)(?: "([^"]+)")?\)/', function($match) use ($imageSize, &$maxWidth, &$maxHeight) { $alt = $match[1]; diff --git a/app/model/TelegramNotifier.php b/app/model/TelegramNotifier.php index eba4b35..cd62aaa 100644 --- a/app/model/TelegramNotifier.php +++ b/app/model/TelegramNotifier.php @@ -8,10 +8,8 @@ use Longman\TelegramBot\Telegram; class TelegramNotifier { - private Telegram $telegram; - public function __construct(string $apiKey, private int $chatId, string $botName) { - $this->telegram = new Telegram($apiKey, $botName); + new Telegram($apiKey, $botName); } public function chatMessage($username, $message) { diff --git a/app/model/orm/post/Post.php b/app/model/orm/post/Post.php index a9c5ff6..177e832 100644 --- a/app/model/orm/post/Post.php +++ b/app/model/orm/post/Post.php @@ -7,6 +7,7 @@ use DateTimeImmutable; use Nette; use Nextras\Orm\Entity\Entity; +use Nextras\Orm\Relationships\OneHasMany; /** * Post diff --git a/app/presenters/BasePresenter.php b/app/presenters/BasePresenter.php index 2a62015..a00a4d0 100644 --- a/app/presenters/BasePresenter.php +++ b/app/presenters/BasePresenter.php @@ -30,9 +30,6 @@ abstract class BasePresenter extends Nette\Application\UI\Presenter { #[Nette\DI\Attributes\Inject] public App\Model\TelegramNotifier $telegramNotifier; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - #[Nette\DI\Attributes\Inject] public App\Helpers\Formatting\ChatFormatter $chatFormatter; @@ -50,7 +47,7 @@ protected function createComponentPaginator($name): \VisualPaginator { protected function startup(): void { if ($this->getUser()->isLoggedIn()) { - $user = $this->users->getById($this->getUser()->getIdentity()->id); + $user = $this->users->getById($this->getUser()->getIdentity()->getId()); $user->lastActivity = new DateTimeImmutable(); $this->users->persistAndFlush($user); } @@ -68,7 +65,7 @@ public function beforeRender(): void { parent::beforeRender(); $template = $this->getTemplate(); if ($this->getUser()->isLoggedIn()) { - $user = $this->users->getById($this->getUser()->getIdentity()->id); + $user = $this->users->getById($this->getUser()->getIdentity()->getId()); $template->unreadMails = $user->receivedMail->get()->findBy(['read' => false])->countStored(); $template->upcomingMeetings = $this->meetings->findUpcoming()->countStored(); } @@ -113,7 +110,7 @@ public function beforeRender(): void { } public function allowed($resource, $action): bool { - $user = $this->getUser()->isLoggedIn() ? $this->users->getById($this->getUser()->getIdentity()->id) : null; + $user = $this->getUser()->isLoggedIn() ? $this->users->getById($this->getUser()->getIdentity()->getId()) : null; return $this->authorizator->isAllowed($user, $resource, $action); } @@ -127,7 +124,7 @@ protected function createComponentChat(): \App\Components\ChatControl { $this->users, $this->telegramNotifier, $this->helperLoader, - $this->request, + $this->getHttpRequest(), $this->chatFormatter, ); diff --git a/app/presenters/MailPresenter.php b/app/presenters/MailPresenter.php index 65fadef..032cef6 100644 --- a/app/presenters/MailPresenter.php +++ b/app/presenters/MailPresenter.php @@ -29,9 +29,6 @@ class MailPresenter extends BasePresenter { #[Nette\DI\Attributes\Inject] public App\Model\UserRepository $users; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - private int $itemsPerPage = 25; public function renderList($sent = false): void { @@ -43,7 +40,7 @@ public function renderList($sent = false): void { $template->sent = $sent; $paginator = $this['paginator']->getPaginator(); $paginator->itemsPerPage = $this->itemsPerPage; - $mails = $this->mails->findBy([$sent ? 'sender' : 'recipient' => $this->getUser()->getIdentity()->id]); + $mails = $this->mails->findBy([$sent ? 'sender' : 'recipient' => $this->getUser()->getIdentity()->getId()]); $paginator->itemCount = $mails->countStored(); $template->mails = $mails->orderBy(['timestamp' => 'DESC'])->limitBy($paginator->itemsPerPage, $paginator->offset); } @@ -69,7 +66,7 @@ public function actionShow($id, $tree = false): void { $this->error('Toto není tvá zpráva', Nette\Http\IResponse::S403_FORBIDDEN); } - if (!$mail->read && $mail->recipient->id === $this->getUser()->getIdentity()->id) { + if (!$mail->read && $mail->recipient->id === $this->getUser()->getIdentity()->getId()) { $mail->read = true; $this->mails->persistAndFlush($mail); } @@ -80,7 +77,8 @@ public function actionShow($id, $tree = false): void { protected function createComponentMailForm(): Nette\Application\UI\Form { $form = new Nette\Application\UI\Form(); $form->addProtection(); - $form->setRenderer(new Renderers\Bs3FormRenderer()); + $renderer = new Renderers\Bs3FormRenderer(); + $form->setRenderer($renderer); $subject = $form->addText('subject', 'Předmět:')->setRequired(); $subject->getControlPrototype()->autofocus = true; @@ -97,7 +95,7 @@ protected function createComponentMailForm(): Nette\Application\UI\Form { $submitButton = $form->addSubmit('send', 'Odeslat'); $submitButton->onClick[] = [$this, 'mailFormSucceeded']; - $form->getRenderer()->primaryButton = $submitButton; + $renderer->primaryButton = $submitButton; return $form; } @@ -118,8 +116,8 @@ public function mailFormSucceeded(SubmitButton $button): void { $mail->subject = $values->subject; $mail->markdown = $values->markdown; $mail->content = $formatted['text']; - $mail->sender = $this->users->getById($this->getUser()->getIdentity()->id); - $mail->ip = $this->request->remoteAddress; + $mail->sender = $this->users->getById($this->getUser()->getIdentity()->getId()); + $mail->ip = $this->getHttpRequest()->getRemoteAddress()(); if ($this->getAction() === 'reply') { $original_id = $this->getParameter('id'); @@ -132,7 +130,7 @@ public function mailFormSucceeded(SubmitButton $button): void { $this->error('Zpráva s tímto id neexistuje.'); } - if ($original->recipient->id !== $this->getUser()->getIdentity()->id) { + if ($original->recipient->id !== $this->getUser()->getIdentity()->getId()) { $this->error('Zpráva, na kterou chceš odpovědět není určena do tvých rukou.', Nette\Http\IResponse::S403_FORBIDDEN); } @@ -198,7 +196,7 @@ protected function notifyByMail(Mail $mail): void { $message->setFrom($messageTemplate->sender . ' '); $message->setSubject('Nová zpráva ' . $mail->subject . ' (fan-club-penguin.cz)'); $message->addTo($mail->recipient->email); - $message->setBody($messageTemplate); + $message->setBody((string) $messageTemplate); $mailer = new SendmailMailer(); $mailer->send($message); @@ -239,7 +237,7 @@ public function actionReply($id): void { $this->error('Zpráva s tímto id neexistuje.'); } - if ($original->recipient->id !== $this->getUser()->getIdentity()->id) { + if ($original->recipient->id !== $this->getUser()->getIdentity()->getId()) { $this->error('Zpráva, na kterou chceš odpovědět není určena do tvých rukou.', Nette\Http\IResponse::S403_FORBIDDEN); } $this->getTemplate()->original = $original; diff --git a/app/presenters/MeetingPresenter.php b/app/presenters/MeetingPresenter.php index 6d61674..c6bf1bb 100644 --- a/app/presenters/MeetingPresenter.php +++ b/app/presenters/MeetingPresenter.php @@ -27,9 +27,6 @@ class MeetingPresenter extends BasePresenter { #[Nette\DI\Attributes\Inject] public App\Model\UserRepository $users; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - #[Nette\DI\Attributes\Inject] public App\Model\HelperLoader $helperLoader; @@ -126,8 +123,8 @@ public function meetingFormSucceeded(SubmitButton $submit): void { $meeting->date = $values->date->setTime((int) $hour, (int) $minute); if ($this->getAction() === 'create') { - $meeting->ip = $this->request->remoteAddress; - $meeting->user = $this->users->getById($this->getUser()->getIdentity()->id); + $meeting->ip = $this->getHttpRequest()->getRemoteAddress(); + $meeting->user = $this->users->getById($this->getUser()->getIdentity()->getId()); } $this->meetings->persistAndFlush($meeting); @@ -163,7 +160,7 @@ public function meetingFormPreview(SubmitButton $button): void { [$hour, $minute] = explode(':', $program[0]['time']); $meeting->program = Json::encode($program); $meeting->date = $values->date->setTime((int) $hour, (int) $minute); - $meeting->user = $this->users->getById($this->getUser()->getIdentity()->id); + $meeting->user = $this->users->getById($this->getUser()->getIdentity()->getId()); $this->getTemplate()->preview = $meeting; @@ -186,9 +183,8 @@ public function actionEdit($id): void { if (!$this->getUser()->isLoggedIn()) { $this->redirect('Sign:in', ['backlink' => $this->storeRequest()]); } - /** @var Meeting $meeting */ $meeting = $this->meetings->getById($id); - if (!$meeting) { + if ($meeting === null) { $this->error('Sraz nenalezen.'); } if (!$this->allowed($meeting, 'edit')) { @@ -249,7 +245,7 @@ public function actionDelete($id): void { */ protected function createComponentParticipator(): Multiplier { return new Multiplier(function($meetingId) { - $userId = $this->getUser()->getIdentity()->id; + $userId = $this->getUser()->getIdentity()->getId(); $meeting = $this->meetings->getById($meetingId); $youParticipate = array_reduce(iterator_to_array($meeting->visitors->get()), function($carry, $visitor) use ($userId) { if ($visitor->id === $userId) { @@ -269,7 +265,7 @@ public function participatorClicked(Nette\Application\UI\Form $form, $values): v } $meeting = $this->meetings->getById($values->id); - $userId = $this->getUser()->getIdentity()->id; + $userId = $this->getUser()->getIdentity()->getId(); $youParticipate = $values->action === 'unparticipate'; try { if ($youParticipate) { diff --git a/app/presenters/PagePresenter.php b/app/presenters/PagePresenter.php index 6a98262..31398f4 100644 --- a/app/presenters/PagePresenter.php +++ b/app/presenters/PagePresenter.php @@ -29,9 +29,6 @@ class PagePresenter extends BasePresenter { #[Nette\DI\Attributes\Inject] public Nette\Http\Response $response; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - #[Nette\DI\Attributes\Inject] public Nette\Caching\Storage $storage; @@ -127,7 +124,8 @@ public function renderLinks(): void { protected function createComponentPageForm(): Nette\Application\UI\Form { $form = new Nette\Application\UI\Form; $form->addProtection(); - $form->setRenderer(new Renderers\Bs3FormRenderer()); + $renderer = new Renderers\Bs3FormRenderer(); + $form->setRenderer($renderer); $form->addText('title', 'Nadpis:')->setRequired()->getControlPrototype()->autofocus = true; $slug = $form->addText('slug', 'Adresa:')->setRequired()->setType('url'); if ($this->getAction() == 'edit') { @@ -141,7 +139,7 @@ protected function createComponentPageForm(): Nette\Application\UI\Form { $submitButton = $form->addSubmit('send', 'Odeslat a zveřejnit'); $submitButton->onClick[] = [$this, 'pageFormSucceeded']; - $form->getRenderer()->primaryButton = $submitButton; + $renderer->primaryButton = $submitButton; return $form; } @@ -176,7 +174,7 @@ public function pageFormSucceeded(SubmitButton $button): void { if ($this->getAction() === 'create') { $page->slug = $values->slug; - $page->user = $this->users->getById($this->getUser()->getIdentity()->id); + $page->user = $this->users->getById($this->getUser()->getIdentity()->getId()); } try { @@ -186,8 +184,8 @@ public function pageFormSucceeded(SubmitButton $button): void { $revision->markdown = $values->markdown; $revision->page = $page; $revision->content = $formatted['text']; - $revision->user = $this->users->getById($this->getUser()->getIdentity()->id); - $revision->ip = $this->request->remoteAddress; + $revision->user = $this->users->getById($this->getUser()->getIdentity()->getId()); + $revision->ip = $this->getHttpRequest()->getRemoteAddress(); $page->revisions->add($revision); $this->pages->persistAndFlush($page); diff --git a/app/presenters/PostPresenter.php b/app/presenters/PostPresenter.php index 4823b1f..7b33657 100644 --- a/app/presenters/PostPresenter.php +++ b/app/presenters/PostPresenter.php @@ -26,9 +26,6 @@ class PostPresenter extends BasePresenter { #[Nette\DI\Attributes\Inject] public App\Model\UserRepository $users; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - #[Nette\DI\Attributes\Inject] public Nette\Caching\Storage $storage; @@ -66,7 +63,8 @@ public function renderList(): void { protected function createComponentPostForm() { $form = new Nette\Application\UI\Form; $form->addProtection(); - $form->setRenderer(new Renderers\Bs3FormRenderer()); + $renderer = new Renderers\Bs3FormRenderer(); + $form->setRenderer($renderer); $form->addText('title', 'Nadpis:')->setRequired()->getControlPrototype()->autofocus = true; $form->addTextArea('markdown', 'Obsah:')->setRequired()->getControlPrototype()->addRows(15)->addClass('editor'); $form->addCheckbox('published', 'Zveřejnit')->setDefaultValue(true); @@ -77,7 +75,7 @@ protected function createComponentPostForm() { $submitButton = $form->addSubmit('save', 'Uložit'); $submitButton->onClick[] = [$this, 'postFormSucceeded']; - $form->getRenderer()->primaryButton = $submitButton; + $renderer->primaryButton = $submitButton; return $form; } @@ -111,7 +109,7 @@ public function postFormSucceeded(SubmitButton $button): void { } if ($this->getAction() === 'create') { - $post->user = $this->users->getById($this->getUser()->getIdentity()->id); + $post->user = $this->users->getById($this->getUser()->getIdentity()->getId()); } $this->posts->persistAndFlush($post); @@ -121,8 +119,8 @@ public function postFormSucceeded(SubmitButton $button): void { $revision->title = $values->title; $revision->post = $post; $revision->content = $formatted['text']; - $revision->user = $this->getUser()->getIdentity()->id; - $revision->ip = $this->request->remoteAddress; + $revision->user = $this->getUser()->getIdentity()->getId(); + $revision->ip = $this->getHttpRequest()->getRemoteAddress(); $post->revisions->add($revision); $cache = new Cache($this->storage, 'posts'); diff --git a/app/presenters/ProfilePresenter.php b/app/presenters/ProfilePresenter.php index b72230f..2e6aadb 100644 --- a/app/presenters/ProfilePresenter.php +++ b/app/presenters/ProfilePresenter.php @@ -46,9 +46,6 @@ class ProfilePresenter extends BasePresenter { #[Nette\DI\Attributes\Inject] public Nette\Security\Passwords $passwords; - #[Nette\DI\Attributes\Inject] - public Nette\Http\IRequest $request; - public function renderList(): void { $template = $this->getTemplate(); $template->profiles = $this->users->findAll()->orderBy('username'); @@ -61,10 +58,10 @@ public function renderShow($id): void { } $template = $this->getTemplate(); if (file_exists($this->context->parameters['avatarStorage'] . '/' . $this->profile->id . 'm.png')) { - $template->avatar = str_replace('♥basePath♥', $this->request->url->baseUrl, $this->context->parameters['avatarStoragePublic']) . '/' . $this->profile->id . 'm.png'; + $template->avatar = str_replace('♥basePath♥', $this->getHttpRequest()->getUrl()->getBaseUrl(), $this->context->parameters['avatarStoragePublic']) . '/' . $this->profile->id . 'm.png'; } - $template->ipAddress = $this->request->remoteAddress; + $template->ipAddress = $this->getHttpRequest()->getRemoteAddress(); $template->profile = $this->profile; $template->stamps = $this->stamps->findAll(); } @@ -151,7 +148,7 @@ public function profileFormSucceeded(Form $form): void { $values->avatar->move($original); try { $resized = Image::fromFile($original)->resize(100, 100); - Image::fromBlank('100', '100', Image::rgb(0, 0, 0, 127))->place($resized, '50%', '50%')->save($medium); + Image::fromBlank(100, 100, Image::rgb(0, 0, 0, 127))->place($resized, '50%', '50%')->save($medium); } catch (Exception $e) { $form->addError('Chyba při zpracování avataru.'); Debugger::log($e); @@ -271,7 +268,7 @@ public function passwordResetRequestFormSucceeded(Form $form): void { $t = Random::generate(); $token = new Token; $token->token = $this->passwords->hash($t); - $token->ip = $this->request->remoteAddress; + $token->ip = $this->getHttpRequest()->getRemoteAddress(); $token->expiration = (new DateTimeImmutable())->add(\DateInterval::createFromDateString('2 day')); $token->type = Token::PASSWORD; $user->tokens->add($token); @@ -285,7 +282,7 @@ public function passwordResetRequestFormSucceeded(Form $form): void { $mailTemplate->url = $this->link('//Profile:resetPassword', ['tid' => $token->id, 'token' => $t]); $mailTemplate->username = $user->username; $mail = new Message; - $mail->setFrom('admin@fan-club-penguin.cz')->addTo($user->email)->setHtmlBody($mailTemplate); + $mail->setFrom('admin@fan-club-penguin.cz')->addTo($user->email)->setHtmlBody((string) $mailTemplate); $mailer = new SendmailMailer; $mailer->send($mail); diff --git a/composer.json b/composer.json index 871595a..6e11822 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,9 @@ "mockery/mockery": "^1.5", "nette/tester": "^2.4", "nextras/migrations": "^3.0", + "nextras/orm-phpstan": "^1.0", + "phpstan/phpstan": "^1.7", + "phpstan/phpstan-nette": "^1.0", "symfony/console": "^3.2" }, "autoload": { diff --git a/composer.lock b/composer.lock index 4f37f63..9f2c490 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": "205dea5447e02195312d291febaff38a", + "content-hash": "562af4cee34bd3608ff48d6728d4477d", "packages": [ { "name": "actinarium/php-diff", @@ -3138,6 +3138,177 @@ }, "time": "2022-04-04T15:13:14+00:00" }, + { + "name": "nextras/orm-phpstan", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/nextras/orm-phpstan.git", + "reference": "e215076ccf92632f8bd2aa4b79f4a172a338c83f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextras/orm-phpstan/zipball/e215076ccf92632f8bd2aa4b79f4a172a338c83f", + "reference": "e215076ccf92632f8bd2aa4b79f4a172a338c83f", + "shasum": "" + }, + "require": { + "php": "~7.1 || ~8.0", + "phpstan/phpstan": "^1.0" + }, + "require-dev": { + "nette/tester": "^2.3.1", + "nextras/orm": "~4.0 || ~5.0@dev", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Nextras\\OrmPhpStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan extension for Nextras Orm", + "support": { + "issues": "https://github.com/nextras/orm-phpstan/issues", + "source": "https://github.com/nextras/orm-phpstan/tree/v1.0.1" + }, + "time": "2022-05-01T21:42:32+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "48c4621b1a6dde32aab2e9a79658b843ffb614f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/48c4621b1a6dde32aab2e9a79658b843ffb614f7", + "reference": "48c4621b1a6dde32aab2e9a79658b843ffb614f7", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.7.3" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-05-29T11:36:09+00:00" + }, + { + "name": "phpstan/phpstan-nette", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-nette.git", + "reference": "f4654b27b107241e052755ec187a0b1964541ba6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-nette/zipball/f4654b27b107241e052755ec187a0b1964541ba6", + "reference": "f4654b27b107241e052755ec187a0b1964541ba6", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "phpstan/phpstan": "^1.0" + }, + "conflict": { + "nette/application": "<2.3.0", + "nette/component-model": "<2.3.0", + "nette/di": "<2.3.0", + "nette/forms": "<2.3.0", + "nette/http": "<2.3.0", + "nette/utils": "<2.3.0" + }, + "require-dev": { + "nette/forms": "^3.0", + "nette/utils": "^2.3.0 || ^3.0.0", + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-php-parser": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Nette Framework class reflection extension for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-nette/issues", + "source": "https://github.com/phpstan/phpstan-nette/tree/1.0.0" + }, + "time": "2021-09-20T16:12:57+00:00" + }, { "name": "symfony/console", "version": "v3.4.47", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..a88d78b --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,15 @@ +includes: + - vendor/phpstan/phpstan-nette/extension.neon + - vendor/phpstan/phpstan-nette/rules.neon + - vendor/nextras/orm-phpstan/extension.neon +parameters: + level: max + paths: + - app + - tests + - www + # checkMissingIterableValueType: false + # treatPhpDocTypesAsCertain: false + # checkGenericClassInNonGenericObjectType: false + ignoreErrors: + # - '(Call to an undefined method App\\Components\\TeamForm::addDynamic\(\))'