Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
parameters:
ignoreErrors:
-
message: "#^Throwing checked exception InvalidArgumentException in yielding method is denied as it gets thrown upon Generator iteration$#"
message: '#^Call to an undefined method object\:\:getId\(\)\.$#'
identifier: method.notFound
count: 1
path: src/Serializer/LogSerializer.php

-
message: '#^Throwing checked exception InvalidArgumentException in yielding method is denied as it gets thrown upon Generator iteration$#'
identifier: shipmonk.checkedExceptionInYieldingMethod
count: 2
path: tests/Serializer/LogSerializerTest.php
1 change: 0 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
parameters:
level: 5
paths:
- src/
- tests/
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __construct(
) {
$this->entityClass = $entity::class;
$this->entityColumn = $entityColumn;
$this->entityOldValue = mb_substr($entityOldValue, 0, Log::MAX_STRING_LENGTH);
$this->entityOldValue = $entityOldValue !== null ? mb_substr($entityOldValue, 0, Log::MAX_STRING_LENGTH) : null;
$this->requestTrace = $requestTrace;
$this->createdAt = new DateTimeImmutable();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/UnsupportObjectException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class UnsupportObjectException extends \DomainException
{
public function __construct($object, $code = 0, ?\Throwable $previous = null)
public function __construct(object $object, int $code = 0, ?\Throwable $previous = null)
{
$message = sprintf('Unhandled object of class %s', $object::class);
parent::__construct($message, $code, $previous);
Expand Down
13 changes: 10 additions & 3 deletions src/Factory/LogDataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
/** @phpstan-type LogData array{entity: object, entityColumn: string, entityOldValue: ?string} */
class LogDataFactory
{
/**
* @param list<class-string> $includedEntities
* @param list<class-string> $excludedEntities
*/
public function __construct(
private readonly LogSerializer $formatter,
private readonly array $includedEntities,
Expand Down Expand Up @@ -54,7 +58,7 @@ public function createFromEvent(OnFlushEventArgs $eventArgs): iterable
}
}

private function isLoggable($entity): bool
private function isLoggable(object $entity): bool
{
if ($this->isSubClassFromList($entity, $this->excludedEntities)) {
return false;
Expand All @@ -63,7 +67,10 @@ private function isLoggable($entity): bool
return [] === $this->includedEntities || $this->isSubClassFromList($entity, $this->includedEntities);
}

private function isSubClassFromList($entity, array $classes): bool
/**
* @param list<class-string> $classes
*/
private function isSubClassFromList(object $entity, array $classes): bool
{
foreach ($classes as $class) {
if (is_a($entity, $class)) {
Expand All @@ -75,7 +82,7 @@ private function isSubClassFromList($entity, array $classes): bool
}

/** @return LogData[] */
private function getLogsForEntityFields($entity, EntityManagerInterface $entityManager): iterable
private function getLogsForEntityFields(object $entity, EntityManagerInterface $entityManager): iterable
{
$unitOfWork = $entityManager->getUnitOfWork();

Expand Down
10 changes: 5 additions & 5 deletions src/Serializer/LogSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ public function formatEntity(EntityManagerInterface $entityManager, object $enti
}
}

return json_encode($data, JSON_PRETTY_PRINT);
return (string) json_encode($data, JSON_PRETTY_PRINT);
}

public function formatValueAsString($value): string
public function formatValueAsString(mixed $value): string
{
return json_encode($this->formatValue($value));
return (string) json_encode($this->formatValue($value));
}

/**
Expand All @@ -71,13 +71,13 @@ private function formatField(object $entity, string $field): mixed
/**
* Returns a formatted value depending on the given value's type.
*/
private function formatValue($value): mixed
private function formatValue(mixed $value): mixed
{
return match (gettype($value)) {
'string' => mb_substr($value, 0, Log::MAX_STRING_LENGTH),
'NULL', 'boolean', 'double', 'integer' => $value,
'object' => $this->formatObject($value),
'array' => array_map(__METHOD__, $value),
'array' => array_map($this->formatValue(...), $value),
'resource', 'resource (closed)', 'unknown type'
=> throw new \InvalidArgumentException('Unhandled type'),
};
Expand Down
3 changes: 3 additions & 0 deletions tests/Factory/LogDataFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LogDataFactoryTest extends KernelTestCase
public function testExcludedEntityIsIgnored(): void
{
$em = self::getContainer()->get(EntityManagerInterface::class);
self::assertInstanceOf(EntityManagerInterface::class, $em);
$em->persist(new Author());
$em->getUnitOfWork()->computeChangeSets();

Expand All @@ -31,6 +32,7 @@ public function testExcludedEntityIsIgnored(): void
public function testNewEntityIsLogged(): void
{
$em = self::getContainer()->get(EntityManagerInterface::class);
self::assertInstanceOf(EntityManagerInterface::class, $em);
$em->persist($createdAuthor = new Author());
$em->getUnitOfWork()->computeChangeSets();

Expand Down Expand Up @@ -94,6 +96,7 @@ public function testUpdatedEntityIsLogged(): void
private function mockEntityManager(): array
{
$emReal = self::getContainer()->get(EntityManagerInterface::class);
self::assertInstanceOf(EntityManagerInterface::class, $emReal);
$em = $this->createMock(EntityManagerInterface::class);

$unitOfWork = $this->createMock(UnitOfWork::class);
Expand Down
1 change: 1 addition & 0 deletions tests/Functional/Entity/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#[ORM\Entity]
class Address extends AbstractEntity
{
/** @phpstan-ignore property.unusedType */
private ?string $streetName = null;

public function __construct()
Expand Down
1 change: 1 addition & 0 deletions tests/Functional/Entity/FunctionalLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function __construct(
string $requestTrace,
) {
$this->id = Uuid::uuid1();
/** @phpstan-ignore method.notFound */
$this->entityId = (string) $entity->getId();
parent::__construct(
$entity,
Expand Down
4 changes: 3 additions & 1 deletion tests/Functional/Entity/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(
}

#[Assert\NotBlank]
protected $title;
protected ?string $title = null;

#[ORM\ManyToOne(targetEntity: Author::class, inversedBy: 'posts')]
protected Author $author;
Expand All @@ -31,9 +31,11 @@ public function getAuthor(): Author
return $this->author;
}

/** @var ArrayCollection<int, Tag> */
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'posts')]
protected ArrayCollection $tags;

/** @return Collection<int, Tag> */
public function getTags(): Collection
{
return $this->tags;
Expand Down
1 change: 1 addition & 0 deletions tests/Functional/Entity/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public function __construct()
$this->posts = new ArrayCollection();
}

/** @var ArrayCollection<int, Post> */
#[ORM\ManyToMany(Post::class, 'tags')]
protected ArrayCollection $posts;

Expand Down
7 changes: 5 additions & 2 deletions tests/Serializer/LogSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ public function testFormatEntity(): void
$post->addTag($tag);

$entityManager = self::getContainer()->get(EntityManagerInterface::class);
self::assertInstanceOf(EntityManagerInterface::class, $entityManager);

$formatter = self::getContainer()->get(LogSerializer::class);
self::assertInstanceOf(LogSerializer::class, $formatter);
self::assertSame(
json_encode(array_merge(
$this->helperFormatEntity($author),
Expand Down Expand Up @@ -64,6 +66,7 @@ public function testFormatEntity(): void
);
}

/** @return array<string, mixed> */
public function helperFormatEntity(AbstractEntity $entity): array
{
return [
Expand All @@ -76,13 +79,13 @@ public function helperFormatEntity(AbstractEntity $entity): array
/**
* @dataProvider providerFormatValueAsString
*/
public function testFormatValueAsStringWorks($value, $formatted): void
public function testFormatValueAsStringWorks(mixed $value, string $formatted): void
{
$formatter = new LogSerializer();
self::assertSame($formatted, $formatter->formatValueAsString($value));
}

public function providerFormatValueAsString(): iterable
public static function providerFormatValueAsString(): iterable
{
yield [null, 'null'];
yield [[null], '[null]'];
Expand Down
2 changes: 1 addition & 1 deletion tests/Subscriber/LoggerSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function testSubscriberPersistsLogs(): void
$subscriber = new LoggerSubscriber(
$logFactory,
$logDataFactory,
realpath(__DIR__ . '/../..')
(string) realpath(__DIR__ . '/../..')
);

$subscriber->onFlush($event);
Expand Down
Loading