Skip to content

Commit

Permalink
bug #1370 Fix issues reported by PHPStan #1334 (kniziol)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the main branch.

Discussion
----------

Fix issues reported by PHPStan #1334

Closes #1334

Commits
-------

773f504 Fix issues reported by PHPStan #1334
  • Loading branch information
javiereguiluz committed Dec 2, 2022
2 parents 9172868 + 773f504 commit 6511204
Show file tree
Hide file tree
Showing 32 changed files with 271 additions and 518 deletions.
457 changes: 0 additions & 457 deletions phpstan-baseline.neon

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions phpstan.neon.dist
@@ -1,6 +1,3 @@
includes:
- phpstan-baseline.neon

parameters:
level: max
paths:
Expand Down
12 changes: 11 additions & 1 deletion src/Command/AddUserCommand.php
Expand Up @@ -129,7 +129,9 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
}

// Ask for the password if it's not defined
/** @var string|null $password */
$password = $input->getArgument('password');

if (null !== $password) {
$this->io->text(' > <info>Password</info>: '.u('*')->repeat(u($password)->length()));
} else {
Expand Down Expand Up @@ -165,10 +167,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$stopwatch = new Stopwatch();
$stopwatch->start('add-user-command');

/** @var string $username */
$username = $input->getArgument('username');

/** @var string $plainPassword */
$plainPassword = $input->getArgument('password');

/** @var string $email */
$email = $input->getArgument('email');

/** @var string $fullName */
$fullName = $input->getArgument('full-name');

$isAdmin = $input->getOption('admin');

// make sure to validate the user data is correct
Expand Down Expand Up @@ -198,7 +208,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::SUCCESS;
}

private function validateUserData($username, $plainPassword, $email, $fullName): void
private function validateUserData(string $username, string $plainPassword, string $email, string $fullName): void
{
// first check if a user with the same username already exists.
$existingUser = $this->users->findOneBy(['username' => $username]);
Expand Down
4 changes: 3 additions & 1 deletion src/Command/DeleteUserCommand.php
Expand Up @@ -107,7 +107,9 @@ protected function interact(InputInterface $input, OutputInterface $output): voi

protected function execute(InputInterface $input, OutputInterface $output): int
{
$username = $this->validator->validateUsername($input->getArgument('username'));
/** @var string|null $username */
$username = $input->getArgument('username');
$username = $this->validator->validateUsername($username);

/** @var User|null $user */
$user = $this->users->findOneByUsername($username);
Expand Down
16 changes: 12 additions & 4 deletions src/Command/ListUsersCommand.php
Expand Up @@ -88,20 +88,25 @@ protected function configure(): void
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var int|null $maxResults */
$maxResults = $input->getOption('max-results');

// Use ->findBy() instead of ->findAll() to allow result sorting and limiting
$allUsers = $this->users->findBy([], ['id' => 'DESC'], $maxResults);

// Doctrine query returns an array of objects and we need an array of plain arrays
$usersAsPlainArrays = array_map(static function (User $user) {
$createUserArray = static function (User $user) {
return [
$user->getId(),
$user->getFullName(),
$user->getUsername(),
$user->getEmail(),
implode(', ', $user->getRoles()),
];
}, $allUsers);
};

// Doctrine query returns an array of objects, and we need an array of plain arrays
/** @var callable $createUserArray */
$usersAsPlainArrays = array_map($createUserArray, $allUsers);

// In your console commands you should always use the regular output type,
// which outputs contents directly in the console window. However, this
Expand All @@ -119,7 +124,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$usersAsATable = $bufferedOutput->fetch();
$output->write($usersAsATable);

if (null !== $email = $input->getOption('send-to')) {
/** @var string $email */
$email = $input->getOption('send-to');

if (null !== $email) {
$this->sendReport($usersAsATable, $email);
}

Expand Down
14 changes: 11 additions & 3 deletions src/Controller/Admin/BlogController.php
Expand Up @@ -19,6 +19,7 @@
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\SubmitButton;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
Expand Down Expand Up @@ -80,7 +81,8 @@ public function new(

// See https://symfony.com/doc/current/form/multiple_buttons.html
$form = $this->createForm(PostType::class, $post)
->add('saveAndCreateNew', SubmitType::class);
->add('saveAndCreateNew', SubmitType::class)
;

$form->handleRequest($request);

Expand All @@ -98,7 +100,10 @@ public function new(
// See https://symfony.com/doc/current/controller.html#flash-messages
$this->addFlash('success', 'post.created_successfully');

if ($form->get('saveAndCreateNew')->isClicked()) {
/** @var SubmitButton $submit */
$submit = $form->get('saveAndCreateNew');

if ($submit->isClicked()) {
return $this->redirectToRoute('admin_post_new');
}

Expand Down Expand Up @@ -156,7 +161,10 @@ public function edit(Request $request, Post $post, EntityManagerInterface $entit
#[IsGranted('delete', subject: 'post')]
public function delete(Request $request, Post $post, EntityManagerInterface $entityManager): Response
{
if (!$this->isCsrfTokenValid('delete', $request->request->get('token'))) {
/** @var string|null $token */
$token = $request->request->get('token');

if (!$this->isCsrfTokenValid('delete', $token)) {
return $this->redirectToRoute('admin_post_index');
}

Expand Down
21 changes: 16 additions & 5 deletions src/Controller/BlogController.php
Expand Up @@ -13,6 +13,7 @@

use App\Entity\Comment;
use App\Entity\Post;
use App\Entity\Tag;
use App\Entity\User;
use App\Event\CommentCreatedEvent;
use App\Form\CommentType;
Expand Down Expand Up @@ -52,6 +53,7 @@ public function index(Request $request, int $page, string $_format, PostReposito
{
$tag = null;
if ($request->query->has('tag')) {
/** @var Tag $tag */
$tag = $tags->findOneBy(['name' => $request->query->get('tag')]);
}
$latestPosts = $posts->findLatest($page, $tag);
Expand Down Expand Up @@ -155,8 +157,8 @@ public function commentForm(Post $post): Response
#[Route('/search', methods: ['GET'], name: 'blog_search')]
public function search(Request $request, PostRepository $posts): Response
{
$query = $request->query->get('q', '');
$limit = $request->query->get('l', 10);
$query = (string) $request->query->get('q', '');
$limit = (int) $request->query->get('l', 10);

if (!$request->isXmlHttpRequest()) {
return $this->render('blog/search.html.twig', ['query' => $query]);
Expand All @@ -166,11 +168,20 @@ public function search(Request $request, PostRepository $posts): Response

$results = [];
foreach ($foundPosts as $post) {
/** @var string $author */
$author = $post->getAuthor() ? $post->getAuthor()->getFullName() : '';

/** @var string $title */
$title = $post->getTitle();

/** @var string $summary */
$summary = $post->getSummary();

$results[] = [
'title' => htmlspecialchars($post->getTitle(), \ENT_COMPAT | \ENT_HTML5),
'title' => htmlspecialchars($title, \ENT_COMPAT | \ENT_HTML5),
'date' => $post->getPublishedAt()->format('M d, Y'),
'author' => htmlspecialchars($post->getAuthor()->getFullName(), \ENT_COMPAT | \ENT_HTML5),
'summary' => htmlspecialchars($post->getSummary(), \ENT_COMPAT | \ENT_HTML5),
'author' => htmlspecialchars($author, \ENT_COMPAT | \ENT_HTML5),
'summary' => htmlspecialchars($summary, \ENT_COMPAT | \ENT_HTML5),
'url' => $this->generateUrl('blog_post', ['slug' => $post->getSlug()]),
];
}
Expand Down
5 changes: 4 additions & 1 deletion src/Controller/UserController.php
Expand Up @@ -68,7 +68,10 @@ public function changePassword(
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword($passwordHasher->hashPassword($user, $form->get('newPassword')->getData()));
/** @var string $plainPassword */
$plainPassword = $form->get('newPassword')->getData();

$user->setPassword($passwordHasher->hashPassword($user, $plainPassword));
$entityManager->flush();

return $this->redirectToRoute('security_logout');
Expand Down
27 changes: 26 additions & 1 deletion src/DataFixtures/AppFixtures.php
Expand Up @@ -18,6 +18,7 @@
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\String\AbstractUnicodeString;
use Symfony\Component\String\Slugger\SluggerInterface;
use function Symfony\Component\String\u;

Expand Down Expand Up @@ -67,6 +68,8 @@ private function loadTags(ObjectManager $manager): void

private function loadPosts(ObjectManager $manager): void
{
/** @var User $author */
/** @var array<Tag> $tags */
foreach ($this->getPostData() as [$title, $slug, $summary, $content, $publishedAt, $author, $tags]) {
$post = new Post();
$post->setTitle($title);
Expand All @@ -78,8 +81,11 @@ private function loadPosts(ObjectManager $manager): void
$post->addTag(...$tags);

foreach (range(1, 5) as $i) {
/** @var User $commentAuthor */
$commentAuthor = $this->getReference('john_user');

$comment = new Comment();
$comment->setAuthor($this->getReference('john_user'));
$comment->setAuthor($commentAuthor);
$comment->setContent($this->getRandomText(random_int(255, 512)));
$comment->setPublishedAt(new \DateTime('now + '.$i.'seconds'));

Expand All @@ -92,6 +98,9 @@ private function loadPosts(ObjectManager $manager): void
$manager->flush();
}

/**
* @return array<array{string, string, string, string, array<string>}>
*/
private function getUserData(): array
{
return [
Expand All @@ -102,6 +111,9 @@ private function getUserData(): array
];
}

/**
* @return string[]
*/
private function getTagData(): array
{
return [
Expand All @@ -117,6 +129,11 @@ private function getTagData(): array
];
}

/**
* @throws \Exception
*
* @return array<int, array{0: string, 1: AbstractUnicodeString, 2: string, 3: string, 4: \DateTime, 5: object, 6: array<object>}>
*/
private function getPostData(): array
{
$posts = [];
Expand All @@ -137,6 +154,9 @@ private function getPostData(): array
return $posts;
}

/**
* @return string[]
*/
private function getPhrases(): array
{
return [
Expand Down Expand Up @@ -226,6 +246,11 @@ private function getPostContent(): string
MARKDOWN;
}

/**
* @throws \Exception
*
* @return array<object>
*/
private function getRandomTags(): array
{
$tagNames = $this->getTagData();
Expand Down
10 changes: 8 additions & 2 deletions src/Entity/Post.php
Expand Up @@ -66,14 +66,14 @@ class Post
private ?User $author = null;

/**
* @var Comment[]|Collection
* @var Collection<int, Comment>
*/
#[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'post', orphanRemoval: true, cascade: ['persist'])]
#[ORM\OrderBy(['publishedAt' => 'DESC'])]
private Collection $comments;

/**
* @var Tag[]|Collection
* @var Collection<int, Tag>
*/
#[ORM\ManyToMany(targetEntity: Tag::class, cascade: ['persist'])]
#[ORM\JoinTable(name: 'symfony_demo_post_tag')]
Expand Down Expand Up @@ -143,6 +143,9 @@ public function setAuthor(User $author): void
$this->author = $author;
}

/**
* @return Collection<int, Comment>
*/
public function getComments(): Collection
{
return $this->comments;
Expand Down Expand Up @@ -185,6 +188,9 @@ public function removeTag(Tag $tag): void
$this->tags->removeElement($tag);
}

/**
* @return Collection<int, Tag>
*/
public function getTags(): Collection
{
return $this->tags;
Expand Down
14 changes: 13 additions & 1 deletion src/Entity/User.php
Expand Up @@ -53,6 +53,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column(type: Types::STRING)]
private ?string $password = null;

/**
* @var string[]
*/
#[ORM\Column(type: Types::JSON)]
private array $roles = [];

Expand All @@ -73,7 +76,7 @@ public function getFullName(): ?string

public function getUserIdentifier(): string
{
return $this->username;
return (string) $this->username;
}

public function getUsername(): string
Expand Down Expand Up @@ -121,6 +124,9 @@ public function getRoles(): array
return array_unique($roles);
}

/**
* @param string[] $roles
*/
public function setRoles(array $roles): void
{
$this->roles = $roles;
Expand Down Expand Up @@ -151,12 +157,18 @@ public function eraseCredentials(): void
// $this->plainPassword = null;
}

/**
* @return array{int|null, string|null, string|null}
*/
public function __serialize(): array
{
// add $this->salt too if you don't use Bcrypt or Argon2i
return [$this->id, $this->username, $this->password];
}

/**
* @param array{int|null, string, string} $data
*/
public function __unserialize(array $data): void
{
// add $this->salt too if you don't use Bcrypt or Argon2i
Expand Down
3 changes: 2 additions & 1 deletion src/EventSubscriber/CheckRequirementsSubscriber.php
Expand Up @@ -12,6 +12,7 @@
namespace App\EventSubscriber;

use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
Expand Down Expand Up @@ -94,6 +95,6 @@ private function isSQLitePlatform(): bool
{
$databasePlatform = $this->entityManager->getConnection()->getDatabasePlatform();

return $databasePlatform ? 'sqlite' === $databasePlatform->getName() : false;
return $databasePlatform instanceof SqlitePlatform;
}
}

0 comments on commit 6511204

Please sign in to comment.